Make exe

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".

 

Options

Notes

Resources

Features that are unavailable in exe

Features that are different in exe

UAC

Properties -> Run in separate process

License

 

Options

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.

It is optional but should always be used. You can use the default file default.exe.manifest. Manifest enables visual styles (dialogs will look nicer). UAC: manifest specifies whether the exe must run with higher privileges. Read more below.

 

.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.

Only a single program can use the hotkey. The hotkey will not work if another instance of the program or another program already uses that hotkey. For example, Windows Explorer may use it for a shortcut. Don't use hotkeys with modifiers (Ctrl, Shift, Alt) if the macro uses keyboard/mouse commands, because then user-pressed modifier keys will be mixed with macro-pressed keys/buttons and the result may be dangerous.

 

Run functions when creating exe

When creating exe, QM can call your functions that automate related tasks. The functions receive full path of the program in the _command variable.

 

Before - a function to call before starting to create exe (when you click OK). QM waits while it is running. Error if it returns 0. The function, for example, can end the program if it is running (you can use function MakeExeCloseRunning).

 

After - function to call after the exe is successfully created. QM waits while it is running. Error if it returns 0. The function, for example, can add the exe file to a zip file. Example:

 

str s1 s2

 exe file
s1=_command

 other files
s2=
 $qm$\a.ico
 $qm$\b.bmp
 $qm$\c.dll
s1.from(s1 "[]" s2)

 add all to zip
zip "$my qm$\myexe10.zip" s1
ret 1

 

On Run - function to run when the program is launched from QM. If used, QM does not run the program. The function, for example, can run the program with a command line. Example for .exe files: run _command "/command line". Example for .qmm files: run "qmmacro.exe" F"''{_command}'' /command line". To run with command line or pass function arguments, also can be used mac.

 

Debug

 

Show added items - display in the output all added functions, items that are added as text, ActiveX control classes (read below), and image files (read below).

 

Run immediately - run the program or the "Run on Run" function automatically when the program is created.

 

Output to QM - if QM is running, display all output of the program (out, RT error, etc) in QM. If unchecked, out does nothing, unless redirected (RedirectQmOutput, ExeOutputWindow, ExeConsoleRedirectQmOutput). If unchecked or redirected, RT error is shown in a timed message box.

 

Go to error - if QM is running, show RT errors of the program in QM (open the function and show the place). This works correctly only if the function is not modified and not renamed since the program was created last time.

 

Note: the last two options are active even if the exe runs on other computers where QM is installed and running.

 

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.

SetConsoleTitle "QM test console"
ExeConsoleRedirectQmOutput ;;redirect out etc to ExeConsoleWrite

ARRAY(str) a; int i
ExeParseCommandLine _command a
for(i 0 a.len) out a[i]

ExeConsoleWrite "Type something and press Enter"
str s
ExeConsoleRead s
ExeConsoleWrite F"s=''{s}''"
2

 

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.

Notes

Where are saved Make Exe dialog settings

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.

 

How to run exe

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.

 

Source code

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.

This source code will be added to exe because need to extract the dialog definition from it.

 BEGIN DIALOG
 0 "" 0x90C80AC8 0x0 0 0 224 136 "Dialog"
 1 Button 0x54030001 0x4 116 116 48 14 "OK"
 2 Button 0x54030000 0x4 168 116 48 14 "Cancel"
 END DIALOG

if(!ShowDialog("This Macro" 0 0)) ret

 

This source code will not be added to exe because the dialog definition is in a variable. Will be added only the dialog definition string.

 

str dd=
 BEGIN DIALOG
 0 "" 0x90C80AC8 0x0 0 0 224 136 "Dialog"
 1 Button 0x54030001 0x4 116 116 48 14 "OK"
 2 Button 0x54030000 0x4 168 116 48 14 "Cancel"
 END DIALOG

if(!ShowDialog(dd 0 0)) ret

 

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.

 

Other files

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.

 

Creating Setup program

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.

 

Errors

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.

 

Global variables and settings

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.

 

Single instance

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

 at the beginning of exe main function:
SetLastError 0
__Handle m=CreateMutex(0 1 "mutex_my_exe")
if(!m) mes- "Error"
if(GetLastError=ERROR_ALREADY_EXISTS) ;;another instance of your exe is running
	 possibly execute some code here
	ret ;;exit exe

 

Command line arguments

If the program is launched with command line arguments, it is in a special variable _command. To parse, you can use function ExeParseCommandLine.

 

Exit code

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).

 

Threads

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.

 

Triggers

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

 

How to get exe file path

Use _qmdir or ExeFullPath.

 

Exe file size

QM cannot create small exe files. Minimal size is about 400 KB.

 

Speed

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).

 

Can QM create dll files?

QM can create only exe files.

 

You can use class __Tcc to create dlls in C language.

 

Supported Windows versions

Programs created with QM can run on Windows 7, 8, 10, 11. Read more below.

Resources

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

str multiline=
 :206 $qm$\keyboard.ico
 :207 $qm$\mouse.ico

 

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.

Features that are unavailable in exe

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:

Features that are different in exe

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:

 

UAC

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

Properties -> 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.

 

UAC integrity level

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.

 

Notes

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.

 

.qmm files

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.

 

Possible problems with antivirus software

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.

License

With Quick Macros you can create, use and distribute programs without restrictions.