rainmeter-studio/Application/Application.cpp
Birunthan Mohanathas 04e3376d5a 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.
2013-10-19 16:49:48 +03:00

163 lines
4.0 KiB
C++

/*
Copyright (C) 2001 Kimmo Pekkola
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#define _CRTDBG_MAP_ALLOC
#define WIN32_LEAN_AND_MEAN
#include <crtdbg.h>
#include <Windows.h>
#include <ShellAPI.h>
#include <Shlwapi.h>
EXTERN_C IMAGE_DOS_HEADER __ImageBase;
typedef int (*RainmeterMainFunc)(LPWSTR cmdLine);
WCHAR* GetCommandLineArguments()
{
WCHAR* args = GetCommandLine();
// Skip past (quoted) application path in cmdLine.
if (*args == L'"')
{
++args; // Skip leading quote.
while (*args && *args != L'"')
{
++args;
}
++args; // Skip trailing quote.
}
else
{
while (*args && *args != L' ')
{
++args;
}
}
// Skip leading whitespace (similar to CRT implementation).
while (*args && *args <= L' ')
{
++args;
}
return args;
}
/*
** Attempts to load Rainmeter.dll. If it fails, retries after loading our own copies of the CRT
** DLLs in the Runtime directory.
*/
HINSTANCE LoadRainmeterLibrary()
{
HINSTANCE rmDll = LoadLibrary(L"Rainmeter.dll");
if (!rmDll)
{
WCHAR path[MAX_PATH];
if (GetModuleFileName(nullptr, path, MAX_PATH) > 0)
{
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);
}
}
}
return rmDll;
}
/*
** Entry point. In Release builds, the entry point is Main() since the CRT is not used.
**
*/
int APIENTRY wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int)
{
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
//_CrtSetBreakAlloc(000);
// Prevent system error message boxes.
UINT oldMode = SetErrorMode(0);
SetErrorMode(oldMode | SEM_FAILCRITICALERRORS);
HINSTANCE instance = (HINSTANCE)&__ImageBase;
WCHAR* args = GetCommandLineArguments();
HRSRC iconResource = FindResource(instance, MAKEINTRESOURCE(1), RT_ICON);
if (iconResource)
{
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
{
// Stub prodecure. If icon resources have been removed, try to launch the actual Rainmeter.exe.
HKEY hKey;
const REGSAM desiredSam = KEY_QUERY_VALUE | KEY_WOW64_32KEY;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"Software\\Rainmeter", 0, desiredSam, &hKey) == ERROR_SUCCESS)
{
const DWORD size = MAX_PATH;
WCHAR buffer[size];
DWORD type = 0;
if (RegQueryValueEx(hKey, nullptr , nullptr, &type, (LPBYTE)buffer, (LPDWORD)&size) == ERROR_SUCCESS &&
type == REG_SZ)
{
SetCurrentDirectory(buffer);
lstrcat(buffer, L"\\Rainmeter.exe");
ShellExecute(nullptr, L"open", buffer, args, nullptr, SW_SHOWNORMAL);
}
RegCloseKey(hKey);
}
return 0;
}
return 1;
}
#ifndef _DEBUG
EXTERN_C int WINAPI Main()
{
int result = wWinMain(nullptr, nullptr, nullptr, 0);
ExitProcess(result);
return 0; // Never reached.
}
#endif