在运行时为Mac和Linux获取已部署的Matlab应用程序的位置

时间:2013-07-25 18:59:31

标签: matlab matlab-deployment

我有一些独立的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的脚本),以便{{1} }可以从exec1读取并执行data.xml

尝试摘要:

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

4 个答案:

答案 0 :(得分:3)

函数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文件。有关详细信息,请参阅this MathWorks support答案,以及示例ME​​X文件。

答案 1 :(得分: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实际上更难(参见this question),但这样的事情可能有效:

myapp.sh

#!/bin/bash
SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )"
"${SCRIPTPATH}/myapp.o" --ExecutablePath="${SCRIPTPATH}" $*

答案 2 :(得分:1)

也许你需要:

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

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

答案 3 :(得分:0)

Mac: To get the location of an installed executable MyDeployedApplication.app on Mac from within the deployed app itself, try the following:

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

This solution uses the 'ps', 'grep', and 'top' terminal commands, assumes the user has a single instance of MyDeployedApplication.app currently running, and has been tested on MAC OS Yosemite 10.10.5 with MATLAB Compiler 2015a only.

Note: While pgrep worked to return the PID of the deployed, currently running application from outside of the application (directly in Terminal or in an open MATLAB session), it did not return anything from within the application. Hence the use of top and grep.

Linux: To get the path of the installed executable on Linux, change the syntax of Sam's answer to Linux style:

[status, result] = system('echo $PATH');
realpwd = char(regexpi(result, '(.*?):', 'tokens', 'once'));