Modifies AutoHotkey.exe to allow scripts to do the following even while UAC is enabled:
- Interact with windows of administrative programs without running the script as administrator.
- Use SendPlay.
- There are limitations; please read the post before using this script.
This script modifies the executable file's embedded manifest, then creates and installs a self-signed certificate and uses it to sign the file. It will prompt you for source and destination file. If you select the same file as both source and destination, a backup copy will be created; otherwise, the script will ask you if you want to register a "Run with UI Access" context menu item. Either way, the destination file must be in Program Files or a sub-directory.
Do not modify the executable which this script creates or updates, since that would invalidate its digital signature.
The executable will not run on any other system, unless you install the certificate used to sign the file. To do this on Windows Vista or 7, right click the executable file, click Properties, go to the Digital Signatures tab, double-click the signature, click View Certificate, then click Install Certificate and follow the prompts. If prompted to select a certificate store, choose Trusted Root Certificate Authorities.
CreateProcess fails - Attempting to launch the executable with CreateProcess results in failure - "The requested operation requires elevation." This isn't a problem for the Run command since it falls back to ShellExecuteEx, but it may affect other programs which try to launch AutoHotkey (including SciTE and perhaps other editors).
In the following, "UIA" means "UI Access".
ComObjActive/ComObjGet may fail. UIA programs are probably only able to access the active objects of other UIA programs, not regular programs. For example,
ComObjActive("Word.Application") will fail because Word is not marked for UI access. The reverse is also true: objects registered by UIA scripts can only be accessed by other UIA programs/scripts.
The script's own windows can't be automated by non-UIA programs/scripts. This isn't a problem if you run all your scripts with UI access. However, testing has shown that running a non-UIA script which uses a mouse hook (even as simple as
#InstallMouseHook) may prevent all mouse hotkeys from working when the mouse is pointing at a window owned by a UIA script, even hotkeys implemented by the UIA script itself. This might also apply to keyboard hooks, but I have been unable to confirm that. A workaround is to ensure UIA scripts are loaded last.
With User Account Control (UAC) enabled, most programs are prevented from interacting with any windows which are running at a higher privilege level. For AutoHotkey, this usually means that hotkeys and Send won't work with administrative programs unless the script is also run as administrator. Running a script as administrator is fairly simple; however, it has at least two significant drawbacks:
- The need to deal with a UAC prompt each time the script starts.
- Any programs the script launches also receive administrative privileges.
Microsoft's recommended solution is to flag the application as one that needs "UI access," with the following additional requirements:
- The executable must be digitally signed with a trusted certificate.
- The executable must be in \Program Files\ or \Windows\System32\.
(On my x64 system, \Program Files (x86)\ also seems to satisfy this requirement.)
This could be solved once and for all by signing AutoHotkey.exe before distribution, except for the following problems:
- Certificates signed by a trusted certificate authority cost money, and typically need to be renewed each year.
- If I were to buy a certificate and use it to sign AutoHotkey.exe, every time any script triggered a UAC prompt, my name would appear. I would not like that (I will not be held accountable for the actions of scripts I did not write).
- If a self-signed certificate is used, it would need to be installed on each system before AutoHotkey.exe can run on that system.
- The several limitations listed above.
The script can be supplied with one or two filenames on the command line, in which case it will attempt to silently create or update the destination executable file. If the script has been run before, it will reuse the "AutoHotkey" certificate created by a prior run. This certificate can be found in the user's "Personal" certificate store.
I have not tested the script with AutoHotkey Basic. It will not run on AutoHotkey Basic, but running the script on AutoHotkey_L and selecting an AutoHotkey Basic EXE as input will probably work.
I have not tested this script with a compiled script as input. Without a commercial digital signature, it probably wouldn't be very useful since the resulting EXE would not be very portable. However, it should work if given a script compiled with AutoHotkey_L v1.1.01 or later.