Skip to content

Commit

Permalink
win,msi: broadcast WM_SETTINGCHANGE after install
Browse files Browse the repository at this point in the history
In theory the msi should broadcast a 'WM_SETTINGCHANGE' message to all
windows after modifying the PATH environment variable. This ensures that
the new PATH is visible to other processes without restarting windows
(although it's still necessary to close and reopen active console
windows).

Unfortunately, the broadcast doesn't always happen, for unknown reasons.
That's why this patch adds a custom action that unconditionally
broadcasts a WM_SETTINGCHANGE message.

Bug: #603
PR: #613
Reviewed-by: Bert Belder <bertbelder@gmail.com>
  • Loading branch information
mathiask88 authored and piscisaureus committed Jan 27, 2015
1 parent 69ce064 commit 668bde8
Show file tree
Hide file tree
Showing 7 changed files with 258 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -29,6 +29,7 @@ Release/
*.suo
*.vcproj
*.vcxproj
!custom_actions.vcxproj
*.vcxproj.user
*.vcxproj.filters
UpgradeLog*.XML
Expand Down
42 changes: 42 additions & 0 deletions tools/msvs/msi/custom_actions.c
@@ -0,0 +1,42 @@

#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <msiquery.h>
#include <wcautil.h>


UINT WINAPI BroadcastEnvironmentUpdate(MSIHANDLE hInstall) {
HRESULT hr = S_OK;
UINT er = ERROR_SUCCESS;

hr = WcaInitialize(hInstall, "BroadcastEnvironmentUpdate");
ExitOnFailure(hr, "Failed to initialize");

SendMessageTimeoutW(HWND_BROADCAST,
WM_SETTINGCHANGE,
0,
(LPARAM) L"Environment",
SMTO_ABORTIFHUNG,
5000,
NULL);

LExit:
er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
return WcaFinalize(er);
}


BOOL WINAPI DllMain(HINSTANCE hInst, ULONG ulReason, VOID* dummy) {
switch (ulReason) {
case DLL_PROCESS_ATTACH:
WcaGlobalInitialize(hInst);
break;

case DLL_PROCESS_DETACH:
WcaGlobalFinalize();
break;
}

return TRUE;
}
4 changes: 4 additions & 0 deletions tools/msvs/msi/custom_actions.def
@@ -0,0 +1,4 @@
LIBRARY "custom_actions"

EXPORTS
BroadcastEnvironmentUpdate
181 changes: 181 additions & 0 deletions tools/msvs/msi/custom_actions.vcxproj
@@ -0,0 +1,181 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{B70585F8-DAB7-40FA-9904-13CF53A73A06}</ProjectGuid>
<RootNamespace>BroadcastPathUpdateCustomAction</RootNamespace>
<Keyword>Win32Proj</Keyword>
<ProjectName>custom_actions</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>12.0.30501.0</_ProjectFileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>$(WIX)sdk\VS2013\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>msi.lib;dutil.lib;wcautil.lib;version.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(WIX)sdk\VS2013\lib\x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<ModuleDefinitionFile>custom_actions.def</ModuleDefinitionFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>$(WIX)sdk\VS2013\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>msi.lib;dutil.lib;wcautil.lib;version.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(WIX)sdk\VS2013\lib\x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<ModuleDefinitionFile>custom_actions.def</ModuleDefinitionFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>$(WIX)sdk\VS2013\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile>
</PrecompiledHeaderFile>
<PrecompiledHeaderOutputFile>
</PrecompiledHeaderOutputFile>
</ClCompile>
<Link>
<AdditionalDependencies>msi.lib;dutil.lib;wcautil.lib;version.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(WIX)sdk\VS2013\lib\x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<ModuleDefinitionFile>custom_actions.def</ModuleDefinitionFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>$(WIX)sdk\VS2013\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile>
</PrecompiledHeaderFile>
<PrecompiledHeaderOutputFile>
</PrecompiledHeaderOutputFile>
</ClCompile>
<Link>
<AdditionalDependencies>msi.lib;dutil.lib;wcautil.lib;version.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(WIX)sdk\VS2013\lib\x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<ModuleDefinitionFile>custom_actions.def</ModuleDefinitionFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="custom_actions.c">
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="custom_actions.def" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
10 changes: 10 additions & 0 deletions tools/msvs/msi/nodemsi.sln
Expand Up @@ -3,6 +3,8 @@ Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "nodemsi", "nodemsi.wixproj", "{1D808FF0-B5A9-4BE9-859D-B334B6F48BE2}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "custom_actions", "custom_actions.vcxproj", "{B70585F8-DAB7-40FA-9904-13CF53A73A06}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Expand All @@ -19,6 +21,14 @@ Global
{1D808FF0-B5A9-4BE9-859D-B334B6F48BE2}.Release|x64.Build.0 = Release|x64
{1D808FF0-B5A9-4BE9-859D-B334B6F48BE2}.Release|x86.ActiveCfg = Release|x86
{1D808FF0-B5A9-4BE9-859D-B334B6F48BE2}.Release|x86.Build.0 = Release|x86
{B70585F8-DAB7-40FA-9904-13CF53A73A06}.Debug|x64.ActiveCfg = Debug|x64
{B70585F8-DAB7-40FA-9904-13CF53A73A06}.Debug|x64.Build.0 = Debug|x64
{B70585F8-DAB7-40FA-9904-13CF53A73A06}.Debug|x86.ActiveCfg = Debug|Win32
{B70585F8-DAB7-40FA-9904-13CF53A73A06}.Debug|x86.Build.0 = Debug|Win32
{B70585F8-DAB7-40FA-9904-13CF53A73A06}.Release|x64.ActiveCfg = Release|x64
{B70585F8-DAB7-40FA-9904-13CF53A73A06}.Release|x64.Build.0 = Release|x64
{B70585F8-DAB7-40FA-9904-13CF53A73A06}.Release|x86.ActiveCfg = Release|Win32
{B70585F8-DAB7-40FA-9904-13CF53A73A06}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
10 changes: 10 additions & 0 deletions tools/msvs/msi/nodemsi.wixproj
Expand Up @@ -56,6 +56,16 @@
<ItemGroup>
<EmbeddedResource Include="WixUI_en-us.wxl" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="custom_actions.vcxproj">
<Name>custom_actions</Name>
<Project>{b70585f8-dab7-40fa-9904-13cf53a73a06}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
</ItemGroup>
<Import Project="$(WixTargetsPath)" />
<Target Name="BeforeBuild">
<HeatDirectory ToolPath="$(WixToolPath)" Directory="..\..\..\deps\npm" PreprocessorVariable="var.NpmSourceDir" DirectoryRefId="NodeModulesFolder" ComponentGroupName="NpmSourceFiles" GenerateGuidsNow="true" SuppressFragments="false" OutputFile="..\..\..\npm.wxs" RunAsSeparateProcess="true">
Expand Down
10 changes: 10 additions & 0 deletions tools/msvs/msi/product.wxs
Expand Up @@ -269,10 +269,20 @@
Execute="deferred"
Return="check" />

<Binary Id='BroadcastEnvironmentUpdate'
SourceFile='$(var.custom_actions.TargetDir)$(var.custom_actions.TargetName).dll' />

<CustomAction Id="BroadcastEnvironmentUpdate"
BinaryKey="BroadcastEnvironmentUpdate"
DllEntry="BroadcastEnvironmentUpdate"
Execute="immediate"
Return="check" />

<InstallExecuteSequence>
<Custom Action="LinkNodeExeToIojsExe" After="InstallFiles">
$NodeAlias = 3
</Custom>
<Custom Action='BroadcastEnvironmentUpdate' After='InstallFinalize'/>
</InstallExecuteSequence>

<UI Id="NodeInstallUI">
Expand Down

0 comments on commit 668bde8

Please sign in to comment.