From 426ea607e88d22319d8fddb9eaf684d6b7d2df4b Mon Sep 17 00:00:00 2001 From: huanghongxun Date: Fri, 8 Feb 2019 22:05:16 +0800 Subject: [PATCH] HMCLauncher: try bundled JRE --- HMCLauncher/HMCL/HMCL.cpp | Bin 12854 -> 0 bytes HMCLauncher/HMCL/HMCL.h | Bin 80 -> 0 bytes HMCLauncher/HMCL/HMCL.vcxproj | 12 ++- HMCLauncher/HMCL/HMCL.vcxproj.filters | 22 +++++- HMCLauncher/HMCL/Version.cpp | 15 ++++ HMCLauncher/HMCL/Version.h | 20 +++++ HMCLauncher/HMCL/java.cpp | 88 +++++++++++++++++++++ HMCLauncher/HMCL/java.h | 10 +++ HMCLauncher/HMCL/main.cpp | 79 +++++++++++++++++++ HMCLauncher/HMCL/main.h | 3 + HMCLauncher/HMCL/os.cpp | 108 ++++++++++++++++++++++++++ HMCLauncher/HMCL/os.h | 23 ++++++ 12 files changed, 375 insertions(+), 5 deletions(-) delete mode 100644 HMCLauncher/HMCL/HMCL.cpp delete mode 100644 HMCLauncher/HMCL/HMCL.h create mode 100644 HMCLauncher/HMCL/Version.cpp create mode 100644 HMCLauncher/HMCL/Version.h create mode 100644 HMCLauncher/HMCL/java.cpp create mode 100644 HMCLauncher/HMCL/java.h create mode 100644 HMCLauncher/HMCL/main.cpp create mode 100644 HMCLauncher/HMCL/main.h create mode 100644 HMCLauncher/HMCL/os.cpp create mode 100644 HMCLauncher/HMCL/os.h diff --git a/HMCLauncher/HMCL/HMCL.cpp b/HMCLauncher/HMCL/HMCL.cpp deleted file mode 100644 index 94c42fbbbede8c231ba7eb534e0a83256482ff32..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12854 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 diff --git a/HMCLauncher/HMCL/HMCL.h b/HMCLauncher/HMCL/HMCL.h deleted file mode 100644 index c4aafa38ed5f51ce4664cbebc89f024a8e8eb731..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 80 zcmW-YK?;B%00ieO_y^Iuf0C36Dx>iG*6LxGWtjbX;N~H*a;hDbi-m&4%mnsH4jNh9 Q;pG=znN4fBkxg_wevTFn3;+NC diff --git a/HMCLauncher/HMCL/HMCL.vcxproj b/HMCLauncher/HMCL/HMCL.vcxproj index 9b6e9113d..03e8ac938 100644 --- a/HMCLauncher/HMCL/HMCL.vcxproj +++ b/HMCLauncher/HMCL/HMCL.vcxproj @@ -23,7 +23,7 @@ {672B1019-E741-4C0D-A986-627E2ACE157B} Win32Proj HMCL - 8.1 + 7.0 @@ -152,19 +152,25 @@ - + + + + - + + + Create Create Create Create + diff --git a/HMCLauncher/HMCL/HMCL.vcxproj.filters b/HMCLauncher/HMCL/HMCL.vcxproj.filters index 04ebb26dd..e4fb0ec74 100644 --- a/HMCLauncher/HMCL/HMCL.vcxproj.filters +++ b/HMCLauncher/HMCL/HMCL.vcxproj.filters @@ -24,7 +24,16 @@ 头文件 - + + 头文件 + + + 头文件 + + + 头文件 + + 头文件 @@ -32,7 +41,16 @@ 源文件 - + + 源文件 + + + 源文件 + + + 源文件 + + 源文件 diff --git a/HMCLauncher/HMCL/Version.cpp b/HMCLauncher/HMCL/Version.cpp new file mode 100644 index 000000000..a8b0279a6 --- /dev/null +++ b/HMCLauncher/HMCL/Version.cpp @@ -0,0 +1,15 @@ +#include "stdafx.h" +#include "Version.h" + +Version::Version(const std::wstring & rawString) +{ + int idx = 0; + ver[0] = ver[1] = ver[2] = ver[3] = 0; + for (auto &i : rawString) + { + if (idx >= 4) break; + if (i == '.') ++idx; + else if (i == '_') ++idx; + else if (isdigit(i)) ver[idx] = ver[idx] * 10 + (i - L'0'); + } +} diff --git a/HMCLauncher/HMCL/Version.h b/HMCLauncher/HMCL/Version.h new file mode 100644 index 000000000..2e0784d16 --- /dev/null +++ b/HMCLauncher/HMCL/Version.h @@ -0,0 +1,20 @@ +#pragma once + +#include + +class Version +{ +public: + int ver[4]; + + Version(const std::wstring &rawString); + + bool operator<(const Version &other) const + { + for (int i = 0; i < 4; ++i) + if (ver[i] != other.ver[i]) + return ver[i] < other.ver[i]; + return false; + } +}; + diff --git a/HMCLauncher/HMCL/java.cpp b/HMCLauncher/HMCL/java.cpp new file mode 100644 index 000000000..93e806e66 --- /dev/null +++ b/HMCLauncher/HMCL/java.cpp @@ -0,0 +1,88 @@ +#include "stdafx.h" +#include "java.h" +#include "os.h" + +const Version JAVA_8(L"1.8"), JAVA_11(L"11"); + +const LPCWSTR JDK_OLD = L"SOFTWARE\\JavaSoft\\Java Development Kit"; +const LPCWSTR JRE_OLD = L"SOFTWARE\\JavaSoft\\Java Runtime Environment"; +const LPCWSTR JDK_NEW = L"SOFTWARE\\JavaSoft\\JDK"; +const LPCWSTR JRE_NEW = L"SOFTWARE\\JavaSoft\\JRE"; + +bool oldJavaFound = false, newJavaFound = false; + +bool FindJavaByRegistryKey(HKEY rootKey, LPCWSTR subKey, std::wstring & path) +{ + WCHAR javaVer[MAX_KEY_LENGTH]; // buffer for subkey name, special for JavaVersion + DWORD cbName; // size of name string + DWORD cSubKeys = 0; // number of subkeys + DWORD cbMaxSubKey; // longest subkey size + DWORD cValues; // number of values for key + DWORD cchMaxValue; // longest value name + DWORD cbMaxValueData; // longest value data + LSTATUS result; + + HKEY hKey; + if (ERROR_SUCCESS != (result = RegOpenKeyEx(rootKey, subKey, 0, KEY_WOW64_64KEY | KEY_READ, &hKey))) + return false; + + RegQueryInfoKey( + hKey, // key handle + NULL, // buffer for class name + NULL, // size of class string + NULL, // reserved + &cSubKeys, // number of subkeys + &cbMaxSubKey, // longest subkey size + NULL, // longest class string + &cValues, // number of values for this key + &cchMaxValue, // longest value name + &cbMaxValueData, // longest value data + NULL, // security descriptor + NULL); // last write time + + if (!cSubKeys) + return false; + + bool flag = false; + for (DWORD i = 0; i < cSubKeys; ++i) + { + cbName = MAX_KEY_LENGTH; + if (ERROR_SUCCESS != (result = RegEnumKeyEx(hKey, i, javaVer, &cbName, NULL, NULL, NULL, NULL))) + continue; + + HKEY javaKey; + if (ERROR_SUCCESS != RegOpenKeyEx(hKey, javaVer, 0, KEY_READ, &javaKey)) + continue; + + if (ERROR_SUCCESS == MyRegQueryValue(javaKey, L"JavaHome", REG_SZ, path)) + { + if (Version(javaVer) < JAVA_8) + oldJavaFound = true; + else if (!(Version(javaVer) < JAVA_11)) + newJavaFound = true; + else + flag = true; + } + + if (flag) + break; + } + + RegCloseKey(hKey); + + return flag; +} + +bool FindJavaInRegistry(std::wstring & path) +{ + return FindJavaByRegistryKey(HKEY_LOCAL_MACHINE, JDK_OLD, path) || + FindJavaByRegistryKey(HKEY_LOCAL_MACHINE, JRE_OLD, path) || + FindJavaByRegistryKey(HKEY_LOCAL_MACHINE, JDK_NEW, path) || + FindJavaByRegistryKey(HKEY_LOCAL_MACHINE, JRE_NEW, path); +} + +bool FindJava(std::wstring & path) +{ + return FindJavaInRegistry(path) || + ERROR_SUCCESS == MyGetEnvironmentVariable(L"JAVA_HOME", path); +} diff --git a/HMCLauncher/HMCL/java.h b/HMCLauncher/HMCL/java.h new file mode 100644 index 000000000..86e96ecd3 --- /dev/null +++ b/HMCLauncher/HMCL/java.h @@ -0,0 +1,10 @@ +#pragma once +#include +#include +#include "Version.h" + +// Find Java installation in system registry +bool FindJavaInRegistry(std::wstring &path); + +// Find Java Installation in registry and environment variable +bool FindJava(std::wstring &path); diff --git a/HMCLauncher/HMCL/main.cpp b/HMCLauncher/HMCL/main.cpp new file mode 100644 index 000000000..61fd58e7a --- /dev/null +++ b/HMCLauncher/HMCL/main.cpp @@ -0,0 +1,79 @@ +#include "stdafx.h" +#include "main.h" +#include "os.h" +#include "java.h" + +using namespace std; + + +void LaunchJVM(const wstring &javaPath, const wstring &jarPath) +{ + if (MyCreateProcess(L"\"" + javaPath + L"\" -XX:MinHeapFreeRatio=5 -XX:MaxHeapFreeRatio=15 -jar \"" + jarPath + L"\"")) + exit(EXIT_SUCCESS); +} + +int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) +{ + wstring path, exeName; + + // Since Jar file is appended to this executable, we should first get the location of JAR file. + if (ERROR_SUCCESS != MyGetModuleFileName(NULL, exeName)) + return 1; + + + // First try the Java packaged together. + bool is64Bit = false; + GetArch(is64Bit); // if failed to determine architecture of operating system, consider 32-bit. + + if (is64Bit) + { + LaunchJVM(L"jre-x64\\bin\\javaw.exe", exeName); + } + else + { + LaunchJVM(L"jre-x86\\bin\\javaw.exe", exeName); + } + + if (FindJava(path)) + LaunchJVM(path + L"\\bin\\javaw.exe", exeName); + + // Try java in PATH + LaunchJVM(L"javaw", exeName); + + // Or we try to search Java in C:\Program Files. + { + WIN32_FIND_DATA data; + HANDLE hFind = FindFirstFile(L"C:\\Program Files\\Java\\*", &data); // Search all subdirectory + + if (hFind != INVALID_HANDLE_VALUE) { + do { + wstring javaw = wstring(L"C:\\Program Files\\Java\\") + data.cFileName + wstring(L"\\bin\\javaw.exe"); + if (FindFirstFileExists(javaw.c_str(), 0)) { + LaunchJVM(javaw, exeName); + } + } while (FindNextFile(hFind, &data)); + FindClose(hFind); + } + } + + // Consider C:\Program Files (x86)\Java + { + WIN32_FIND_DATA data; + HANDLE hFind = FindFirstFile(L"C:\\Program Files (x86)\\Java\\*", &data); // Search all subdirectory + + if (hFind != INVALID_HANDLE_VALUE) { + do { + wstring javaw = wstring(L"C:\\Program Files (x86)\\Java\\") + data.cFileName + L"\\bin\\javaw.exe"; + if (FindFirstFileExists(javaw.c_str(), 0)) { + LaunchJVM(javaw, exeName); + } + } while (FindNextFile(hFind, &data)); + FindClose(hFind); + } + } + + MessageBox(NULL, L"Java installation cannot be found in this computer, please download it from https://java.com \n" + L"未能在这台电脑上找到Java 8~Java 10,请从 https://java.com 下载安装Java", L"Error", MB_ICONERROR | MB_OK); + ShellExecute(0, 0, L"https://java.com/", 0, 0, SW_SHOW); + return 1; +} diff --git a/HMCLauncher/HMCL/main.h b/HMCLauncher/HMCL/main.h new file mode 100644 index 000000000..e60f2eb7e --- /dev/null +++ b/HMCLauncher/HMCL/main.h @@ -0,0 +1,3 @@ +#pragma once + +#include "resource.h" diff --git a/HMCLauncher/HMCL/os.cpp b/HMCLauncher/HMCL/os.cpp new file mode 100644 index 000000000..820e53819 --- /dev/null +++ b/HMCLauncher/HMCL/os.cpp @@ -0,0 +1,108 @@ +#include "stdafx.h" +#include "os.h" + +using namespace std; + +LSTATUS MyRegQueryValue(HKEY hKey, LPCWSTR subKey, DWORD dwType, wstring &out) +{ + DWORD dwSize = 0; + LSTATUS ret = RegQueryValueEx(hKey, subKey, 0, &dwType, NULL, &dwSize); + if (ret != ERROR_SUCCESS) return ret; + WCHAR *buffer = new WCHAR[dwSize]; + ret = RegQueryValueEx(hKey, subKey, 0, &dwType, (LPBYTE)buffer, &dwSize); + if (ret != ERROR_SUCCESS) return ret; + out = buffer; + delete[] buffer; + return ERROR_SUCCESS; +} + +LSTATUS MyGetModuleFileName(HMODULE hModule, std::wstring &out) +{ + DWORD res, size = MAX_PATH; + out = wstring(); + out.resize(size); + while ((res = GetModuleFileName(hModule, &out[0], size)) == size) + { + out.resize(size += MAX_PATH); + } + if (res == 0) + return GetLastError(); + else + { + out.resize(size - MAX_PATH + res); + return ERROR_SUCCESS; + } +} + +LSTATUS MyGetEnvironmentVariable(LPCWSTR name, std::wstring & out) +{ + DWORD res, size = MAX_PATH; + out = wstring(); + out.resize(size); + while ((res = GetEnvironmentVariable(name, &out[0], size)) == size) + { + out.resize(size += MAX_PATH); + } + if (res == 0) + return GetLastError(); + else + { + out.resize(size - MAX_PATH + res); + return ERROR_SUCCESS; + } +} + +bool MyCreateProcess(const std::wstring &command) +{ + wstring writable_command = command; + STARTUPINFO si; + PROCESS_INFORMATION pi; + si.cb = sizeof(si); + ZeroMemory(&si, sizeof(si)); + ZeroMemory(&pi, sizeof(pi)); + + return (CreateProcess(NULL, &writable_command[0], NULL, NULL, false, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi)); +} + +bool FindFirstFileExists(LPCWSTR lpPath, DWORD dwFilter) +{ + WIN32_FIND_DATA fd; + HANDLE hFind = FindFirstFile(lpPath, &fd); + bool bFilter = (false == dwFilter) ? true : fd.dwFileAttributes & dwFilter; + bool ret = ((hFind != INVALID_HANDLE_VALUE) && bFilter) ? true : false; + FindClose(hFind); + return ret; +} + +bool GetArch(bool & is64Bit) +{ +#if _WIN64 + isWindows64bit = true; + return true; +#elif _WIN32 + typedef BOOL(WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL); + + BOOL isWow64 = FALSE; + + // IsWow64Process is not available on all supported versions of Windows. + // Use GetModuleHandle to get a handle to the DLL that contains the function + // and GetProcAddress to get a pointer to the function if available. + + LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS) + GetProcAddress(GetModuleHandle(TEXT("kernel32")), "IsWow64Process"); + + if (fnIsWow64Process) + { + if (!fnIsWow64Process(GetCurrentProcess(), &isWow64)) + return false; + + is64Bit = isWow64; + return true; + } + else // IsWow64Process is not supported, fail to detect. + return false; + +#else +#error _WIN64 and _WIN32 are both undefined. +#endif +} diff --git a/HMCLauncher/HMCL/os.h b/HMCLauncher/HMCL/os.h new file mode 100644 index 000000000..406e661b4 --- /dev/null +++ b/HMCLauncher/HMCL/os.h @@ -0,0 +1,23 @@ +#pragma once +#include +#include + +const int MAX_KEY_LENGTH = 255; +const int MAX_VALUE_NAME = 16383; + +// Query registry value of class root hKey, key path subKey, stores result in parameter out. +LSTATUS MyRegQueryValue(HKEY hKey, LPCWSTR subKey, DWORD dwType, std::wstring &out); + +// Get module file name, stores result in parameter out. +LSTATUS MyGetModuleFileName(HMODULE hModule, std::wstring &out); + +// Get environment variable by name, C++ style, stores the value in parameter out. +LSTATUS MyGetEnvironmentVariable(LPCWSTR name, std::wstring &out); + +// Create process by invoking CreateProcess, only pass command. +bool MyCreateProcess(const std::wstring &command); + +// Check if file lpPath exists. +bool FindFirstFileExists(LPCWSTR lpPath, DWORD dwFilter); + +bool GetArch(bool &is64Bit); \ No newline at end of file