Dan
Posts: 4484
Joined: Wed Apr 24, 2013 3:51 pm

Force environment refresh using custom action

Tue Dec 18, 2018 3:28 pm

Hello,

There are cases when the environment variables are not refreshed during installation, so the modifications to the environment variables do not result in an immediate change. The list of environment variables is being loaded when the process is initialized but not refreshed. In order to have the newly created environment variable you can have a custom action that will force a refresh of the environment variables. Basically you need to broadcast a settings change message to all windows in the system so that any interested application can perform an update.

To overcome this behavior, you can broadcast a WM_SETTINGCHANGE message to all windows to inform them of the change.

Here's a PowerShell script that performs this task:

Code: Select all

This is what is in the inline script:

# Block for declaring the script parameters.

Param()
# Your code goes here.
Add-Type -TypeDefinition @"
    using System;
    using System.Runtime.InteropServices;

    public class NativeMethods
    {
        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        public static extern IntPtr SendMessageTimeout(
            IntPtr hWnd, uint Msg, UIntPtr wParam, string lParam,
            uint fuFlags, uint uTimeout, out UIntPtr lpdwResult);
    }
"@

$HWND_BROADCAST = [IntPtr] 0xffff
$WM_SETTINGCHANGE = 0x1a
$SMTO_ABORTIFHUNG = 0x2
$result = [UIntPtr]::Zero

[void] ([Nativemethods]::SendMessageTimeout($HWND_BROADCAST, $WM_SETTINGCHANGE, [UIntPtr]::Zero, 'Environment', $SMTO_ABORTIFHUNG, 5000, [ref] $result))
For more details, you can check the Invoke-Command to set PSModulePath article.

The sample project is attached to this thread, so if you are interested to take a look directly at my project, you are more than welcome to download the ZIP file.

Of course, you can create your custom action as a custom action written in C# or a custom action written in C++.

Best regards,
Dan
Attachments
Force Envir Refresh.zip
(3.84 KiB) Downloaded 251 times
Dan Ghiorghita - Advanced Installer Team
Follow us: Twitter - Facebook - YouTube

sjeslis
Posts: 306
Joined: Mon Aug 22, 2011 11:40 pm
Contact: Website

Re: Force environment refresh using custom action

Mon Mar 25, 2019 10:17 pm

I've used this as C# code for years in our installer as a CA DLL, method is "RefreshEnv. I now have a customer where some Windows 7 and Windows 10 machines are hanging in or on this call, see log snippet below:

MSI (s) (30:F0) [14:20:25:196]: Invoking remote custom action. DLL: C:\windows\Installer\MSI5340.tmp, Entrypoint: RefreshEnv
Action start 14:20:25: RefreshEnvironment.57BC1370_8347_47BC_8EDA_F94B982FDA46.
SFXCA: Extracting custom action to temporary directory: C:\windows\Installer\MSI5340.tmp-\
SFXCA: Binding to CLR version v4.0.30319
Calling custom action CIC.CustomActions!Cicero.CustomActions.CustomActions.RefreshEnv
Action ended 14:20:17: AI_DetectSoftware. Return value 1.

MSI (c) (20:04) [14:20:17:081]: Note: 1: 2262 2: MultipleInstances 3: -2147287038
MSI (c) (20:04) [14:20:17:081]: Note: 1: 2262 2: MultipleInstancesProps 3: -2147287038
MSI (c) (20:04) [14:20:17:081]: PROPERTY CHANGE: Deleting AI_BOOTSTRAPPER property. Its current value is '1'.
MSI (c) (20:3C) [14:24:34:054]: Destroying RemoteAPI object.
MSI (c) (20:68) [14:24:34:054]: Custom Action Manager thread ending.
=== Verbose logging stopped: 3/25/2019 14:24:34 ===

Have you guys heard this from anyone else?
Scott Jeslis
Senior Software Engineer
Cicero, Inc.

Daniel
Posts: 8174
Joined: Mon Apr 02, 2012 1:11 pm
Contact: Website

Re: Force environment refresh using custom action

Wed Mar 27, 2019 1:52 pm

Hello Scott,

I am afraid I am not aware of other reports nor of a possible workaround or solution. Maybe you try to debug you custom action implementation code on the related systems.

All the best,
Daniel
Daniel Radu - Advanced Installer Team
Follow us: Twitter - Facebook - YouTube

Return to “Sample Projects”