Как ответить на WM_SettingChange внутри скрипта AutoHotKey - PullRequest
1 голос
/ 12 августа 2010

(Этот вопрос похож на Delphi: как ответить на WM_SettingChange / WM_WinIniChange? , но для языка AutoHotKey . Это не относится к отправке WM_SETTINGCHANGE изнутри AutoHotKey.)

В другом процессе Windows («отправитель») я изменяю переменную среды PATH, изменяя реестр HK_CURRENT_USER.Затем я отправляю / публикую сообщение WM_SETTINGCHANGE с помощью API SendMessageTimeout.

Мой одновременно запущенный скрипт AutoHotKey («получатель»), который я использую в качестве средства запуска программ, похоже, не знает об изменении.Я хочу перехватить это сообщение, чтобы обновить локальную копию сценария переменной PATH.Возможно ли это?

Например, "отправителем" может быть диалоговое окно Свойства системы или какой-нибудь другой скрипт AutoHotKey :

EnvUpdate

или какой-нибудь другой удобный бинарный файл Windows, например nircmd :

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

Ответы [ 2 ]

1 голос
/ 12 августа 2010

Используйте функцию 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
0 голосов
/ 21 февраля 2011

Пользователь NoobSawce на форумах AutoHotKey опубликовал эту функцию для обновления переменных среды .

Мой скрипт 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
...