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:
Birunthan Mohanathas
2013-10-19 16:49:48 +03:00
parent 04230d608f
commit 04e3376d5a
5 changed files with 78 additions and 77 deletions

View File

@ -21,11 +21,11 @@
#include <crtdbg.h>
#include <Windows.h>
#include <ShellAPI.h>
#include <delayimp.h>
#include <Shlwapi.h>
EXTERN_C IMAGE_DOS_HEADER __ImageBase;
EXTERN_C __declspec(dllimport) int RainmeterMain(LPWSTR cmdLine);
typedef int (*RainmeterMainFunc)(LPWSTR cmdLine);
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];
int arch = 32;
#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)
WCHAR path[MAX_PATH];
if (GetModuleFileName(nullptr, path, MAX_PATH) > 0)
{
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");
ExitProcess(0);
// Loading msvcpNNN.dll will load msvcrNNN.dll as well.
HINSTANCE msvcrDll = LoadLibrary(path);
SetDllDirectory(L"");
if (msvcrDll)
{
rmDll = LoadLibrary(L"Rainmeter.dll");
FreeLibrary(msvcrDll);
}
}
}
return nullptr;
return rmDll;
}
EXTERN_C PfnDliHook __pfnDliFailureHook2 = DelayLoadFailureHook;
/*
** 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);
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
{

View File

@ -22,7 +22,9 @@
<Link>
<SubSystem>Windows</SubSystem>
<EntryPointSymbol>wWinMainCRTStartup</EntryPointSymbol>
<DelayLoadDLLs>Rainmeter.dll</DelayLoadDLLs>
<DelayLoadDLLs>
</DelayLoadDLLs>
<AdditionalDependencies>Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PostBuildEvent>
<Command>if exist ..\testbench\x32\debug\Skins goto skip
@ -44,7 +46,9 @@ xcopy /Q /S /Y ..\Build\Themes ..\testbench\x32\debug\Layouts
<Link>
<SubSystem>Windows</SubSystem>
<EntryPointSymbol>wWinMainCRTStartup</EntryPointSymbol>
<DelayLoadDLLs>Rainmeter.dll</DelayLoadDLLs>
<DelayLoadDLLs>
</DelayLoadDLLs>
<AdditionalDependencies>Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PostBuildEvent>
<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>
<EntryPointSymbol>Main</EntryPointSymbol>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<DelayLoadDLLs>Rainmeter.dll</DelayLoadDLLs>
<DelayLoadDLLs>
</DelayLoadDLLs>
<AdditionalDependencies>Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PostBuildEvent>
<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>
<EntryPointSymbol>Main</EntryPointSymbol>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<DelayLoadDLLs>Rainmeter.dll</DelayLoadDLLs>
<DelayLoadDLLs>
</DelayLoadDLLs>
<AdditionalDependencies>Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PostBuildEvent>
<Command>if exist ..\testbench\x64\release\Skins goto skip