setting current directory using cd from inside .mlapp files

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?

3 Comments

I would avoid CD. Did you try ADDPATH ?
No, will give this a try, but out of curiousity why should cd be more fragile than addpath?
Ok, yes, that seems to work... thanks a bunch. I can't say I'm super happy with cd's unreliable functionality but glad for an alternate solution.

Sign in to comment.

Answers (2)

Matt J
Matt J on 2 Jul 2025
Edited: Matt J on 2 Jul 2025
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

"cd() was never executed in any of your tests."
Then why does
pth = fileparts(mfilename('fullpath'));
disp(pth);
cd(pth)
output the path of the .mlapp to the command line
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.
Well, cd() may not be at fault but in that case the wierd behavior is on the part of Matlab, because what is happening is not at all obvious and it shouldn't be unexpected that a user may launching an .mlapp file while a session is open. 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 (i.e. update the path in the background) which would at least add some consistency with appdesigner.
"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.
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.
"I don't know how you are producing that behavior."
To clarify: this is referring to execution of an m-file that is not in the current directory *from within the editor.* In that case you get the usual prompt (“<<Your m-file>> is not found in the current folder or on the Matlab path.” Followed by a prompt to change the directory or add the path.) Double clicking on an m-file from the file explorer opens it in the editor.
Running / opening m-files makes sense and provides all the necessary user guardrails. In contrast, .mlapp files do not (see e.g. the behavior above). I think there are a number of alternatives that provide functionality and guardrails. For example, if you have the matlab editor open and you double click on an mlapp, perhaps it opens in the appdesigner (vs executing). Or, if Matlab wants to preserve the behavior of execution upon double-click in the File Explorer, perhaps it could prompt the user the same way it does for m-files, regarding updating the path or changing the current directory. As it currently stands, however, it gives the impression that it executed but strips the functionality and never prompts the user. As Stephen23 suggested, I will submit an enhancement request.
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).
Somehow my response seems to have disappeared in the ether so I'm going to try again.
I am referring to the case of opening an mlapp by double clicking on the file in the Explorer after Matlab has been opened but without opening appdesigner. This does not seem to me to be an unusual use case.
At any rate, this executes the mlapp in such a way that the behavior diverges signifcantly from a) opening an mlapp by double clicking in the explorer before Matlab has been opened (in which case Matlab opens and the current directory is the same as the mlapp, and the mlapp executes successfully) and it also diverges from the behavior experienced by opening an mlapp (either via double-clicking in explorer or via the app designer) after both Matlab and the appdesigner have been opened, in which case using cd() in the startup function works successfully.
In this (again, seemingly not unusual) use case, I see the behavior above: the UI opens, the startup function executes, but since the path has not been updated (as seems to happen in the other cases) you have the UI open but without any functionality.
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
fullName = '/MATLAB/toolbox/matlab/general/bench.m'
[pathToFile, filename, ext] = fileparts(fullName) % you used just pathToFile
pathToFile = '/MATLAB/toolbox/matlab/general'
filename = 'bench'
ext = '.m'
[filetype, opencmd, loadcmd] = finfo(fullName)
filetype = 'm'
opencmd = 'openm'
loadcmd = 0×0 empty char array
OK. I revised my last comment with proper execution of finfo.

Sign in to comment.

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.

1 Comment

Appreciate all the responses, unfortunately I am away from a computer for the next three days and cannot apply the test suggested by Steven Lord. On my computer, though, if I run an klapp as described and the mlapp is not in the path already the UI appears but I get class errors thrown if any button is pressed because it is not recognizing the class associated with the mlapp. This is on 2024a, with the specific prodedure I described above. Maybe the behavior has changed since then.

Sign in to comment.

Categories

Find more on Package and Share Apps in Help Center and File Exchange

Products

Release

R2024a

Asked:

on 2 Jul 2025

Commented:

on 3 Jul 2025

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!