mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-09-11 12:56:53 -04:00
引导用户下载 Java (#1659)
* Direct users to download Java * Read JVM options from environment variables
This commit is contained in:
parent
23cc568bac
commit
c6a5624708
Binary file not shown.
@ -78,6 +78,7 @@ bool FindJavaInRegistry(std::wstring& path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool FindJava(std::wstring& path) {
|
bool FindJava(std::wstring& path) {
|
||||||
return FindJavaInRegistry(path) ||
|
return ERROR_SUCCESS == MyGetEnvironmentVariable(L"HMCL_JAVA_HOME", path) ||
|
||||||
ERROR_SUCCESS == MyGetEnvironmentVariable(L"JAVA_HOME", path);
|
ERROR_SUCCESS == MyGetEnvironmentVariable(L"JAVA_HOME", path) ||
|
||||||
|
FindJavaInRegistry(path);
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define ERROR_PROMPT L"Java installation cannot be found in this computer,\n"\
|
#define ERROR_TITLE L"Java not found"
|
||||||
L"please download it from %s.\n"\
|
|
||||||
L"Click 'OK' to go to the download page."
|
|
||||||
|
|
||||||
#define ERROR_PROMPT_ZH L"未能在这台电脑上找到 Java,请从 %s 下载安装 Java。\n"\
|
#define ERROR_TITLE_ZH L"未找到 Java"
|
||||||
L"点击“确定”立即前往下载页面。"
|
|
||||||
|
#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。"
|
||||||
|
@ -16,26 +16,23 @@ LPCWSTR VENDOR_DIRS[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void RawLaunchJVM(const std::wstring &javaPath, const std::wstring &workdir,
|
void RawLaunchJVM(const std::wstring &javaPath, const std::wstring &workdir,
|
||||||
const std::wstring &jarPath) {
|
const std::wstring &jarPath, const std::wstring &jvmOptions) {
|
||||||
if (MyCreateProcess(
|
if (MyCreateProcess(L"\"" + javaPath + L"\" " + jvmOptions + L" -jar \"" + jarPath + L"\"", workdir))
|
||||||
L"\"" + javaPath +
|
|
||||||
L"\" -XX:MinHeapFreeRatio=5 -XX:MaxHeapFreeRatio=15 -jar \"" +
|
|
||||||
jarPath + L"\"",
|
|
||||||
workdir))
|
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LaunchJVM(const std::wstring &javaPath, const std::wstring &workdir,
|
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"");
|
Version javaVersion(L"");
|
||||||
if (!MyGetFileVersionInfo(javaPath, javaVersion)) return;
|
if (!MyGetFileVersionInfo(javaPath, javaVersion)) return;
|
||||||
|
|
||||||
if (J8 <= javaVersion) {
|
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"*";
|
std::wstring pattern = baseDir + L"*";
|
||||||
|
|
||||||
WIN32_FIND_DATA data;
|
WIN32_FIND_DATA data;
|
||||||
@ -45,7 +42,7 @@ void FindJavaInDirAndLaunchJVM(const std::wstring &baseDir, const std::wstring &
|
|||||||
do {
|
do {
|
||||||
std::wstring javaw = baseDir + data.cFileName + std::wstring(L"\\bin\\javaw.exe");
|
std::wstring javaw = baseDir + data.cFileName + std::wstring(L"\\bin\\javaw.exe");
|
||||||
if (FindFirstFileExists(javaw.c_str(), 0)) {
|
if (FindFirstFileExists(javaw.c_str(), 0)) {
|
||||||
LaunchJVM(javaw, workdir, jarPath);
|
LaunchJVM(javaw, workdir, jarPath, jvmOptions);
|
||||||
}
|
}
|
||||||
} while (FindNextFile(hFind, &data));
|
} while (FindNextFile(hFind, &data));
|
||||||
FindClose(hFind);
|
FindClose(hFind);
|
||||||
@ -54,7 +51,7 @@ void FindJavaInDirAndLaunchJVM(const std::wstring &baseDir, const std::wstring &
|
|||||||
|
|
||||||
int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
||||||
LPWSTR lpCmdLine, int nCmdShow) {
|
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
|
// Since Jar file is appended to this executable, we should first get the
|
||||||
// location of JAR file.
|
// location of JAR file.
|
||||||
@ -67,6 +64,10 @@ int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
|||||||
exeName = exeName.substr(last_slash + 1);
|
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
|
bool useChinese = GetUserDefaultUILanguage() == 2052; // zh-CN
|
||||||
|
|
||||||
OSVERSIONINFOEX osvi;
|
OSVERSIONINFOEX osvi;
|
||||||
@ -94,14 +95,14 @@ int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
|||||||
bool isARM64 = (systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM64);
|
bool isARM64 = (systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM64);
|
||||||
|
|
||||||
if (isARM64) {
|
if (isARM64) {
|
||||||
RawLaunchJVM(L"jre-arm64\\bin\\javaw.exe", workdir, exeName);
|
RawLaunchJVM(L"jre-arm64\\bin\\javaw.exe", workdir, exeName, jvmOptions);
|
||||||
}
|
}
|
||||||
if (isX64) {
|
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;
|
std::wstring programFiles;
|
||||||
|
|
||||||
@ -112,7 +113,7 @@ int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
|||||||
MyPathAppend(dir, vendorDir);
|
MyPathAppend(dir, vendorDir);
|
||||||
MyPathAddBackslash(dir);
|
MyPathAddBackslash(dir);
|
||||||
|
|
||||||
FindJavaInDirAndLaunchJVM(dir, workdir, exeName);
|
FindJavaInDirAndLaunchJVM(dir, workdir, exeName, jvmOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Consider C:\Program Files (x86)
|
// Consider C:\Program Files (x86)
|
||||||
@ -122,11 +123,11 @@ int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
|||||||
MyPathAppend(dir, vendorDir);
|
MyPathAppend(dir, vendorDir);
|
||||||
MyPathAddBackslash(dir);
|
MyPathAddBackslash(dir);
|
||||||
|
|
||||||
FindJavaInDirAndLaunchJVM(dir, workdir, exeName);
|
FindJavaInDirAndLaunchJVM(dir, workdir, exeName, jvmOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try java in PATH
|
// Try java in PATH
|
||||||
RawLaunchJVM(L"javaw", workdir, exeName);
|
RawLaunchJVM(L"javaw", workdir, exeName, jvmOptions);
|
||||||
|
|
||||||
std::wstring hmclJavaDir;
|
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))) {
|
if (SUCCEEDED(MySHGetFolderPath(CSIDL_APPDATA, buffer)) || SUCCEEDED(MySHGetFolderPath(CSIDL_PROFILE, buffer))) {
|
||||||
MyPathAppend(buffer, L".hmcl");
|
MyPathAppend(buffer, L".hmcl");
|
||||||
MyPathAppend(buffer, L"java");
|
MyPathAppend(buffer, L"java");
|
||||||
if (isX64) {
|
if (isARM64) {
|
||||||
|
MyPathAppend(buffer, L"windows-arm64");
|
||||||
|
} else if (isX64) {
|
||||||
MyPathAppend(buffer, L"windows-x86_64");
|
MyPathAppend(buffer, L"windows-x86_64");
|
||||||
} else {
|
} else {
|
||||||
MyPathAppend(buffer, L"windows-x86");
|
MyPathAppend(buffer, L"windows-x86");
|
||||||
@ -145,67 +148,25 @@ int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!hmclJavaDir.empty()) {
|
if (!hmclJavaDir.empty()) {
|
||||||
FindJavaInDirAndLaunchJVM(hmclJavaDir, workdir, exeName);
|
FindJavaInDirAndLaunchJVM(hmclJavaDir, workdir, exeName, jvmOptions);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
error:
|
error:
|
||||||
LPCWSTR downloadLink = isWin7OrLater && (isX64 || isARM64) ? L"https://www.microsoft.com/openjdk" : L"https://java.com";
|
LPCWSTR downloadLink;
|
||||||
|
|
||||||
WCHAR errorPrompt[180];
|
if (isWin7OrLater) {
|
||||||
{
|
if (isARM64) {
|
||||||
LPCWSTR errorPromptFormat = useChinese ? ERROR_PROMPT_ZH : ERROR_PROMPT;
|
downloadLink = L"https://aka.ms/download-jdk/microsoft-jdk-17-windows-aarch64.msi";
|
||||||
wsprintf(errorPrompt, errorPromptFormat, downloadLink);
|
} 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);
|
ShellExecute(0, 0, downloadLink, 0, 0, SW_SHOW);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user