diff --git a/HMCLauncher/HMCL/HMCL.rc b/HMCLauncher/HMCL/HMCL.rc index 2a43fb4f5..9120cdbaa 100644 Binary files a/HMCLauncher/HMCL/HMCL.rc and b/HMCLauncher/HMCL/HMCL.rc differ diff --git a/HMCLauncher/HMCL/java.cpp b/HMCLauncher/HMCL/java.cpp index d3fddce7a..067c12fb2 100644 --- a/HMCLauncher/HMCL/java.cpp +++ b/HMCLauncher/HMCL/java.cpp @@ -78,6 +78,7 @@ bool FindJavaInRegistry(std::wstring& path) { } bool FindJava(std::wstring& path) { - return FindJavaInRegistry(path) || - ERROR_SUCCESS == MyGetEnvironmentVariable(L"JAVA_HOME", path); + return ERROR_SUCCESS == MyGetEnvironmentVariable(L"HMCL_JAVA_HOME", path) || + ERROR_SUCCESS == MyGetEnvironmentVariable(L"JAVA_HOME", path) || + FindJavaInRegistry(path); } diff --git a/HMCLauncher/HMCL/lang.h b/HMCLauncher/HMCL/lang.h index 8f0722dfa..41c276ac3 100644 --- a/HMCLauncher/HMCL/lang.h +++ b/HMCLauncher/HMCL/lang.h @@ -1,8 +1,12 @@ #pragma once -#define ERROR_PROMPT L"Java installation cannot be found in this computer,\n"\ - L"please download it from %s.\n"\ - L"Click 'OK' to go to the download page." +#define ERROR_TITLE L"Java not found" -#define ERROR_PROMPT_ZH L"未能在这台电脑上找到 Java,请从 %s 下载安装 Java。\n"\ - L"点击“确定”立即前往下载页面。" \ No newline at end of file +#define ERROR_TITLE_ZH L"未找到 Java" + +#define ERROR_PROMPT L"The Java runtime environment is required to run HMCL and Minecraft,\n"\ + L"Click 'OK' to start downloading java.\n"\ + L"Please restart HMCL after installing Java." + +#define ERROR_PROMPT_ZH L"运行 HMCL 以及 Minecraft 需要 Java 运行时环境,点击“确定”开始下载。\n"\ + L"请在安装 Java 完成后重新启动 HMCL。" diff --git a/HMCLauncher/HMCL/main.cpp b/HMCLauncher/HMCL/main.cpp index 1057465a1..ff3e7d53a 100644 --- a/HMCLauncher/HMCL/main.cpp +++ b/HMCLauncher/HMCL/main.cpp @@ -16,26 +16,23 @@ LPCWSTR VENDOR_DIRS[] = { }; void RawLaunchJVM(const std::wstring &javaPath, const std::wstring &workdir, - const std::wstring &jarPath) { - if (MyCreateProcess( - L"\"" + javaPath + - L"\" -XX:MinHeapFreeRatio=5 -XX:MaxHeapFreeRatio=15 -jar \"" + - jarPath + L"\"", - workdir)) + const std::wstring &jarPath, const std::wstring &jvmOptions) { + if (MyCreateProcess(L"\"" + javaPath + L"\" " + jvmOptions + L" -jar \"" + jarPath + L"\"", workdir)) exit(EXIT_SUCCESS); } void LaunchJVM(const std::wstring &javaPath, const std::wstring &workdir, - const std::wstring &jarPath) { + const std::wstring &jarPath, const std::wstring &jvmOptions) { Version javaVersion(L""); if (!MyGetFileVersionInfo(javaPath, javaVersion)) return; if (J8 <= javaVersion) { - RawLaunchJVM(javaPath, workdir, jarPath); + RawLaunchJVM(javaPath, workdir, jarPath, jvmOptions); } } -void FindJavaInDirAndLaunchJVM(const std::wstring &baseDir, const std::wstring &workdir, const std::wstring &jarPath) { +void FindJavaInDirAndLaunchJVM(const std::wstring &baseDir, const std::wstring &workdir, + const std::wstring &jarPath, const std::wstring &jvmOptions) { std::wstring pattern = baseDir + L"*"; WIN32_FIND_DATA data; @@ -45,7 +42,7 @@ void FindJavaInDirAndLaunchJVM(const std::wstring &baseDir, const std::wstring & do { std::wstring javaw = baseDir + data.cFileName + std::wstring(L"\\bin\\javaw.exe"); if (FindFirstFileExists(javaw.c_str(), 0)) { - LaunchJVM(javaw, workdir, jarPath); + LaunchJVM(javaw, workdir, jarPath, jvmOptions); } } while (FindNextFile(hFind, &data)); FindClose(hFind); @@ -54,7 +51,7 @@ void FindJavaInDirAndLaunchJVM(const std::wstring &baseDir, const std::wstring & int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) { - std::wstring path, exeName; + std::wstring path, exeName, jvmOptions; // Since Jar file is appended to this executable, we should first get the // location of JAR file. @@ -67,6 +64,10 @@ int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, exeName = exeName.substr(last_slash + 1); } + if (ERROR_SUCCESS != MyGetEnvironmentVariable(L"HMCL_JAVA_OPTS", jvmOptions)) { + jvmOptions = L"-XX:MinHeapFreeRatio=5 -XX:MaxHeapFreeRatio=15"; // Default Options + } + bool useChinese = GetUserDefaultUILanguage() == 2052; // zh-CN OSVERSIONINFOEX osvi; @@ -94,14 +95,14 @@ int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, bool isARM64 = (systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM64); if (isARM64) { - RawLaunchJVM(L"jre-arm64\\bin\\javaw.exe", workdir, exeName); + RawLaunchJVM(L"jre-arm64\\bin\\javaw.exe", workdir, exeName, jvmOptions); } if (isX64) { - RawLaunchJVM(L"jre-x64\\bin\\javaw.exe", workdir, exeName); + RawLaunchJVM(L"jre-x64\\bin\\javaw.exe", workdir, exeName, jvmOptions); } - RawLaunchJVM(L"jre-x86\\bin\\javaw.exe", workdir, exeName); + RawLaunchJVM(L"jre-x86\\bin\\javaw.exe", workdir, exeName, jvmOptions); - if (FindJava(path)) LaunchJVM(path + L"\\bin\\javaw.exe", workdir, exeName); + if (FindJava(path)) LaunchJVM(path + L"\\bin\\javaw.exe", workdir, exeName, jvmOptions); std::wstring programFiles; @@ -112,7 +113,7 @@ int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, MyPathAppend(dir, vendorDir); MyPathAddBackslash(dir); - FindJavaInDirAndLaunchJVM(dir, workdir, exeName); + FindJavaInDirAndLaunchJVM(dir, workdir, exeName, jvmOptions); } // Consider C:\Program Files (x86) @@ -122,11 +123,11 @@ int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, MyPathAppend(dir, vendorDir); MyPathAddBackslash(dir); - FindJavaInDirAndLaunchJVM(dir, workdir, exeName); + FindJavaInDirAndLaunchJVM(dir, workdir, exeName, jvmOptions); } // Try java in PATH - RawLaunchJVM(L"javaw", workdir, exeName); + RawLaunchJVM(L"javaw", workdir, exeName, jvmOptions); std::wstring hmclJavaDir; { @@ -134,7 +135,9 @@ int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, if (SUCCEEDED(MySHGetFolderPath(CSIDL_APPDATA, buffer)) || SUCCEEDED(MySHGetFolderPath(CSIDL_PROFILE, buffer))) { MyPathAppend(buffer, L".hmcl"); MyPathAppend(buffer, L"java"); - if (isX64) { + if (isARM64) { + MyPathAppend(buffer, L"windows-arm64"); + } else if (isX64) { MyPathAppend(buffer, L"windows-x86_64"); } else { MyPathAppend(buffer, L"windows-x86"); @@ -145,67 +148,25 @@ int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, } if (!hmclJavaDir.empty()) { - FindJavaInDirAndLaunchJVM(hmclJavaDir, workdir, exeName); - if (isWin7OrLater) { - HRSRC scriptFileResource = FindResource(NULL, MAKEINTRESOURCE(ID_SCRIPT_DOWNLOAD_JAVA), RT_RCDATA); - if (!scriptFileResource) goto error; - - HGLOBAL scriptHandle = LoadResource(NULL, scriptFileResource); - DWORD dataSize = SizeofResource(NULL, scriptFileResource); - void *data = LockResource(scriptHandle); - - std::wstring tempScriptPath; - if (ERROR_SUCCESS != MyGetTempFile(L"hmcl-download-java-", L"ps1", tempScriptPath)) goto error; - - HANDLE hFile; - DWORD dwBytesWritten = 0; - BOOL bErrorFlag = FALSE; - - hFile = CreateFile(tempScriptPath.c_str(), GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); - if (hFile == INVALID_HANDLE_VALUE) goto error; - - bErrorFlag = WriteFile(hFile, data, dataSize, &dwBytesWritten, NULL); - if (FALSE == bErrorFlag || dwBytesWritten != dataSize) goto error; - - CloseHandle(hFile); - - std::wstring commandLineBuffer; - - commandLineBuffer += L"powershell.exe -WindowStyle Hidden -ExecutionPolicy Bypass -File "; - MyAppendPathToCommandLine(commandLineBuffer, tempScriptPath); - commandLineBuffer += L" -JavaDir "; - MyAppendPathToCommandLine(commandLineBuffer, hmclJavaDir); - commandLineBuffer += L" -Arch "; - if (isX64) { - commandLineBuffer += L"x86-64"; - } else { - commandLineBuffer += L"x86"; - } - - STARTUPINFO si; - PROCESS_INFORMATION pi; - si.cb = sizeof(si); - ZeroMemory(&si, sizeof(si)); - ZeroMemory(&pi, sizeof(pi)); - if (!CreateProcess(NULL, &commandLineBuffer[0], NULL, NULL, false, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi)) goto error; - WaitForSingleObject(pi.hProcess, INFINITE); - DeleteFile(tempScriptPath.c_str()); - - // Try starting again after installing Java - FindJavaInDirAndLaunchJVM(hmclJavaDir, workdir, exeName); - } + FindJavaInDirAndLaunchJVM(hmclJavaDir, workdir, exeName, jvmOptions); } error: - LPCWSTR downloadLink = isWin7OrLater && (isX64 || isARM64) ? L"https://www.microsoft.com/openjdk" : L"https://java.com"; + LPCWSTR downloadLink; - WCHAR errorPrompt[180]; - { - LPCWSTR errorPromptFormat = useChinese ? ERROR_PROMPT_ZH : ERROR_PROMPT; - wsprintf(errorPrompt, errorPromptFormat, downloadLink); + if (isWin7OrLater) { + if (isARM64) { + downloadLink = L"https://aka.ms/download-jdk/microsoft-jdk-17-windows-aarch64.msi"; + } if (isX64) { + downloadLink = L"https://aka.ms/download-jdk/microsoft-jdk-17-windows-x64.msi"; + } else { + downloadLink = L"https://download.bell-sw.com/java/17.0.4.1+1/bellsoft-jre17.0.4.1+1-windows-i586-full.msi"; + } + } else { + downloadLink = L"https://www.java.com"; } - if (IDOK == MessageBox(NULL, errorPrompt, L"Error", MB_ICONERROR | MB_OKCANCEL)) { + if (IDOK == MessageBox(NULL, useChinese ? ERROR_PROMPT_ZH : ERROR_PROMPT, useChinese ? ERROR_TITLE_ZH : ERROR_TITLE, MB_ICONWARNING | MB_OKCANCEL)) { ShellExecute(0, 0, downloadLink, 0, 0, SW_SHOW); } return 1;