Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

重构 HMCLauncher #3007

Open
wants to merge 22 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
51b4108
Feature: Support scanning Java from HMCL_JAVA_HOME, JAVA_HOME, PATH a…
burningtnt Apr 26, 2024
7595604
Fix: I forget to remove /* and */. Refactor java.h.
burningtnt Apr 26, 2024
bd04465
Remove useless function.
burningtnt Apr 26, 2024
24b9aae
尝试性的为HMCLauncher添加cmake及gcc支持
YSXX1013 Apr 27, 2024
b63bde4
完善cmake及gcc支持
YSXX1013 Apr 27, 2024
853876c
尝试支持Github Actions
YSXX1013 Apr 27, 2024
185c674
尝试支持Github Actions-2
YSXX1013 Apr 27, 2024
88870c2
尝试支持Github Actions-3
YSXX1013 Apr 27, 2024
e0e30ff
尝试支持Github Actions-4
YSXX1013 Apr 27, 2024
abadd2a
尝试支持Github Actions-5
YSXX1013 Apr 27, 2024
eb95ce4
Merge branch 'HMCL-dev:main' into main
YSXX1013 May 8, 2024
5fdd6f2
Merge branch 'HMCL-dev:main' into main
YSXX1013 May 16, 2024
c8fa232
Merge branch 'HMCL-dev:main' into main
YSXX1013 Jun 3, 2024
89d2bf0
Merge branch 'refs/heads/YSXX1013/main' into feature/refactor-hmclaun…
burningtnt Jun 15, 2024
17d684e
Rrovide a built HMCLauncher.exe
burningtnt Jun 15, 2024
0df1f1d
Feature: Using java from .hmcl/runtime/bin/javaw.exe
burningtnt Jul 5, 2024
46f1984
Feature: Download JRE and detect broken JVM.
burningtnt Jul 22, 2024
8b1c3f5
Fix: msbuild compiling.
burningtnt Jul 22, 2024
9e722ce
Update install.cpp
burningtnt Jul 24, 2024
b7c7ceb
Remove useless functions and Recompile HMCLauncher.
burningtnt Jul 28, 2024
ce87c91
Merge remote-tracking branch 'refs/remotes/official/main' into featur…
burningtnt Nov 1, 2024
cee22d6
Recompile HMCLauncher
burningtnt Nov 1, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified HMCL/src/main/resources/assets/HMCLauncher.exe
Binary file not shown.
3 changes: 2 additions & 1 deletion HMCLauncher/HMCL/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ if(ENABLE_MINGW_STATIC_LINK_LIBSTDCXX AND MINGW)
add_link_options(-static)
endif()
set(CMAKE_WIN32_EXECUTABLE ON)
add_executable(HMCLauncher WIN32 HMCL.rc java.cpp main.cpp os.cpp stdafx.cpp Version.cpp)
add_executable(HMCLauncher WIN32 HMCL.rc java.cpp main.cpp os.cpp install.cpp stdafx.cpp Version.cpp)
target_link_libraries(HMCLauncher Version)
target_link_libraries(HMCLauncher wininet)
install(TARGETS HMCLauncher)
2 changes: 2 additions & 0 deletions HMCLauncher/HMCL/HMCL.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="java.h" />
<ClInclude Include="install.h" />
<ClInclude Include="lang.h" />
<ClInclude Include="main.h" />
<ClInclude Include="os.h" />
Expand All @@ -170,6 +171,7 @@
</ItemGroup>
<ItemGroup>
<ClCompile Include="java.cpp" />
<ClCompile Include="install.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="os.cpp" />
<ClCompile Include="stdafx.cpp">
Expand Down
6 changes: 6 additions & 0 deletions HMCLauncher/HMCL/HMCL.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@
<ClInclude Include="java.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="install.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="os.h">
<Filter>头文件</Filter>
</ClInclude>
Expand All @@ -53,6 +56,9 @@
<ClCompile Include="java.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="install.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="os.cpp">
<Filter>源文件</Filter>
</ClCompile>
Expand Down
189 changes: 189 additions & 0 deletions HMCLauncher/HMCL/install.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
#include "install.h"

int InstallHMCLJRE(const std::wstring &home, const std::wstring &domain,
const std::wstring &file) {
WIN32_FIND_DATA ffd;
std::wstring runtime, jreDownloadedFile, jreDownloadedDirectory, command;
STARTUPINFO si;
PROCESS_INFORMATION pi;

runtime = home + L"runtime";
jreDownloadedFile = home + L".hmclauncher-jre-";
jreDownloadedFile.append(std::to_wstring(rand()));
jreDownloadedDirectory = jreDownloadedFile + L"";
jreDownloadedFile.append(L".zip");

HANDLE hFind = INVALID_HANDLE_VALUE, hCleanable[8];
for (int i = 0;i < 8;i ++) {
hCleanable[i] = INVALID_HANDLE_VALUE;
}

int err = 0;

err = DownloadHMCLJRE(jreDownloadedFile, domain, file);
if (err != 0) {
goto cleanup;
}

if (!CreateDirectory(jreDownloadedDirectory.c_str(), NULL)) {
err = GetLastError();
goto cleanup;
}

command = L"tar.exe -xf \"" + jreDownloadedFile + L"\"";
si.cb = sizeof(si);
ZeroMemory(&si, sizeof(si));
ZeroMemory(&pi, sizeof(pi));

if (!CreateProcess(NULL, &command[0], NULL, NULL, false,
NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW, NULL, jreDownloadedDirectory.c_str(), &si,
&pi)) {
err = GetLastError();
goto cleanup;
}
hCleanable[0] = si.hStdInput;
hCleanable[1] = si.hStdOutput;
hCleanable[2] = si.hStdError;
hCleanable[3] = pi.hProcess;
hCleanable[4] = pi.hThread;

while (true) {
DWORD exitCode;
if (!GetExitCodeProcess(pi.hProcess, &exitCode)) {
err = GetLastError();
goto cleanup;
}

if (exitCode != STILL_ACTIVE) {
if (exitCode != 0) {
err = exitCode;
goto cleanup;
}
break;
}
}

hFind = FindFirstFile((jreDownloadedDirectory + L"\\*").c_str(), &ffd);
if (hFind == INVALID_HANDLE_VALUE) {
err = GetLastError();
goto cleanup;
}

{
std::wstring targetFile = std::wstring();
do {
std::wstring fileName = std::wstring(ffd.cFileName);
if (fileName.size() <= 2 && fileName[0] == L'.') {
continue;
}
if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
if (targetFile.size() != 0) {
err = HMCL_ERR_INVALID_JRE_PACK;
goto cleanup;
}

targetFile.append(fileName);
}
} while (FindNextFile(hFind, &ffd) != 0);
err = GetLastError();
if (err != ERROR_NO_MORE_FILES) {
goto cleanup;
}
err = 0;

if (targetFile.size() == 0) {
err = HMCL_ERR_INVALID_JRE_PACK;
goto cleanup;
}

if (!MoveFile((jreDownloadedDirectory + L'\\' + targetFile).c_str(), runtime.c_str())) {
err = GetLastError();
goto cleanup;
}
}

cleanup:
if (hFind != INVALID_HANDLE_VALUE) {
CloseHandle(hFind);
}
for (int i = 0;i < 8;i ++) {
HANDLE hCH = hCleanable[i];
if (hCH != INVALID_HANDLE_VALUE) {
CloseHandle(hCH);
}
}
RemoveDirectory(jreDownloadedDirectory.c_str());
DeleteFile(jreDownloadedFile.c_str());
return err;
}

int DownloadHMCLJRE(std::wstring &jreDownloadedFile, const std::wstring &domain,
const std::wstring &file) {
int err = 0;
HINTERNET hInternet = NULL, hConnection = NULL, hRequest = NULL;
byte buffer[4096];
HANDLE fd = NULL;

{
hInternet = InternetOpen(L"HMCLauncher", INTERNET_OPEN_TYPE_PRECONFIG, NULL,
NULL, 0);
if (hInternet == NULL) {
err = GetLastError();
goto cleanup;
}
hConnection =
InternetConnect(hInternet, domain.c_str(), INTERNET_DEFAULT_HTTPS_PORT,
NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
if (hConnection == NULL) {
err = GetLastError();
goto cleanup;
}

const wchar_t *ACCEPTS[] = {L"application/zip", NULL};
hRequest = HttpOpenRequest(hConnection, L"GET", file.c_str(), NULL, NULL,
ACCEPTS, INTERNET_FLAG_SECURE, 0);
if (hRequest == NULL) {
err = GetLastError();
goto cleanup;
}

if (!HttpSendRequest(hRequest, NULL, 0, NULL, 0)) {
err = GetLastError();
goto cleanup;
}

{
DWORD receivedCount, unused;

fd = CreateFile(jreDownloadedFile.c_str(), GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (fd == INVALID_HANDLE_VALUE) {
err = GetLastError();
goto cleanup;
}

while (InternetReadFile(hRequest, buffer, 4096, &receivedCount) &&
receivedCount) {
if (!WriteFile(fd, buffer, receivedCount, &unused, NULL)) {
err = GetLastError();
goto cleanup;
}
}
}
}

cleanup:
if (hRequest != NULL) {
InternetCloseHandle(hRequest);
}
if (hConnection != NULL) {
InternetCloseHandle(hConnection);
}
if (hInternet != NULL) {
InternetCloseHandle(hInternet);
}
if (fd != NULL) {
CloseHandle(fd);
}
return err;
}
9 changes: 9 additions & 0 deletions HMCLauncher/HMCL/install.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include "stdafx.h"

#define HMCL_ERR_INVALID_JRE_PACK -129

int InstallHMCLJRE(const std::wstring &home, const std::wstring &domain,
const std::wstring &file);

int DownloadHMCLJRE(std::wstring &target, const std::wstring &domain,
const std::wstring &file);
86 changes: 58 additions & 28 deletions HMCLauncher/HMCL/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "os.h"
#include "java.h"
#include "lang.h"
#include "install.h"
#include <windows.h>

Version J8(TEXT("8"));
Expand All @@ -18,13 +19,29 @@ __attribute__ ((dllexport)) DWORD AmdPowerXpressRequestHighPerformance = 0x00000
}

void LaunchHMCLDirect(const std::wstring &javaPath, const std::wstring &workdir,
const std::wstring &jarPath, const std::wstring &jvmOptions) {
if (MyCreateProcess(L"\"" + javaPath + L"\" " + jvmOptions + L" -jar \"" + jarPath + L"\"", workdir))
const std::wstring &jarPath,
const std::wstring &jvmOptions) {
HANDLE hProcess = MyCreateProcess(L"\"" + javaPath + L"\" " + jvmOptions + L" -jar \"" +
jarPath + L"\"", workdir);
if (hProcess == INVALID_HANDLE_VALUE) {
return;
}

Sleep(5000);
DWORD exitCode;
if (!GetExitCodeProcess(hProcess, &exitCode)) {
GetLastError();
CloseHandle(hProcess);
return;
}
CloseHandle(hProcess);
if (exitCode == STILL_ACTIVE || exitCode == 0) {
exit(EXIT_SUCCESS);
}
}

void LaunchHMCL(const std::wstring &javaPath, const std::wstring &workdir,
const std::wstring &jarPath, const std::wstring &jvmOptions) {
const std::wstring &jarPath, const std::wstring &jvmOptions) {
Version javaVersion(L"");
if (!MyGetFileVersionInfo(javaPath, javaVersion)) return;

Expand All @@ -34,11 +51,13 @@ void LaunchHMCL(const std::wstring &javaPath, const std::wstring &workdir,
}

void OpenHelpPage() {
burningtnt marked this conversation as resolved.
Show resolved Hide resolved
ShellExecute(0, 0, L"https://docs.hmcl.net/help.html", 0, 0, SW_SHOW);
ShellExecute(0, 0, L"https://docs.hmcl.net/help.html", 0, 0, SW_SHOW);
}

int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPWSTR lpCmdLine, int nCmdShow) {
srand(GetTickCount64());

std::wstring exeName, jvmOptions;

// Since Jar file is appended to this executable, we should first get the
Expand All @@ -52,54 +71,65 @@ 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
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

SYSTEM_INFO systemInfo;
GetNativeSystemInfo(&systemInfo);
// TODO: check whether the bundled JRE is valid.

// First, try the Java packaged together.
bool isX64 = (systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64);
bool isARM64 = (systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM64);
bool isX64 =
(systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64);
bool isARM64 =
(systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM64);

if (isARM64) {
LaunchHMCLDirect(L"jre-arm64\\bin\\javaw.exe", workdir, exeName, jvmOptions);
LaunchHMCLDirect(L"jre-arm64\\bin\\java.exe", workdir, exeName,
jvmOptions);
}
if (isX64) {
LaunchHMCLDirect(L"jre-x64\\bin\\javaw.exe", workdir, exeName, jvmOptions);
LaunchHMCLDirect(L"jre-x64\\bin\\java.exe", workdir, exeName, jvmOptions);
}
LaunchHMCLDirect(L"jre-x86\\bin\\javaw.exe", workdir, exeName, jvmOptions);
LaunchHMCLDirect(L"jre-x86\\bin\\java.exe", workdir, exeName, jvmOptions);

// Next, try the Java installed on thi computer.
// Next, try the Java installed on this computer.
std::wstring path;
int status;

ScanJava(systemInfo, path, status);

if (status != JAVA_STATUS_NOT_FOUND) {
MyPathAppend(path, std::wstring(L"bin\\javaw.exe"));
MyPathAppend(path, std::wstring(L"bin\\java.exe"));
LaunchHMCL(path, workdir, exeName, jvmOptions);
}

// Try java in PATH
LaunchHMCLDirect(L"javaw", workdir, exeName, jvmOptions);

LPCWSTR downloadLink;

if (isARM64) {
downloadLink = L"https://docs.hmcl.net/downloads/windows/arm64.html";
} if (isX64) {
downloadLink = L"https://docs.hmcl.net/downloads/windows/x86_64.html";
} else {
downloadLink = L"https://docs.hmcl.net/downloads/windows/x86.html";
LaunchHMCLDirect(L"java", workdir, exeName, jvmOptions);

std::wstring home;
if (SUCCEEDED(MySHGetFolderPath(CSIDL_APPDATA, home)) ||
SUCCEEDED(MySHGetFolderPath(CSIDL_PROFILE, home))) {
MyPathNormalize(home);
MyPathAppend(home, L".hmcl\\");

std::wstring file = L"";
if (isARM64) {
file = L"/java/11.0.24+9/bellsoft-jre11.0.24+9-windows-aarch64-full.zip";
} else if (isX64) {
file = L"/java/11.0.24+9/bellsoft-jre11.0.24+9-windows-i586-full.zip";
} else {
file = L"/java/11.0.24+9/bellsoft-jre11.0.24+9-windows-amd64-full.zip";
Comment on lines +119 to +123
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

或许可以做成能自动获得最新的版本,或者什么别的

硬编在这不太好吧

}
InstallHMCLJRE(home, L"download.bell-sw.com", file);

LaunchHMCLDirect(home + L"runtime\\bin\\java.exe", workdir, exeName, jvmOptions);
}

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;
return 0;
}
2 changes: 1 addition & 1 deletion HMCLauncher/HMCL/main.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#pragma once

#include "resource.h"
#include "resource.h"
Loading
Loading