10

我有一些独立的 Matlab 程序,出于不同的原因需要访问它们所在目录中的文件(启动另一个程序或在那里读取一些 XML 文件)。我有以下适用于 Windows 的功能:

function execDir = get_deployed_exec_dir()
% Returns the directory of the currently running executable, if deployed,
% an empty string if not deployed (or if unable to determine the directory)
execDir = '';
if isdeployed
    [status, execDir] = system('path');
    if status == 0
        execDir = char(regexpi(execDir, 'Path=(.*?);', 'tokens', 'once'));
    end
end

为了让它在 Linux 和 Mac 上工作,我想我可以替换system('path')system('echo $PATH')更改正则表达式以适应 Unix 语法,但与 Windows 不同,当前运行的可执行文件的目录似乎不会自动添加到路径的前面多变的。Matlab中有没有办法获取当前运行的可执行文件的目录(我知道有脚本,但部署时似乎不能正常工作),或者我应该在运行之前编辑设置MCR的脚本应用程序设置我的代码可以使用system命令读取的变量?

具体而言,用户计算机上的某处是文件夹EXECFOLDER,其结构:

EXECFOLDER
| exec1
| exec2
| run_exec1.sh
| run_exec2.sh
| data.xml

我想弄清楚EXECFOLDER无论用户在哪里运行run_exec1.sh(设置 MCR 和调用的脚本exec1)的路径,以便exec1可以读取data.xml和执行exec2.

尝试总结:

  • system('echo $PATH'): 可执行目录不在 Mac 和 Linux 的路径上
  • matlabroot: MCR 的位置
  • pwd: 用户的当前文件夹,当它以完整路径运行时,它可能与可执行文件的位置不同
  • dbstack: 未打包的 .m 文件的位置
  • which: 未打包的 .m 文件的位置
  • fileattrib: 未打包的 .m 文件的位置
4

4 回答 4

4

该功能是否满足ctfroot您的需求?

ctfroot是来自 MATLAB 编译器的命令。从文档中:

root = ctfroot返回一个字符串,该字符串是展开已部署应用程序的可部署存档的文件夹的名称。

ctfroot您可能只想在一个if isdeployed块内使用该命令。

编辑

如果您需要可执行文件的位置,而不是扩展它的位置,您可以使用以下函数:

function currentDir = getcurrentdir
if isdeployed % Stand-alone mode.
    [status, result] = system('path');
    currentDir = char(regexpi(result, 'Path=(.*?);', 'tokens', 'once'));
else % MATLAB mode.
    currentDir = pwd;
end

这是因为可执行文件的路径在运行时作为第一个条目添加到 PATH 变量中。

或者,您可以创建一个执行类似作业的 MEX 文件。有关更多详细信息以及 MEX 文件示例,请参阅此 MathWorks 支持答案。

于 2015-01-15T14:05:22.750 回答
2

这方面有什么进展吗?

您需要做的(对于两个平台)是访问由 shell 传递给可执行文件的第 0 个参数。这样做的一种方法是在脚本中包装对可执行文件的调用并显式传递位置:

myapp.bat:

set scriptpath=%~d0%~p0
"%scriptpath%%~n0%.exe" --ExecutablePath="%scriptpath%" %*

或者,如果您不希望 CMD 窗口留在附近

myapp.bat:

set scriptpath=%~d0%~p0
start "%~n0" "%scriptpath%%~n0%.exe" --ExecutablePath="%scriptpath%" %*

Bash 实际上更难(见这个问题),但这样的事情可能会奏效:

我的应用程序.sh

#!/bin/bash
SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )"
"${SCRIPTPATH}/myapp.o" --ExecutablePath="${SCRIPTPATH}" $*
于 2013-11-29T07:41:49.800 回答
1

也许你需要:

curr_dir = strrep(which(mfilename('fullpath')),mfilename,'')

这将为您提供当前正在运行的 .m 文件的目录。

于 2015-01-14T09:56:21.037 回答
1

Mac: 要从已部署的应用程序本身中获取 Mac 上已安装可执行文件MyDeployedApplication.app的位置,请尝试以下操作:

if isdeployed && ismac
    NameOfDeployedApp = 'MyDeployedApplication'; % do not include the '.app' extension
    [~, result] = system(['top -n100 -l1 | grep ' NameOfDeployedApp ' | awk ''{print $1}''']);
    result=strtrim(result);
    [status, result] = system(['ps xuwww -p ' result ' | tail -n1 | awk ''{print $NF}''']);
    if status==0
        diridx=strfind(result,[NameOfDeployedApp '.app']);
        realpwd=result(1:diridx-2);
    else
        msgbox({'realpwd not set:',result})
    end
else
    realpwd = pwd;
end

此解决方案使用“ps”、“grep”和“top”终端命令,假设用户当前正在运行MyDeployedApplication.app的单个实例,并且仅在带有 MATLAB Compiler 2015a 的 MAC OS Yosemite 10.10.5 上进行了测试。

注意:虽然 pgrep 从应用程序外部(直接在终端或打开的 MATLAB 会话中)返回已部署的、当前正在运行的应用程序的 PID,但它没有从应用程序内返回任何内容。因此使用 top 和 grep。

Linux: 要在 Linux 上获取已安装可执行文件的路径,请将 Sam 对 Linux 风格的回答的语法更改为:

[status, result] = system('echo $PATH');
realpwd = char(regexpi(result, '(.*?):', 'tokens', 'once'));        
于 2016-07-11T20:46:32.090 回答