【问题标题】:How to respond to WM_SettingChange inside an AutoHotKey script如何在 AutoHotKey 脚本中响应 WM_SettingChange
【发布时间】:2010-08-12 03:37:12
【问题描述】:

(此问题类似于Delphi: How to respond to WM_SettingChange/WM_WinIniChange?,但针对AutoHotKey 语言。这与从AutoHotKey 内部发送WM_SETTINGCHANGE 无关。)

在另一个 Windows 进程(“发送方”)中,我通过修改 HK_CURRENT_USER 注册表来更改 PATH 环境变量。然后我使用 SendMessageTimeout API 发送/发布 WM_SETTINGCHANGE 消息。

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

例如,“发件人”可能是System Properties dialog box,或者一些another AutoHotKey script

EnvUpdate

或其他一些方便的第三方 Windows 二进制文件,例如 nircmd:

nircmd sysrefresh environment

或一些Ruby code

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

【问题讨论】:

    标签: windows environment-variables autohotkey


    【解决方案1】:

    使用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 (e.g. double-click) or drag and drop onto
    ;;;  the AutoHotKey application.
    ;;;
    ;;; DEBUG
    ;;;  Optionally define a key binding to debug_show_recv_count, e.g.:
    ;;;    #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
    

    【讨论】:

      【解决方案2】:

      AutoHotKey 论坛上的用户 NoobSawce 发布了此 function to refresh environment variables

      我的 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
      

      【讨论】:

        猜你喜欢
        • 2011-02-18
        • 2013-02-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-17
        • 2018-05-07
        • 2018-01-23
        相关资源
        最近更新 更多