setting current directory using cd from inside .mlapp files
Show older comments
I'm making an app and trying to understand the path behavior for .mlapp files. I'm observing the following behavior:
- If I open Matlab by double-clicking on an .mlapp file the path is automatically set to the path of the .mlapp file.
- If Matlab is already open, however, and the current directory does not corerspond to the directory of the .mlapp file, then warnings get thrown when the .mlapp file is opened by double-clicking on it, and errors get thrown when any buttons are pushed because <<some method>> is not defined for the class associated with <<your app's class>>.
- I tried to fix this by putting the following code into the startup function:
cd(fileparts(mfilename('fullpath')));
The above, however did not work. If Matlab is not already set to the correct directory, then running the .mlapp file by double-clicking on it does not result in the current directory being updated despite the new code in the startup function. However, if modify to the following, I see the correct path printed on the commandline!
pth = fileparts(mfilename('fullpath'));
disp(pth);
cd(pth)
This means that the code is being executed at some level, and that the variable "pth" has the correct path, but somehow the cd() command executed in the startup function is not actually changing Matlab's current directory and callbacks etc. still throw errors.
The behavior gets further modified if the appdesigner gets involved:
- If I open appdesigner and I run the app via the "run" button in appdesigner, then it does work, sort of: the path doesn't update in the command window but I don't get crashes and if I do any subsequent path changes via callbacks then the does update in the command line.
- If I put a break point inside the code and step through it, then behavior is exactly as expected, the Matlab command-line updates as expected, it's basically as if a standard m-file is being executed.
- If I change the path manually to some other path and run the .mlapp app via double-clicking on it, now it works as opposed to throwing an error, like it did before I opened appdesigner.
I've passed my app around to some others for testing and they are not as familiar with Matlab. I am quite sure what will happen is that: 1) they will open Matlab in whatever directory it was previously set to, then 2) they will double click on the .mlapp file and 3) they will get errors because it is not auto-setting the path like it seems that it should in the startup function.
Is there a better way to set the path from within a .mlapp file, so that when it gets executed by double-clicking the path gets updated?
Answers (2)
I can't say I'm super happy with cd's unreliable functionality but glad for an alternate solution.
It's not cd() that is at fault. cd() was never executed in any of your tests.
If the app cannot be found on the search path by Matlab, then the .mlapp code as a whole never gets executed, including any calls it makes to cd(). Double-clicking the .mlapp file in the FIle Explorer is a special case, only because, as you noted, it forces Matlab to launch with the app's parent folder as the Current Folder.
13 Comments
Timothy
on 2 Jul 2025
OK. I think I see what is happening. If you launch an .mlapp from the File Explorer (you didn't say this was Windows OS, but I'm assuming it is), instead of from within the Matlab desktop, the startupFcn will run in its entirety, i.e., it will cd to the parent folder of the .mlapp folder. However, as soon as the startupFcn completes, Matlab will then automatically cd() back to the folder it was originally in and it will destroy the app object created by the startup function.
It is as if you had launched the app inside a temporary function workspace and then used onCleanup to revert the Matlab desktop back to its original state.
Basically, I think you are not supposed to be running .mlapp files from the File Explorer with the expectation that it will behave like a standalone .exe. If you want that behavior, you need to use the Matlab compiler.
In any case, cd() is still not at fault. It is not failing to execute. It is just that other internal wrappers are running after startupFcn to undo its effects.
Timothy
on 3 Jul 2025
"If I attempt to run an m-file that is not in the current directory, I am atleast prompted to update the directory. It would be helpful if Matlab would either do that or do what appdesigner does ..."
Then make an enhancement request here: https://www.mathworks.com/support/contact_us.html
Most of the people on this forum are volunteers, if you want TMW to change something then write them a request! Feel free to include a link to this thread.
Timothy
on 3 Jul 2025
If I attempt to run an m-file that is not in the current directory, I am atleast prompted to update the directory.
I don't know how you are producing that behavior. When I launch an mfile from the File Explorer, it simply opens the file in the Matlab Editor, independently of what the Matlab Desktop's current folder is, without any messages. This is yet another sign that the File Explorer should not be relied upon to treat Matlab files as normal executables.
But when you talk about double-clicking on the .mlapp file, you are doing that from outside Matlab correct(e.g. fom File Explorer)? Within Matlab, there is no way to double-click a .mlapp file unless it is in the current folder.
The only way to run a .mlapp file (a) within Matlab (b) when the .mlapp file does not reside in the current folder, is through appdesigner. In that case, I see no failure on the part of cd commands to change the directory (in R2024b).
Timothy
on 3 Jul 2025
Steven Lord
on 3 Jul 2025
Could you open MATLAB, run these commands, and show us what they return, substituting the path to your file for <path to your mlapp file>? I want to check that your MATLAB session is using what we expect to open the mlapp file.
[filetype, opencmd, loadcmd] = finfo(<path to your mlapp file>)
pathToOpencmd = which('-all', opencmd)
Can you also look at what superclasses your app inherits from and show us what "which -all <name of superclass>" returns when MATLAB starts up (without appdesigner having been opened)?
If one of the superclasses your app uses is not on the path or accessible to MATL AB but is only added to the path once the app has been loaded, I think you could have a chicken-and-egg scenario. MATLAB would need to run the cd call to make the superclass "visible" to MATLAB, but it needs the superclass to be visible to be able to instantiate the class so it can run the code inside the app, including the cd call. In that case, opening appdesigner could make that superclass "visible" to MATLAB thus breaking the chicken-egg loop.
In my case,
>> [filetype, opencmd, loadcmd] = finfo('C:\Users\Matt\Downloads\appTest.mlapp')
pathToOpencmd = which('-all', opencmd)
filetype =
'mlapp'
opencmd =
'openmlapp'
loadcmd =
0×0 empty char array
pathToOpencmd =
1×1 cell array
{'C:\Program Files\MATLAB\R2024b\toolbox\matlab\appdesigner\appdesigner\openmlapp.m'}
and I am not inheriting from anything unusual:
classdef appTest < matlab.apps.AppBase
The only peculiar behavior I am seeing in common with @Timothy is that the current folder reverts back to the original one when the .mlapp is launched from File Explorer. I get no errors when activating the app buttons and its callbacks. Opening appDesigner does not change any behavior, as far as I am seeing. Note however that I am in R2024b, whereas @Timothy has posted that he is in R2024a.
You forgot the name of the app. C:\Users\Matt\Downloads is a directory, not a file.
Sorry, rereading what I wrote I see now that "path to your mlapp file" could be ambigious, and you interpreted it as just the directory containing the file when I mean the path plus file name. That's my fault.
fullName = which('bench.m') % what I meant
[pathToFile, filename, ext] = fileparts(fullName) % you used just pathToFile
[filetype, opencmd, loadcmd] = finfo(fullName)
Catalytic
on 3 Jul 2025
0 votes
The behavior makes sense to me, though I somewhat disagree with @Matt J. I think launching a .mlapp from the File Explorer is meant to be like running it as a stand-alone executable. Ideally, this would be done by opening a second Matlab session. However, I guess MathWorks doesn't want the user to incur the overhead of starting up and shutting down Matlab. So as a shortcut, they use any Matlab session that is currently already running. To make this work however, they do have to run some cleanup process to make sure that the effects of the startup function on the existing Matlab session are temporary.
Categories
Find more on Package and Share Apps in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!