2010-08-12 14 views
1

(Cette question est similaire à Delphi: How to respond to WM_SettingChange/WM_WinIniChange? mais pour la langue AutoHotKey. Ce n'est pas sur l'envoi WM_SETTINGCHANGE à l'intérieur AutoHotKey.)Comment répondre à WM_SETTINGCHANGE l'intérieur d'un script AutoHotKey

Dans un autre processus de Windows (« expéditeur »), Je modifie la variable d'environnement PATH en modifiant le Registre HK_CURRENT_USER. Puis j'envoie/publie un message WM_SETTINGCHANGE en utilisant l'API SendMessageTimeout.

Mon script AutoHotKey en cours d'exécution ("receiver"), que j'utilise en tant que programme de lancement, ne semble pas être au courant de la modification. Je veux capturer ce message afin d'actualiser la copie locale du script de la variable PATH. C'est possible?

Par exemple, le "expéditeur" pourrait être le System Properties dialog box, ou quelque another AutoHotKey script:

EnvUpdate 

ou un autre binaire de Windows à portée de main tiers comme nircmd:

nircmd sysrefresh environment 

ou un 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 

Répondre

1

Utilisez le OnMessage fonction pour répondre au message.

Voici un exemple de script.

;;; 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 
0

Le NoobSawce utilisateur sur les forums AutoHotKey a publié ce function to refresh environment variables. Mon script AutoHotKey.ahk appelle cette fonction avant chaque instruction Run afin que toutes les applications lancées à partir d'AutoHotKey obtiennent l'environnement système actuel, et non l'environnement capturé par AutoHotKey au moment de son lancement.

Par exemple:

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