mirror of
https://github.com/chibicitiberiu/rainmeter-studio.git
synced 2024-02-24 04:33:31 +00:00
Installer: Include and deploy msvcr110.dll and msvcp110.dll
The msvcr110.dll and msvcp110.dll libraries are now included in the installer and extracted to InstallDir\Runtime\. The VC++ 2012 redistributable package is no longer downloaded and installed. Rainmeter.exe will first try to load Rainmeter.dll normally. If it fails, it will retry after loading Runtime\msvcp110.dll. This means that our copy of the runtimes will be used only if the system copy is either not present or somehow invalid. See Building.md for updated build instructions.
This commit is contained in:
parent
04230d608f
commit
04e3376d5a
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,4 @@
|
|||||||
|
/Build/Runtime
|
||||||
/TestBench
|
/TestBench
|
||||||
/ipch
|
/ipch
|
||||||
bin
|
bin
|
||||||
|
@ -21,11 +21,11 @@
|
|||||||
#include <crtdbg.h>
|
#include <crtdbg.h>
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include <ShellAPI.h>
|
#include <ShellAPI.h>
|
||||||
#include <delayimp.h>
|
#include <Shlwapi.h>
|
||||||
|
|
||||||
EXTERN_C IMAGE_DOS_HEADER __ImageBase;
|
EXTERN_C IMAGE_DOS_HEADER __ImageBase;
|
||||||
|
|
||||||
EXTERN_C __declspec(dllimport) int RainmeterMain(LPWSTR cmdLine);
|
typedef int (*RainmeterMainFunc)(LPWSTR cmdLine);
|
||||||
|
|
||||||
WCHAR* GetCommandLineArguments()
|
WCHAR* GetCommandLineArguments()
|
||||||
{
|
{
|
||||||
@ -59,33 +59,37 @@ WCHAR* GetCommandLineArguments()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Hook to exit the process gracefully if delay-loading dependencies (i.e. Rainmeter.dll) fails.
|
** Attempts to load Rainmeter.dll. If it fails, retries after loading our own copies of the CRT
|
||||||
**
|
** DLLs in the Runtime directory.
|
||||||
*/
|
*/
|
||||||
FARPROC WINAPI DelayLoadFailureHook(unsigned int dliNotify, DelayLoadInfo* dli)
|
HINSTANCE LoadRainmeterLibrary()
|
||||||
{
|
{
|
||||||
if (dliNotify == dliFailLoadLib)
|
HINSTANCE rmDll = LoadLibrary(L"Rainmeter.dll");
|
||||||
|
if (!rmDll)
|
||||||
{
|
{
|
||||||
WCHAR buffer[128];
|
WCHAR path[MAX_PATH];
|
||||||
int arch = 32;
|
if (GetModuleFileName(nullptr, path, MAX_PATH) > 0)
|
||||||
#ifdef _WIN64
|
|
||||||
arch = 64;
|
|
||||||
#endif
|
|
||||||
const WCHAR* format = L"%S (%i-bit) error %ld.\n\nDo you want to view help online?";
|
|
||||||
wsprintf(buffer, format, dli->szDll, arch, dli->dwLastError);
|
|
||||||
if (MessageBox(nullptr, buffer, L"Rainmeter", MB_YESNO | MB_ICONERROR) == IDYES)
|
|
||||||
{
|
{
|
||||||
ShellExecute(nullptr, L"open", L"http://rainmeter.net/dllerror", nullptr, nullptr, SW_SHOWNORMAL);
|
PathRemoveFileSpec(path);
|
||||||
|
PathAppend(path, L"Runtime");
|
||||||
|
SetDllDirectory(path);
|
||||||
|
PathAppend(path, L"msvcp110.dll");
|
||||||
|
|
||||||
|
// Loading msvcpNNN.dll will load msvcrNNN.dll as well.
|
||||||
|
HINSTANCE msvcrDll = LoadLibrary(path);
|
||||||
|
SetDllDirectory(L"");
|
||||||
|
|
||||||
|
if (msvcrDll)
|
||||||
|
{
|
||||||
|
rmDll = LoadLibrary(L"Rainmeter.dll");
|
||||||
|
FreeLibrary(msvcrDll);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ExitProcess(0);
|
return rmDll;
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
EXTERN_C PfnDliHook __pfnDliFailureHook2 = DelayLoadFailureHook;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Entry point. In Release builds, the entry point is Main() since the CRT is not used.
|
** Entry point. In Release builds, the entry point is Main() since the CRT is not used.
|
||||||
**
|
**
|
||||||
@ -105,7 +109,22 @@ int APIENTRY wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int)
|
|||||||
HRSRC iconResource = FindResource(instance, MAKEINTRESOURCE(1), RT_ICON);
|
HRSRC iconResource = FindResource(instance, MAKEINTRESOURCE(1), RT_ICON);
|
||||||
if (iconResource)
|
if (iconResource)
|
||||||
{
|
{
|
||||||
return RainmeterMain(args);
|
HINSTANCE rmDll = LoadRainmeterLibrary();
|
||||||
|
if (rmDll)
|
||||||
|
{
|
||||||
|
auto rainmeterMain = (RainmeterMainFunc)GetProcAddress(rmDll, MAKEINTRESOURCEA(1));
|
||||||
|
if (rainmeterMain)
|
||||||
|
{
|
||||||
|
return rainmeterMain(args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WCHAR message[128];
|
||||||
|
wsprintf(
|
||||||
|
message,
|
||||||
|
L"Rainmeter.dll load error %ld.",
|
||||||
|
GetLastError());
|
||||||
|
MessageBox(nullptr, message, L"Rainmeter", MB_OK | MB_ICONERROR);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -22,7 +22,9 @@
|
|||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Windows</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
<EntryPointSymbol>wWinMainCRTStartup</EntryPointSymbol>
|
<EntryPointSymbol>wWinMainCRTStartup</EntryPointSymbol>
|
||||||
<DelayLoadDLLs>Rainmeter.dll</DelayLoadDLLs>
|
<DelayLoadDLLs>
|
||||||
|
</DelayLoadDLLs>
|
||||||
|
<AdditionalDependencies>Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
<PostBuildEvent>
|
<PostBuildEvent>
|
||||||
<Command>if exist ..\testbench\x32\debug\Skins goto skip
|
<Command>if exist ..\testbench\x32\debug\Skins goto skip
|
||||||
@ -44,7 +46,9 @@ xcopy /Q /S /Y ..\Build\Themes ..\testbench\x32\debug\Layouts
|
|||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Windows</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
<EntryPointSymbol>wWinMainCRTStartup</EntryPointSymbol>
|
<EntryPointSymbol>wWinMainCRTStartup</EntryPointSymbol>
|
||||||
<DelayLoadDLLs>Rainmeter.dll</DelayLoadDLLs>
|
<DelayLoadDLLs>
|
||||||
|
</DelayLoadDLLs>
|
||||||
|
<AdditionalDependencies>Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
<PostBuildEvent>
|
<PostBuildEvent>
|
||||||
<Command>if exist ..\testbench\x64\debug\Skins goto skip
|
<Command>if exist ..\testbench\x64\debug\Skins goto skip
|
||||||
@ -70,7 +74,9 @@ xcopy /Q /S /Y ..\Build\Themes ..\testbench\x64\debug\Layouts
|
|||||||
<SubSystem>Windows</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
<EntryPointSymbol>Main</EntryPointSymbol>
|
<EntryPointSymbol>Main</EntryPointSymbol>
|
||||||
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
||||||
<DelayLoadDLLs>Rainmeter.dll</DelayLoadDLLs>
|
<DelayLoadDLLs>
|
||||||
|
</DelayLoadDLLs>
|
||||||
|
<AdditionalDependencies>Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
<PostBuildEvent>
|
<PostBuildEvent>
|
||||||
<Command>if exist ..\testbench\x32\release\Skins goto skip
|
<Command>if exist ..\testbench\x32\release\Skins goto skip
|
||||||
@ -97,7 +103,9 @@ xcopy /Q /S /Y ..\Build\Themes ..\testbench\x32\release\Layouts
|
|||||||
<SubSystem>Windows</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
<EntryPointSymbol>Main</EntryPointSymbol>
|
<EntryPointSymbol>Main</EntryPointSymbol>
|
||||||
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
||||||
<DelayLoadDLLs>Rainmeter.dll</DelayLoadDLLs>
|
<DelayLoadDLLs>
|
||||||
|
</DelayLoadDLLs>
|
||||||
|
<AdditionalDependencies>Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
<PostBuildEvent>
|
<PostBuildEvent>
|
||||||
<Command>if exist ..\testbench\x64\release\Skins goto skip
|
<Command>if exist ..\testbench\x64\release\Skins goto skip
|
||||||
|
@ -513,6 +513,10 @@ FunctionEnd
|
|||||||
|
|
||||||
SetOutPath "$INSTDIR\Plugins"
|
SetOutPath "$INSTDIR\Plugins"
|
||||||
File /x *Example*.dll "..\..\TestBench\${DIR}\Release\Plugins\*.dll"
|
File /x *Example*.dll "..\..\TestBench\${DIR}\Release\Plugins\*.dll"
|
||||||
|
|
||||||
|
SetOutPath "$INSTDIR\Runtime"
|
||||||
|
File "..\Runtime\${DIR}\msvcp110.dll"
|
||||||
|
File "..\Runtime\${DIR}\msvcr110.dll"
|
||||||
!macroend
|
!macroend
|
||||||
|
|
||||||
!macro RemoveStartMenuShortcuts STARTMENUPATH
|
!macro RemoveStartMenuShortcuts STARTMENUPATH
|
||||||
@ -542,45 +546,7 @@ Section
|
|||||||
${EndIf}
|
${EndIf}
|
||||||
|
|
||||||
${If} $InstallPortable <> 1
|
${If} $InstallPortable <> 1
|
||||||
; Download and install VC++ 2012 redist if required
|
${AndIfNot} ${AtLeastWinVista}
|
||||||
ReadRegDWORD $0 HKLM "SOFTWARE\Microsoft\VisualStudio\11.0\VC\Runtimes\$InstArc" "Bld"
|
|
||||||
ReadRegDWORD $2 HKLM "SOFTWARE\Microsoft\VisualStudio\11.0\VC\Runtimes\$InstArc" "Installed"
|
|
||||||
${If} $0 == ""
|
|
||||||
; Some VS installs do not appear to have the "VC\Runtimes" node.
|
|
||||||
ReadRegDWORD $0 HKLM "SOFTWARE\Microsoft\VisualStudio\11.0\VC\Libraries\Extended\$InstArc" "Bld"
|
|
||||||
ReadRegDWORD $2 HKLM "SOFTWARE\Microsoft\VisualStudio\11.0\VC\Libraries\Extended\$InstArc" "Install"
|
|
||||||
${EndIf}
|
|
||||||
|
|
||||||
${VersionCompare} "$0" "51106" $1
|
|
||||||
${If} $1 = 2
|
|
||||||
${OrIf} $2 <> 1
|
|
||||||
${If} ${Silent}
|
|
||||||
SetErrorLevel ${ERROR_NOVCREDIST}
|
|
||||||
Quit
|
|
||||||
${EndIf}
|
|
||||||
|
|
||||||
NSISdl::download /TIMEOUT=30000 "http://download.microsoft.com/download/1/6/B/16B06F60-3B20-4FF2-B699-5E9B7962F9AE/VSU1/vcredist_$InstArc.exe" "$PLUGINSDIR\vcredist.exe"
|
|
||||||
Pop $0
|
|
||||||
|
|
||||||
${If} $0 == "success"
|
|
||||||
ExecWait '"$PLUGINSDIR\vcredist.exe" /q /norestart' $0
|
|
||||||
Delete "$PLUGINSDIR\vcredist.exe"
|
|
||||||
|
|
||||||
${If} $0 = 3010
|
|
||||||
SetRebootFlag true
|
|
||||||
${ElseIf} $0 <> 0
|
|
||||||
MessageBox MB_OK|MB_ICONSTOP "$(VCINSTERROR)"
|
|
||||||
Quit
|
|
||||||
${EndIf}
|
|
||||||
${ElseIf} $0 == "cancel"
|
|
||||||
Quit
|
|
||||||
${Else}
|
|
||||||
MessageBox MB_OK|MB_ICONSTOP "$(VCINSTERROR)"
|
|
||||||
Quit
|
|
||||||
${EndIf}
|
|
||||||
${EndIf}
|
|
||||||
|
|
||||||
${IfNot} ${AtLeastWinVista}
|
|
||||||
; Download and install .NET if required
|
; Download and install .NET if required
|
||||||
ReadRegDWORD $0 HKLM "SOFTWARE\Microsoft\NET Framework Setup\NDP\v2.0.50727" "Install"
|
ReadRegDWORD $0 HKLM "SOFTWARE\Microsoft\NET Framework Setup\NDP\v2.0.50727" "Install"
|
||||||
${If} $0 <> 1
|
${If} $0 <> 1
|
||||||
@ -609,7 +575,6 @@ Section
|
|||||||
${EndIf}
|
${EndIf}
|
||||||
${EndIf}
|
${EndIf}
|
||||||
${EndIf}
|
${EndIf}
|
||||||
${EndIf}
|
|
||||||
|
|
||||||
SetOutPath "$INSTDIR"
|
SetOutPath "$INSTDIR"
|
||||||
|
|
||||||
@ -945,6 +910,7 @@ Section Uninstall
|
|||||||
RMDir /r "$INSTDIR\Defaults"
|
RMDir /r "$INSTDIR\Defaults"
|
||||||
RMDir /r "$INSTDIR\Languages"
|
RMDir /r "$INSTDIR\Languages"
|
||||||
RMDir /r "$INSTDIR\Plugins"
|
RMDir /r "$INSTDIR\Plugins"
|
||||||
|
RMDir /r "$INSTDIR\Runtime"
|
||||||
RMDir /r "$INSTDIR\Skins"
|
RMDir /r "$INSTDIR\Skins"
|
||||||
Delete "$INSTDIR\Rainmeter.dll"
|
Delete "$INSTDIR\Rainmeter.dll"
|
||||||
Delete "$INSTDIR\Rainmeter.exe"
|
Delete "$INSTDIR\Rainmeter.exe"
|
||||||
|
@ -11,7 +11,14 @@ After Visual Studio has been installed and updated, open Rainmeter.sln to build.
|
|||||||
|
|
||||||
### Building the installer
|
### Building the installer
|
||||||
|
|
||||||
To build the full Rainmeter distribution, run Build.bat. If you receive "not found" errors, open Build.bat and change the variables at the top to match your system.
|
To build the full Rainmeter installer, you need to get obtain 32-bit and 64-bit versions of the Visual C++ 2012 Update 3 redistributable DLLs and place them in:
|
||||||
|
|
||||||
|
* `Build\Runtime\x32\msvcr110.dll`
|
||||||
|
* `Build\Runtime\x32\msvcp110.dll`
|
||||||
|
* `Build\Runtime\x64\msvcr110.dll`
|
||||||
|
* `Build\Runtime\x64\msvcp110.dll`
|
||||||
|
|
||||||
|
Then run Build.bat. If you receive "not found" errors, open Build.bat and change the `set=` lines at the top to match your system.
|
||||||
|
|
||||||
To sign the installer and the Rainmeter executables, create a Certificate.bat file alongside Build.bat with the following contents:
|
To sign the installer and the Rainmeter executables, create a Certificate.bat file alongside Build.bat with the following contents:
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user