如何响应AutoHotKey脚本中的WM_SettingChange

(这个问题类似于Delphi:如何响应WM_SettingChange / WM_WinIniChange?但是AutoHotKey语言。这不是从AutoHotKey内部发送WM_SETTINGCHANGE。)

在另一个Windows进程(“发件人”)中,我通过修改HK_CURRENT_USERregistry来更改PATH环境variables。 然后,我使用SendMessageTimeout API发送/发布WM_SETTINGCHANGE消息。

我用作程序启动器的同时运行的AutoHotKey脚本(“receiver”)似乎并没有意识到这种变化。 我想要捕获此消息以刷新脚本的PATHvariables的本地副本。 可能吗?

例如,“发件人”可以是“ 系统属性”对话框或其他一些AutoHotKey脚本 :

EnvUpdate 

或者像nircmd这样的其他方便的第三方Windows二进制文件 :

 nircmd sysrefresh environment 

或者一些Ruby代码 :

 ### This is a -*- ruby -*- script require 'Win32API' module Windows::EnvByReg def self.envupdate() result = 0 wParam_unused = 0 timeout_ms = 5000 SendMessageTimeout.call(HWND_BROADCAST, WM_SETTINGCHANGE, wParam_unused, 'Environment', SMTO_ABORTIFHUNG, timeout_ms, result) end SendMessageTimeout = Win32API.new('user32', 'SendMessageTimeout', 'LLLPLLP', 'L') HWND_BROADCAST = 0xffff WM_SETTINGCHANGE = 0x001A SMTO_ABORTIFHUNG = 2 end#module if __FILE__ == $PROGRAM_NAME Windows::EnvByReg.envupdate end 

使用OnMessage函数来回复消息。

这是一个示例脚本。

 ;;; This is an AutoHotKey -*- ahk -*- script ;;; ;;; ABOUT ;;; Respond to WM_SETTINGCHANGE messages and update this process's PATH ;;; environment variable. ;;; ;;; USAGE ;;; Run the script directly (eg double-click) or drag and drop onto ;;; the AutoHotKey application. ;;; ;;; DEBUG ;;; Optionally define a key binding to debug_show_recv_count, eg: ;;; #space:: debug_show_recv_count() ;;; ;;; AUTHOR ;;; piyo @ StackOverflow ;;; ;; ;; Register an AHK function as a callback. ;; OnMessage( (WM_SETTINGCHANGE:=0x1A), "recv_WM_SETTINGCHANGE") ;; ;; Respond to the WM_SETTINGCHANGE message. ;; recv_WM_SETTINGCHANGE(wParam, lParam, msg, hwnd) { global g_recv_WM_SETTINGCHANGE_count g_recv_WM_SETTINGCHANGE_count := g_recv_WM_SETTINGCHANGE_count + 1 ;;debug;; ToolTip Received a WM_SETTINGCHANGE ! reset_env_path_from_registry() } ;; ;; Import the recently changed Path environment variable from the ;; Windows Registry. Import from the System and User environments. ;; reset_env_path_from_registry() { sys_path := "" sys_subkey := "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" RegRead, sys_path, HKEY_LOCAL_MACHINE, %sys_subkey%, Path cu_path := "" cu_subkey := "Environment" RegRead, cu_path, HKEY_CURRENT_USER, %cu_subkey%, Path new_path := sys_path . ";" . cu_path ;;debug;; MsgBox,% new_path EnvSet, PATH,% new_path } ;;; ; Debug var for interactive sanity checking g_recv_WM_SETTINGCHANGE_count := 0 ; Debug function for interactive sanity checking debug_show_recv_count() { global g_recv_WM_SETTINGCHANGE_count path := "" EnvGet, path, PATH msg := "g_recv_WM_SETTINGCHANGE := " . g_recv_WM_SETTINGCHANGE_count msg := msg . "!`n" . path MsgBox,% msg } ;;; end 

AutoHotKey论坛上的用户NoobSawce发布了这个函数来刷新环境变量 。

我的AutoHotKey.ahk脚本在每个Run语句之前调用该函数,以便从AutoHotKey启动的任何应用程序都能获得当前的系统环境,而不是AutoHotKey在启动时捕获的环境。

例如:

 +#b:: RefreshEnvironment() run c:\cygwin\bin\run.exe c:\cygwin\bin\rxvt.exe -geometry 80x40 return +#g:: RefreshEnvironment() run c:\gnu\emacs\bin\runemacs.exe return