Is it possible to get the version number of a compiled program inside the program? I am using the Application Compiler.

16 visualizzazioni (ultimi 30 giorni)
For a project I am working on, I would like the program to output the current version being used in a char array. I have the following code:
if(isdeployed)
version = (Help here);
version_message = ['Now running program.exe version: ' version];
else
version = 'script';
version_message = ['Now running program.m version: ' version];
end
disp(version_message);
Is it possible to dynamically get the version number, or do I have to manually set it to ensure they are the same? I know it can be done with App Designer, but this executable does not use App Designer.

Risposta accettata

dpb
dpb il 1 Mag 2025
Modificato: dpb il 5 Mag 2025
C:\>wmic /?
WMIC is deprecated.
[global switches] <command>
...
"Starting January 29, 2024, you'll find Windows Management Instrumentation Command line (WMIC) feature "disabled by default" on the insider build of Windows 11. ..." from <WMI command line (WMIC) utility deprecation: Next steps>.
Recommends using powershell instead but also notes that eventually the intent is to remove WMIC in some unspecified future release.
An Answer to another Q? posted an example of spawning powershell and parsing the return, I modified that a little to create a more generic utility function
function [status,version,cmdout]=getexeversion(app)
% return executable file version info
cmdout=[];
if ~isfile(app), status=-1; version=[]; return, end % no such file found
cmdstr=['powershell -command (Get-Command """',app,'""").Version'];
[status,cmdout]=system(cmdstr);
if status, version=[]; return, end % command failed
%elements=regexp(cmdout, '\d+', 'match'); % original stripped numbers returned powershell line,column if failed
%version=strjoin(regexp(cmdout, '\d+', 'match'),'.'); % long string returned as Major.Minor.Build.Revision
version=cell2struct(extract(cmdout,digitsPattern),extract(cmdout,lettersPattern)); % return as fields of struct instead
end
An example use would be something like...
>> fn=fullfile('C:\...\MATLAB\Work\','BuildBillingUtility/', ...
'for_redistribution_files_only/','AnnualBillingWorkbokUpdateTool.exe');
>> [s,v,c]=getexeversion(fn)
s =
0
v =
struct with fields:
Major: '4'
Minor: '0'
Build: '0'
Revision: '0'
c =
'
Major Minor Build Revision
----- ----- ----- --------
4 0 0 0
'
>>
where fn points to the built executable.
I put this into an 'About' menu item under an exisitng 'Environment' menu in the particular app to retrieve...all this then requires to manually enter into the app as a constant is the name of the executable so one doesn't have to update or include a version file that possibly can get out of synch. Of course, one would have to add in some way to keep the associated version notes if were to want that additional functionality.
As I noted in that other thread, it is certainly annoying one has to go to such machinations instead of being able to read the Sharing info that is in the app at the App level.
The test for file existence is a workaround that from MATLAB one cannot launch powershell directly; system or ! (bang) only know about CMD(*) so all one gets as a return code is the status of the outer shell, not the status returned by powershell itself. I wasn't able to find any way to manage that.
(*) This is also frustrating if one uses a command shell replacement such as the <Take Command> replacement from JP Software. It's such a pain that Mathworks ignores the user-defined default shell processor with the hardcoded "CMD.EXE" so that one cannot take advantage of the added features thus available. Of course, if one uses such, it isn't portable, but that shouldn't prevent from being able to use when do have...

Più risposte (2)

Image Analyst
Image Analyst il 8 Nov 2023
You can get the version of MATLAB used, or you can get the date/time stamp of your executable, but you cannot get the version number/name you are calling your custom program. What I do is have a text file that keeps track of my version numbers and dates plus what changes were made in that version, and then I call the attached function to read my version number out of my text file (which I ship with my compiled program installer).
  3 Commenti
Eamon
Eamon il 8 Nov 2023
I found a, somewhat complex, single file windows only answer. It worked for me, but I'm not 100% it works always.

Accedi per commentare.


Eamon
Eamon il 8 Nov 2023
First, you need the name and location of your file. If this is standard to a directory and file name, you're fine. Otherwise, you will need to find it.
commandStrings = string(System.Environment.GetCommandLineArgs);
name = char(commandStrings(1));
Do note I have read this may be bad practice, but there is no way to get the name of your compiled exe without doing this. This is important if someone were to change the name of your exe after installation. You need to convert to string then to char, you cannot go straight to char from the original. It has to be a char for the next step.
The following are alternatives that are close but don't work, none of them will get the .exe name. This is important if your user has several .exe files in the same folder:
%Only returns the current working directory, which can change mid program.
cd
pwd
%Empties path
[~, result] = system('set PATH');
thePath = char(regexpi(result, 'Path=(.*?);', 'tokens', 'once'));
%Only works for m files, will give wrong directory on compiled programs,
%and will give the original .m file name rather than the .exe file name.
mfilename %and all options
dbstack
Now you can get the version.
name = strrep(name,'\','\\'); %wmic needs double escape sequence
command = ['wmic datafile where Name="' name '" get Version']; %This will output to console
command = [command ' >NUL'] %This will silence the command to not output to console
[status, cmdout] = system(command);
output = strsplit(cmdout,newline);
progVersion = strtrim(output{2});
disp(progVersion)
This will get the Version property from a file that wmic supports, including .exe files. It worked with the program I tested it with. After getting the command return, split it along the newline, then get the version out of the split. You can skip the third line if you want to see the output in console directly, which, for me and .exe files in general, should be something like:
%MATLAB.exe as example.
Version %Some spaces after verion
9.12.0.0 %And version number
%Followed by 2 new lines.
This will get the version set in your .prj file.
  5 Commenti
Eamon
Eamon il 6 Mag 2025
"System.Environment.GetCommandLineArgs" is a .NET function, included as part of MATLAB's .NET integration. "GetCommandLineArgs" does not have to include the path to the file, so there is a chance you will not get a path to the file you are running.
dpb
dpb il 6 Mag 2025
Modificato: dpb il 6 Mag 2025
Ah, so! I didn't think about the .NET connection, indeed! Thanks.
I guess while it isn't guaranteed by .NET or even by argv[0], that the loader for MATLAB Windows apps references the full file name is probably about as reliable as it gets without one of the real messy alternatives.
This app ends up installed in an IT-controlled environment and by default powershell scripts are disabled so it would require getting them to allow it for these machines to use that path. Single powershell commands can be executed with default permissions, so the version lookup can sneak under the radar.
And, as far as I can tell, there's no way to add additional installation tasks with the MATLAB-supplied installer to be able to do something more clever on the installation.

Accedi per commentare.

Categorie

Scopri di più su MATLAB Compiler in Help Center e File Exchange

Prodotti


Release

R2022a

Community Treasure Hunt

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

Start Hunting!

Translated by