为什么视觉工作室在自动热键之前捕捉关键事件?

我最近把 DVORAK 键盘布局作为一个小小的实验。转变过程中最困难的部分之一就是处理热键。大多数热键设计的 QWERTY 在心里,并且,更糟糕的是,热键似乎是非常肌肉记忆束缚。

我没有重新学习所有的热键,而是编写了一个自动热键脚本,当 CtrlAltWin键与其他键一起按时,将 Dvorak 布局翻译回 QWERTY。我试过的所有地方都很好用,除了 Visual Studio’08。看起来在自动热键翻译之前击键被捕获了。

为什么会这样,我该怎么补救?

以下是我的剧本(从一开始)的摘录:

; control + letter
^;::^z
^q::^x
^j::^c
^k::^v

更新: 该脚本在新安装了 ahk、 vs08和 coderush 的 Win7上运行良好。我操作不了的那台机器正在运行 Vista。对于如何进一步诊断有什么想法吗?

更新2: 该脚本在 Vista 和2010 beta 2中运行良好。似乎只是 VS 08 + Vista 的东西。今晚要重新安装 vs08。

8950 次浏览

Aha! I've figured it out. If ahk and the target app are not running under the same privileges (or user) ahk won't intercept/simulate keyboard events properly. In my case, visual studio was run with administrator (elevated) privileges while the ahk script was run as the currently logged on user.

Either of the following solved the problem:

  • Running both vs and ahk as the current user
  • Compiling the script and running both vs and the compiled app as administrator

Just want to add a couple of points to solution found by the OP himself.

1) The problem is not with AHK and VS running with different permissions - its just that hotkeys created by a script running in a non-admin mode wouldn't work on applications running in the admin mode, but there would be no problem if it's the other way round.

2) There is no need to compile the script necessarily, just set autohotkey.exe to run in the admin mode (that's what I do), or alternatively create a shortcut to the particular script and set it to always run in admin mode. (btw, just to point out, there is no performance gain by running a compiled version of an AHK script, because the code is still interpreted - its just that now the interpreter is embedded in the executable created)

Apparently there is a workaround for this.

From the docs Program.htm#Installer_uiAccess.
Forum thread by Lexikos

Excerpt:

EnableUIAccess

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.

The download link to the ahk file is broken on the forum but I found it on Github: EnableUIAccess.ahk

This is due to a security feature called User Interface Privilege Isolation (UIPI), which is part of User Account Control (UAC).

There are several workarounds listed in the FAQ:

How do I work around problems caused by User Account Control (UAC)?

Common workarounds are as follows:

  • Enable the Add 'Run with UI Access' to context menus option in AutoHotkey Setup. This option can be enabled or disabled without reinstalling AutoHotkey by re-running AutoHotkey Setup from the Start menu. Once it is enabled, launch your script file by right-clicking it and selecting Run with UI Access, or use a command line like "AutoHotkeyU32_UIA.exe" "Your script.ahk" (but include full paths).
  • Run the script as administrator. Note that this also causes any programs launched by the script to run as administrator, and may require the user to accept an approval prompt when launching the script.
  • Disable the local security policy "Run all administrators in Admin Approval Mode" (not recommended).
  • Disable UAC completely. This is not recommended, and is not feasible on Windows 8 or later.

I generally do not recommend running a script as administrator to work around this issue, as it has side-effects that might be unexpected or undesired. For example, any program that the script launches with Run will also run as administrator. The script will also have unnecessary write permission to various folders, such as Program Files. A bit of bad code (malicious code copy-pasted from somewhere, or code with a bug) could do more damage this way.

Of course, I do not recommend the last two options either. That leaves only Run with UI Access, which can be enabled and used as described above.