代码之家  ›  专栏  ›  技术社区  ›  Matteo NNZ

在不重新启动Excel的情况下重新加载环境变量?

  •  4
  • Matteo NNZ  · 技术社区  · 7 年前

    我使用这个函数 Environ() 从正在运行的Excel实例获取环境变量。 当在系统中定义了一个新变量时,Excel将不知道它,直到它重新启动。

    我的问题是: 是否有任何方法可以在不需要重新启动Excel的情况下获取环境变量的新值?

    测试用例是:

    • Windows搜索/系统/高级系统设置/环境变量
    • 打开Microsoft Excel
    • 定义一个新的用户变量,比如 TESTING 有价值 Whatever

    enter image description here

    • 运行以下宏:

      Sub test()
      
          MsgBox "TESTING:" & Environ("TESTING")
      
      End Sub
      

    …变量为空:

    enter image description here

    • 重新启动Microsoft Excel
    • 再次运行同一个宏:变量现在已加载。

    enter image description here

    2 回复  |  直到 7 年前
        1
  •  4
  •   omegastripes    7 年前
    Sub Test()
    
        MsgBox CreateObject("WScript.Shell").Environment("system").Item("testing")
    
    End Sub
    
        2
  •  2
  •   catcat    7 年前

    您需要将Excel窗口子类化并截获 wm_settingchange 从控制面板环境对象发送的消息,以及 setx .

    这是vb.net-lparam包含一个指向字符串的指针 Environment . 由你自己来决定发生了什么变化。

    Console.writeline(Marshal.PtrToStringUni(lparam))
    

    回到VB6/VBA

    这里有一些钩住和解开的代码以及一个winproc。您可以从中获取Excel的硬件 excel.application hWnd 财产。

    Public Sub Hook()
       lpPrevWndProc = SetWindowLong(EditNote.gRtfHwnd, GWL_WNDPROC, _
       AddressOf gWindowProc)
    End Sub
    

    Public Sub Unhook()
       Dim temp As Long
       temp = SetWindowLong(EditNote.gRtfHwnd, GWL_WNDPROC, lpPrevWndProc)
    End Sub
    

    Public Function gWindowProc(ByVal hwnd As Long, ByVal Msg As Long, _
                     ByVal wParam As Long, ByVal lParam As Long) As Long
       If Msg = WM_CONTEXTMENU Then
            If EditNote.mnuViewEditContextMenu.Checked Then EditNote.PopupMenu EditNote.mnuEdit
    '        gWindowProc = CallWindowProc(lpPrevWndProc, hWnd, Msg, wParam, _
             lParam)
       Else ' Send all other messages to the default message handler
          gWindowProc = CallWindowProc(lpPrevWndProc, hwnd, Msg, wParam, _
             lParam)
       End If
    End Function
    

    每个应用程序都会获取其父级环境内存块的副本。一个程序不能访问另一个程序的内存-所以这是一种方法。只有Windows资源管理器才会侦听此消息。因此,更新后的变量仅在Windows资源管理器和由资源管理器启动的任何新程序中可用。注意:cmd不会听这个。