Using addpath on Compiled Code
Mostra commenti meno recenti
Hello. I have run into a problem using a compiled EXE of my code on a target computer (running the MCR)
On my computer where I create the code (and have Matlab installed) - I succesfully connect to a linear stage
%% Load PI MATLAB Driver GCS2
% (if not already loaded)
addpath ( 'C:\Users\Public\PI\PI_MATLAB_Driver_GCS2' );
if ( ~exist ( 'Controller', 'var' ) || ~isa ( Controller, 'PI_GCS_Controller' ) )
Controller = PI_GCS_Controller ()
end;
%% Start connection
%(if not already connected)
boolPIdeviceConnected = false; if ( exist ( 'PIdevice', 'var' ) ), if ( PIdevice.IsConnected ), boolPIdeviceConnected = true; end; end;
if ( ~(boolPIdeviceConnected ) )
% USB
controllerSerialNumber ='020550023'; %'Enter valid serial number here, e.g. "123456789"'; % Use "devicesUsb = Controller.EnumerateUSB('')" to get all PI controller connected to you PC.
% Or look at the label of the case of your controller
PIdevice = Controller.ConnectUSB ( controllerSerialNumber );
% Query controller identification string
connectedControllerName = PIdevice.qIDN()
Whilst this works fine it doesn't work on my compiled version on the target computer and its throwing an addpath error. Doing some searching I see that I shouldn't use addpath in compiled versions of my code.
So do I need to include all the files in the following folder :
C:\Users\Public\PI\PI_MATLAB_Driver_GCS2\@PI_GCS_Controller
If I check ctfroot on the target computer I get.
C:\Users\Scan\AppData\Local\Temp\Scan\mcrCache9.9\HPBR_60
So do I just place my the folder I need access to in the ctfroot directory?
If not whats the solution?
Thanks
Jason
Risposte (2)
Image Analyst
il 15 Gen 2021
Modificato: Image Analyst
il 15 Gen 2021
0 voti
The problem is the CTF root directory is in some weird place that changes from version to version so you'd have to change it every time you compiled and released a new version.
One problem I recently found out about is that if the end user does not use the program for a long time, then Windows might delete some run-time library functions from your CTF if your CTF is in the "Automatic" folder.
On occasion, some of you may see an error
Undefined function or variable 'matlabrc'.
Undefined function or variable 'ctfroot’.
Error in checkRequiredMCRProducts (line 22)
Undefined function or variable 'ctfroot’.
This shows up in the console window (“DOS box”). Sometimes it might just flash briefly and vanish and the program never starts. The official solution given by Mathworks for this problem is below:
The solution is to delete the CTF extraction folder, and run the EXE again. If the MCR_CACHE_ROOT environment variable is not set, the CTF extraction location can be found at:
C:\Users\[username]\AppData\Local\Temp\[username]\mcrCache[version]
To get around the problem of Windows randomly deleting the files you need to specify that the CTF is in some known, permanent location that Windows won't touch, unlike the temporary folder it normally puts it into. So you can set a Sytemt Environment variable from the control panel:
MCR_CACHE_ROOT=C:\users\public\documents\MATLAB\MCR
Then when you run your program, it will unpack the CTF to that location.
Alternatively, you can put your data into a known place like "C:\Users\Public\Documents\MATLAB\YourData" -- this is what I do. Do you have just a few files or a whole folder of files that changes as the user uses your program?
Have you tried using the -a option in mcc? You can do that if you want to bundle your files to be shipped with your executable and it will always find them. However if you expect to be adding files to that folder, then you'll still need to have a folder where you keep the files that is in a known location, like D:\my data or somewhere and then use fullfile() to construct the full file name of your file whenever you need to use it.
4 Commenti
Jason
il 15 Gen 2021
Jason
il 15 Gen 2021
Image Analyst
il 15 Gen 2021
Modificato: Image Analyst
il 15 Gen 2021
What operating system are you on? In windows you can type "Environment" into the search field on your task bar, or it you don't have that, just hit the windows key and type environment. You should see the Environment Variables control panel.
If you have a bunch of data files that you want to ship with your app, like file1.txt, etc. and your installer (I use Centurion Setup by Gammadyne company) puts them into 'C:\Users\Public\PI\PI_MATLAB_Driver_GCS2' then you can construct the full filename in your code like this
folder = 'C:\Users\Public\PI\PI_MATLAB_Driver_GCS2'; % Where you KNOW they live. Otherwise ask the use via uigetdir().
baseFileName = 'file1.txt'; % Whatever...
fullFileName = fullfile(folder, baseFileName);
data = importdata(fullFilename); % Whatever function you want.
You do not need to set a path to that folder, EVER.
See the FAQ:
Jason
il 15 Gen 2021
Bruno Luong
il 15 Gen 2021
Modificato: Bruno Luong
il 15 Gen 2021
0 voti
I can't see addpath in your snip of code.
When you compile the app, all the source mfiles used by you app MUST be found by dependency analyzer. So you must call appropiate ADDPATH before MCC.
If you app calls ADDPATH, then you just need to remove it and call is elsewhere (outside). You might use isdeployed() to have different code branch. But ideally you should restructure the code so that you would never need to call addpath while your program is running.
11 Commenti
Bruno Luong
il 15 Gen 2021
I don't know I use MCC command line, so I do whatever I want in my build script.
Never care about GUI. But can't you just add the path with the "Set Path" menu in MATLAB window?
Steven Lord
il 15 Gen 2021
Add this directory to your path before starting compiling in the GUI, so that the files are present during the compiler's analysis of what should be included in your application. If it's not clear from the static analysis of your code that you need to use those files (like if you're loading a variable of that class from a MAT-file, see the "Fixing Callback Problems: Missing Functions" section on that page) then you'd also need to tell MATLAB and MCC it should include the appropriate class definition from that directory in the application. That "Missing Functions" section of the page describes how to do that.
You cannot have your deployed application call MATLAB scripts, functions, or classes that were not compiled into the application. [Usually when I see someone trying to compile a call to addpath this is what they're trying to do.] See this page for more information.
Jason
il 15 Gen 2021
Jason
il 15 Gen 2021
Bruno Luong
il 15 Gen 2021
Modificato: Bruno Luong
il 15 Gen 2021
This get a little off-topic. It's no longer addpath issue.
You might copy all necessary DLLs in the same level than the exe file manually or use -a option when you build your app
mcc( '-a', 'C:\ProgramData\PI\GCSTranslator\PI_GCS2_DLL_x64.dll', ...
This is about packaging of DLL so that whatever function that uses it can find it.
It looks for the DLL in the current folder (exe file) or in the same folder of the caller. If you use -a I believe it will be located at the same location as the caller.
You need to be aware that the deployed app must have everything it needs in a same package so it can run on other computer, not only the computer you use with MATLAB and you use too compile it.
It require some work if you have third party library to carry with.
Image Analyst
il 15 Gen 2021
No, if you included it with the executable by using the -a option, you do not then need to use the absolute folder name because it should find it without prepending the folder name. Though if it is there in that folder anyway, it won't hurt anything -- just remember to ship that file and install it in that folder.
Hopefully your LoadGCSDLL() function has robust validation code like this:
baseFileName = [c.DLLNameStub, '.DLL']; % Append .dll extension
try
fprintf('Found DLL file %s. Now loading it...\n', baseFileName)
loadlibrary(baseFileName); % Whatever, to load the DLL....
fprintf('Successfully loaded DLL file %s.\n', baseFileName)
catch ME
% You get here if it can't find it without the folder prepended because it's not in the CTF or on the search path.
% Try absolute folder/file combination -- maybe we can find the file there instead.
fullFileName = fullfile(c.DriverDirectoryOnWindows, baseFileName);
if ~isfile(fullFileName)
% File not found.
errorMessage = sprintf('ERROR : DLL file not found:\n%d', fullFileName);
fprintf('%s\n', errorMessage);
uiwait(errordlg(errorMessage));
return; % Whatever you want to do if it can't find the file....
else
% Found it in this folder.
fprintf('Found DLL file %s. Now loading it...\n', fullFileName)
loadlibrary(baseFileName); % Whatever, to load the DLL....
fprintf('Successfully loaded DLL file %s.\n', fullFileName)
end
end
Bruno Luong
il 16 Gen 2021
Modificato: Bruno Luong
il 16 Gen 2021
You can get the exe file folder if you put this file in the same folder than the main function of you app and call it
function currentDir = getcurrentdir
% currentDir = getcurrentdir
if isdeployed % Stand-alone mode.
[~, result] = system('set PATH');
currentDir = char(regexpi(result, 'Path=(.*?);', 'tokens', 'once'));
else % MATLAB mode.
thisfile = mfilename('fullpath');
currentDir = fileparts(thisfile);
end
I don't know the exact meaning of c.DriverDirectoryOnwindows to make any comment. It might need other stuffs in or under this folder. You should check with whoever who distributes the library.
Image Analyst
il 16 Gen 2021
Modificato: Image Analyst
il 16 Gen 2021
Is
currentDir = pwd;
not reliable? Actually the current directory can be different than the location of the executable program, like if the program called cd().
Bruno Luong
il 16 Gen 2021
You'll notice the won't use PWD in deployed.
Categorie
Scopri di più su Standalone Applications in Centro assistenza e File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!

