private/Invoke-BroadcastEnvChanged.ps1
function Invoke-BroadcastEnvChanged { <# .Synopsis Tells the system that environment variables changed. #> [OutputType()] param ( ) begin { } process { $className = 'PhpManager_Env_Broadcaster_v1' $classType = ([System.Management.Automation.PSTypeName]$className).Type if ($null -eq $classType) { Add-Type -Language CSharp -TypeDefinition @" using System; using System.ComponentModel; using System.Runtime.InteropServices; public sealed class $className { /// <summary> /// Send the message to all top-level windows in the system, including disabled or invisible unowned windows. /// </summary> private const int HWND_BROADCAST = 0xffff; /// <summary> /// Possible messages to be sent. /// </summary> private enum SmtoMsg : uint { /// <summary> /// A message that is sent to all top-level windows when the SystemParametersInfo function changes a system-wide setting or when policy settings have changed. /// </summary> WM_SETTINGCHANGE = 0x001A, } /// <summary> /// Possible flags of the SendMessageTimeout function /// </summary> [Flags] private enum SmtoFlags : uint { /// <summary> /// The function returns without waiting for the time-out period to elapse if the receiving thread appears to not respond or "hangs." /// </summary> SMTO_ABORTIFHUNG = 0x0002, /// <summary> /// Prevents the calling thread from processing any other requests until the function returns. /// </summary> SMTO_BLOCK = 0x0001, /// <summary> /// The calling thread is not prevented from processing other requests while waiting for the function to return. /// </summary> SMTO_NORMAL = 0x0000, /// <summary> /// The function does not enforce the time-out period as long as the receiving thread is processing messages. /// </summary> SMTO_NOTIMEOUTIFNOTHUNG = 0x0008, /// <summary> /// The function should return 0 if the receiving window is destroyed or its owning thread dies while the message is being processed. /// </summary> SMTO_ERRORONEXIT = 0x0020, } /// <summary> /// Sends the specified message to one or more windows. /// </summary> /// <param name="hWnd">A handle to the window whose window procedure will receive the message.</param> /// <param name="Msg">The message to be sent.</param> /// <param name="wParam">Any additional message-specific information.</param> /// <param name="lParam">Any additional message-specific information.</param> /// <param name="fuFlags">The behavior of this function.</param> /// <param name="uTimeout">The duration of the time-out period, in milliseconds.</param> /// <param name="lpdwResult">The result of the message processing.</param> /// <returns>If the function fails or times out, the return value is 0.</returns> [DllImport("user32.dll", BestFitMapping = false, ThrowOnUnmappableChar = true, SetLastError = true)] private static extern IntPtr SendMessageTimeout(IntPtr hWnd, UInt32 Msg, IntPtr wParam, String lParam, UInt32 fuFlags, UInt32 uTimeout, IntPtr lpdwResult); /// <summary> /// Broadcasts a "Environment settings changed" message. /// </summary> /// <exception cref="System.TimeoutException">Throws a TimeoutException when the message timed out.</exception> /// <exception cref="System.System.ComponentModel.Win32Exception">Throws a Win32Exception when the function fails.</exception> public static void BroadcastEnvironmentChange() { IntPtr lResult = SendMessageTimeout(new IntPtr(HWND_BROADCAST), (UInt32)SmtoMsg.WM_SETTINGCHANGE, IntPtr.Zero, "Environment", (UInt32)SmtoFlags.SMTO_ABORTIFHUNG, 1000, IntPtr.Zero); if (lResult == IntPtr.Zero) { int rc = Marshal.GetLastWin32Error(); if (rc == 0) { throw new TimeoutException("SendMessageTimeout() timed out"); } throw new Win32Exception(rc); } } } "@ $classType = ([System.Management.Automation.PSTypeName]$className).Type } $classType.GetMethod('BroadcastEnvironmentChange').Invoke($null, @()) Write-Verbose -Message 'Environment change has been broacasted' } end { } } |