By default, macros run in QM, but you also can create standalone programs (exe files) from them. Exe files run like macros, but don't need QM. It is especially useful if you distribute them. Distributing exe also is better because it does not depend on QM version, whereas macros that run in QM may not run on older QM versions.
To make exe from current macro or function, click menu Run -> Make Exe.
The "make exe" feature also is used to run macros in separate process. QM creates a .qmm (compiled macro) or .exe file and executes it in separate process. Therefore in most cases here terms "exe" or "program" mean ".exe program or a macro that runs in separate process".
Features that are unavailable in exe
Features that are different in exe
Properties -> Run in separate process
Main - the macro or function that runs first when the program runs.
Make - the program file to create. Can be .exe or .qmm (used with the "run in separate process" feature).
Icon - program's icon. It also will be used in dialogs etc. Can be ico, exe, dll, ocx. Icon index can be specified like shell32.dll,18.
Manifest - manifest file.
.res - an optional .res file containing resources to add to exe resources.
Auto add files... - add files used in exe macro/functions to exe resources. Adds only files where a resource id specified. Example: scan ":10 $my qm$\file.bmp".
Version - file version and other optional info. Valid version formats: 1, 1.2, 1.2.3, 1.2.3.4. The list in the 'Version info' dialog can include anything.
End hotkey - a hotkey that can be used to end the program. Notes.
Console (QM 2.4.1) - create console exe. A console process has a console window or uses console of parent process (eg cmd.exe). Also, cmd.exe does not wait until a non-console process ends. Console exe code example.
These macro/function properties also are applied when creating exe: "allow only single instance" (function) and "don't run/wait/terminate" (macro). Read more below.
When creating an exe first time, you can choose where to save its settings - in current macro or folder. Choose to save in folder if exe will have more functions that are in the folder; then later these settings will be used when you make (update) exe while any of the functions is open. The folder name should be the same as the program name (e.g. "X Editor"); it is used in exe, for example in error message boxes. You can find exe settings in Folder Properties dialog.
You can use whatever way that you can use to run programs (double click in Windows Explorer, etc).
If you click the Run button, the macro runs in QM, as usually. To run exe when you click the Run button, check "Run in separate process" in Properties.
When creating exe, QM compiles the main function and all other used functions, including threads created using mac. Compiled code is added to exe. Source code is not added, unless need to get certain text from it at run time (read below). In some cases need to use #exe to explicitly add some functions and other data. To see what is added, check 'Show added items'.
Full text (source code) of a macro/function is added to exe if it contains a dialog definition used with ShowDialog, a menu definition used with ShowDialog or DT_CreateMenu, or an other-language script used with CsExec, CsFunc, CsScript.AddCode, CsScript.Compile, CsScript.Exec, WshExec, VbsExec, VbsAddCode, JsExec, JsAddCode, PsCmd, __Tcc.Compile. To avoid adding full source code, store dialog definitions etc in separate macros or in variables. Example.
Exe cannot be decompiled to see the source code that is not added to exe as text, but it is possible to see strings that were in source code. You can encrypt (in Options -> Security) items that contain passwords or other confidential information in strings.
External files (e.g. dll) are not added to exe automatically. You can add them together with exe file to a zip file or setup program, and on other computers extract everything to the same folder. You can also add files to exe as resources, like function ExeQmGridDll does (you can see its code). Read more below.
You may need these files. Take them from QM folder.
If exe runs on your computer, it finds these files in QM folder. You don't have to copy them to your exe folder. The same when it runs on other computers where QM is installed (should be same version). Particularly, if a dll whose path begins with "$qm$" isn't in exe's folder, exe also searches in QM folder, if QM is installed.
QM 2.3.4. Although mailbee.dll and arservicesmgr.dll are COM components, don't need to register them.
If you want to create a setup program for your exe, you'll need a software that does it. It adds all used files (exe, dll files, Help file, etc) to a single compressed setup program, on user's computer runs setup wizard, creates folders, extracts files, creates shortcuts, creates uninstaller, and more.
Recommended free software - Inno Setup. The QM setup program also is created with it. Download and install the QuickStart Pack unicode version. To start creating your setup script, use Example1.iss as an example.
Compile-time errors ("unknown identifier", etc) will not occur in exe, because exe contains already compiled code. Declarations, type libraries and other references are not used in exe (all required information is added to exe when creating it). However, like any other program, the program will fail if a required dll function or COM component does not exist on the computer. To check whether a dll function exists, you can use version variables and delay-loading (dll- ...). To handle "No such interface supported" errors you can use err.
When an unhandled run-time error ("window not found", etc) occurs, the program exits. The error is shown in QM output or message box, depending on 'Output to QM' checkbox in 'Make Exe' dialog (see above). See also: ExeOutputWindow, RedirectQmOutput.
If you use global variables that are initialized at QM startup (for example in your init2 function), you should add the initialization code to the exe, or these variables in exe will be empty. For example, call the initialization function at the beginning of the main function (you can use #if EXE to skip it when running in QM). Don't need it for predefined global variables and for global variables that are initialized by constructor. If you change global run-time settings with RtOptions, do it in exe too.
If the main function has "Allow only single instance" option checked in Properties, only single instance of the program can run at a time. If it is a macro, macro properties "don't run/wait/terminate" are applied, which also means that only single instance of the program can run at a time. In both cases, limited is only the number of instances of the same program. Don't use "Allow only single instance" if you want to have more control, e.g. relay the command line to already running instance. You can use a mutex instead. Note that getopt nthreads will not work. Mutex example
If the program is launched with command line arguments, it is in a special variable _command. To parse, you can use function ExeParseCommandLine.
On success, it is the return value of the main function. It should be 0 or positive. On failure, it is: -1 if the main function ended due to a run-time error; -2 if the program didn't start because another instance is already running; -3 if terminated from outside (e.g. using hotkey); -4 if could not start (e.g., a dll function not found).
The main function runs not in the primary thread of the exe process. Like in QM, the primary thread is used to manage threads and provide other services. The main function is executed in a separate thread.
More threads can be created using mac. The exe process ends when the main function's thread ends. To wait until other threads will end, the main thread can use WaitForThreads.
Functions OnScreenDisplay, MsgBoxAsync, Play and Speak run asynchronously, in separate thread. As well as mac. Your main thread can use wait 0 H or WaitForThreads to wait for them. Some of them have a flag to run synchronously.
You can use shutdown -6 to end a thread in the exe process. It will not end threads in QM and other processes. You can use shutdown -1 to end the exe process from any thread.
Like in QM, constructors and destructors of global variables run in the primary thread.
QM triggers cannot be used to launch exe (unless QM is running and you use its triggers).
To launch exe using a hotkey, can be used a shortcut on desktop or in start menu (you can assign a hotkey in shortcut Properties dialog). To avoid possible problems when Ctrl/Shift/Alt are mixed with keys pressed by exe, exe created from macro waits until these keys are released before starting to execute commands. Exe created from function does not, but you can insert this code at the beginning:
rep() if(GetMod) 0.02; else break
Use _qmdir or ExeFullPath.
QM cannot create small exe files. Minimal size is about 400 KB.
Programs created with QM run at the same speed as macros and functions in QM.
QM does not create native machine code. In some cases QM code runs significantly slower than native machine code (e.g. C++ programs).
QM can create only exe files.
You can use class __Tcc to create dlls in C language.
Programs created with QM can run on Windows 7, 8, 10, 11. Read more below.
See also: macro resources. Note that exe resources is not the same as macro resources, but macro resources are automatically converted to exe resources when creating exe.
Resources are files and other data added to exe file. Can be added bitmaps (pictures), icons, cursors, menus, accelerators, strings, version info, binary data (e.g. files), etc. If you use files in exe macros/functions, you can either distribute them together with the exe (for example in a zip file) or add them to exe as resources.
If "Auto add files ..." is checked, QM searches the source code of all macros/functions that are added to exe (except as text) for strings that look like ":resourceid filepath" and adds the files to exe as resources. For example, to automatically add bitmap file used with scan, use code like scan ":10 file.bmp", and check "Auto add files ...". The table shows what resources are added depending on file type (filename extension).
File type | Resource type | How to load explicitly | How to free explicitly | Comments |
---|---|---|---|---|
bmp | Bitmap. | LoadPictureFile. Returns bitmap handle. | DeleteObject | |
ico | Icon. | GetFileIcon. Returns icon handle. | DestroyIcon | |
cur | QM 2.3.0. Cursor. | GetFileIcon with flag 4. Returns cursor handle. | DestroyCursor | |
exe, dll, ocx, icl | QM 2.3.0. Icon. | GetFileIcon. Returns icon handle. | DestroyIcon | filepath must contain icon index or negative resource id. Examples: ":10 shell32.dll,15", ":10 shell32.dll,-140". Otherwise whole file will be added as RT_RCDATA. |
gif, jpg, png | QM 2.3.0. RT_RCDATA. | LoadPictureFile. Loads as bitmap; returns bitmap handle. QM 2.3.4: supports png. | DeleteObject | Can be used in dialog static picture controls. Assign ":resourceid filepath" to the variable before calling ShowDialog. QM 2.3.4: supports png. |
ani | QM 2.4.1. RT_ANICURSOR. | GetFileIcon with flag 4. Returns cursor handle. | DestroyCursor | In older QM - RT_RCDATA. |
Other | QM 2.3.0. RT_RCDATA. | str.getfile or ExeGetResourceData. Loads raw data. | Don't need. |
resourceid must be a number between 1 and 0xFFFF. Filename extension must consist of 1 - 4 alphanumeric characters. The string must not be in comments or #if-excluded code or F"string".
QM functions that support the ":resourceid filepath" syntax: ShowDialog (title bar icon, icons, bitmaps, imagelists), scan (bmp, icon), GetFileIcon (icon, cursor), LoadPictureFile (bmp, gif, jpg, png), str.getfile, IXml.FromFile, ICsv.FromFile, CsScript.Load, RichEditLoad, bee (QM 2.3.4), __ImageListLoad, __ImageList.Load, __ImageList.Create, ShowDropdownList, and functions that use them.
QM 2.3.0. When using ":resourceid filepath", QM always gets data from the file when the macro runs in QM. In previous versions, QM would try to get the data from exe if it exists.
QM 2.3.1. Supports multiline strings. Example
Other way to add files to exe is #exe addfile.
To create resources of other types, you can use a resource editor. QM does not have it, but you can download one. Using the resource editor, add all that you need and save to a file with .res extension. Specify the file in the Make Exe dialog. When creating exe, QM will add resources from the file to the exe. To load these resources, you can use syntax ":resourceid" (e.g. ":300") with the functions listed above.
Whenever you edit files that you have added to exe, you should make exe again, otherwise its resources will not be updated.
Resources also can be used with Windows API functions (LoadImage, FindResource, and other). To get resource module handle, use GetExeResHandle. Example: int hi=LoadImage(GetExeResHandle +133 IMAGE_ICON 0 0 0). Such code will run in QM as well as in exe.
You should not use dialog resources. You can create dialogs in QM. With dialog resources you could not use ShowDialog and all additional features that QM provides (control variables, etc). Menus also can be created in QM.
By default, exe contains these resources: icon 1 (if icon file specified), manifest 1 (if manifest file specified) and version info 1 (if version or other version info specified).
QM 2.3.0. Exe icon resource id changed from 133 to 1.
The <default> exe icon is the main function's icon. Icons of other QM items are not automatically added to exe. For example, in exe all dialogs will have the same icon (exe icon). In QM they may have different icons. To have different icons in exe, specify the icon files explicitly when calling ShowDialog, using the ":resourceid filepath" syntax.
Some functions and other QM features are unavailable in exe. Most of them are related to QM items and interface, and therefore have no sense in exe. Others use QM hooks, services, etc, that would cost too much in exe.
Unavailable functions:
Unavailable only some features:
QM detects unavailable functions when creating exe. Also detects unavailable features used with mac, qmitem, str.getmacro, wait.
A special constant EXE can be used with #if to include/exclude code that is not supported in exe. It is 1 if compiling .exe, 2 if .qmm, 0 if the macro runs in QM.
Other unavailable features:
Some predefined variables have different values when the macro runs in exe.
Predefined constants (as well as all constants) have values specific to the computer where the exe was created, not where it runs.
Special folder $qm$ is exe file path, not qm.exe path.
Special folder $my qm$ probably does not exist on computers where the program will run.
Some functions are implemented differently in exe, and therefore may behave slightly differently in some cases. It includes:
Windows Vista and later has a security feature - User Account Control (UAC). With UAC, even if you are working on an administrator user account, most programs have only standard user's privileges. It creates various problems for many programs, including QM. They cannot write to many file system and registry locations, manipulate services, and much more. Also, most of them cannot interact (use keyboard, mouse and menu commands, send messages, use hooks, etc) with programs that have higher privileges. QM can interact with all programs, but UAC may be a problem for QM-created programs. Read more about it here.
Since most programs run with standard privileges, your QM-created programs will be able to automate them. If they have to automate programs with higher privileges (admin or uiAccess), or if they need higher privileges for other purposes, they must be started as administrator or marked as uiAccess.
To mark a program as administrator or uiAccess program, add a manifest resource with certain tags. uiAccess programs also must be signed. A code signing certificate costs 100-500 $/year. The default manifest specifies normal privileges (level="asInvoker" uiAccess="false"). Other level values that can be specified are "highestAvailable" and "requireAdministrator". uiAccess can be "false" or "true". You can find more information about UAC and MS Authenticode code signing on the Internet. Also you can ask about it in the Quick Macros forum.
See also: GetProcessUacInfo, Run in separate process
Normally, macros run in QM process. If you check "Run in separate process" in Properties, the macro will run in its own process. This option is available for macros and functions.
When you launch such a macro or function, QM creates and executes a .qmm or .exe file. By default uses .qmm, but you can change file extension to .exe, and then will be created .exe file. You can change exe/qmm settings in the Make Exe dialog.
If the file already exists, QM checks macro and file times etc, and creates file again if need. If settings are stored in a folder, QM also checks all macros/functions in the folder. If the macro directly or indirectly uses functions from other folders, after editing these functions need to create file again (use the Make Exe dialog or edit/run the macro).
This feature can be useful when creating/debugging exe that is not to be run from QM. Instead of invoking menu Run -> Make Exe and Run -> Run Exe, you can just click the Run button. The exe file is exactly the same as if you create it using menu Run -> Make Exe. If you initially have .qmm file, change file extension to .exe.
The "Run in separate process" feature can be useful when some functions require certain privileges while QM is running with different privileges. There are several predefined sets of privileges - integrity levels (IL). Process IL is assigned when starting the process and cannot be changed later. QM itself can run as administrator (High IL), normal user (Medium IL) or uiAccess (Medium+uiAccess IL); you can set it in Options. Macros running in separate process can run as:
0 | As QM | The same IL as of QM. |
1 | User | Medium IL, even if QM is running as administrator. |
2 | Administrator | High IL. On non-admin accounts also runs as admin but shows a password dialog. |
3 | Highest available | High IL on admin accounts. As QM on non-admin accounts. |
4 | Low | Low IL, like Internet Explorer running in protected mode. |
5 | As QM, -uiAccess | The same IL as of QM, but without uiAccess privileges. |
To run exe files with various IL, QM uses function StartProcess. You can also use it in macros, except in exe. The first argument can be one of values from the table.
Integrity levels are used if UAC (User Account Control) is on. Otherwise, exe will run with same privileges as QM, regardless what IL is selected. The only exception is "Administrator", which also is applied on non-administrator accounts on other OS.
On non-administrator accounts, if IL is different than QM, exe may run as other user than QM. Possible problems with user-specific special folders ("$personal$, "$my qm$, etc) and registry keys. If exe does not run, try to change its path (in Make Exe dialog) from "$my qm$" to some common folder, for example "$common appdata$\qmexe".
UAC IL that is specified in Properties is applied only if the exe is started by QM like a macro. It is not applied if the exe is started using run or when you double click exe icon in Windows Explorer. To apply it when you double click exe icon, check "Run in separate process", create shortcut to the macro, and use the shortcut.
There are some limitations in portable QM.
When you run the macro using mac, a command line can be passed to the exe process. The main exe thread receives the string through the _command variable. String and numeric arguments also can be passed (use function). Don't pass pointers and references.
mac "macro name" "command line" 5 "string arg"
To manage the exe process (display running macro icon, end macro on Pause, etc), QM creates a thread in QM. It is listed in the Running Items list and in the Threads dialog. If you end the thread (or end macro using Pause), it also ends the process. If you use mac as function (ie assign to a variable), it returns thread handle. The caller macro can wait until macro ends.
int h=mac("macro name") wait 0 H h
Note: This does not work if both the macro and the caller are macros. At least one of them must be function.
If you use "On Run" function, it receives the command line and arguments through its first parameter. The _command variable contains exe file path. The function should run the exe file and wait until it exits (e.g., run with flag 0x400, or StartProcess and wait for handle). If it does not wait, QM cannot manage the exe process. Also, it should exit soon after the process ends.
function# $ca run _command ca "" "" 0x400
In some cases, the macro does not run in separate process, even if "Run in separate process" is checked: 1. If it is a function called from code. 2. If it is a function started from exe (using mac). 3. If it is a function started by a QM startup/exit trigger and is set to run synchronously. 4. If it is a function called by QM using some special way, e.g. like a filter function.
As described earlier in this topic, some QM features are unavailable or different when the macro runs in separate process. For example, global variables are not shared by processes.
A .qmm file contains compiled macro and related resources. Unlike .exe, it is not executable. The macro is executed by qmmacro.exe when you run the macro from QM as separate process. Executing not from QM also is possible, but not recommended, because .qmm file version must match qmmacro.exe version.
The .qmm file format is the same as of a resource-only dll. For example, you can add icons and use as an icon library.
1. Macros that run in separate process may start with a delay. Probably your antivirus program scans the .exe or .qmm file, and also qmmacro.exe that executes .qmm files.
2. Macros running in separate process may not run normally when using .exe (should not be problems with .qmm). Your antivirus program may show a warning. For an antivirus program, unknown (not commonly downloaded) and unsigned program files may look suspicious. For example, Avast puts them into its sandbox and terminates.
Antivirus programs usually allow you to exclude some files and folders from scanning/autosandboxing. Make exclusions for your exe folder (My QM) and QM folder. It should solve the above problems. Or change autosandbox settings, if it triggers too often for other programs too.
With Quick Macros you can create, use and distribute programs without restrictions.