修复 HMCLauncher 无法正常识别 Windows on Arm 平台的问题 (#3425)

* update

* update

* update
This commit is contained in:
Glavo 2024-11-05 00:20:42 +08:00 committed by GitHub
parent 406f36584d
commit c6658771ca
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 53 additions and 241 deletions

View File

@ -1,7 +1,8 @@
cmake_minimum_required(VERSION 3.25) cmake_minimum_required(VERSION 3.25)
project(HMCLauncher) project(HMCLauncher)
if(MSVC) if(MSVC)
add_compile_options(/utf-8 /D_UNICODE /W4) add_definitions(-DUNICODE -D_UNICODE)
add_compile_options(/utf-8 /W4)
add_link_options(/ENTRY:wWinMainCRTStartup) add_link_options(/ENTRY:wWinMainCRTStartup)
else() else()
add_compile_options(-municode -Wall -Wextra -Wpedantic) add_compile_options(-municode -Wall -Wextra -Wpedantic)

View File

@ -82,8 +82,8 @@ END
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 3,4,0,0 FILEVERSION 3,5,0,0
PRODUCTVERSION 3,4,0,0 PRODUCTVERSION 3,5,0,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L

View File

@ -1,225 +0,0 @@
param(
[string]$JavaDir,
[string]$Arch
)
$chinese = [System.Globalization.CultureInfo]::CurrentCulture.Name -eq 'zh-CN'
[Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[System.Windows.Forms.Application]::EnableVisualStyles()
# Choose Source Dialog
$dialog = New-Object System.Windows.Forms.Form
$dialog.AutoSize = $true
$dialog.AutoSizeMode = [System.Windows.Forms.AutoSizeMode]::GrowAndShrink
if ($chinese) {
$dialog.Text = '未能在这台电脑上找到 Java'
} else {
$dialog.Text = 'Java not found'
}
$dialogLayout = New-Object System.Windows.Forms.FlowLayoutPanel
$dialogLayout.AutoSize = $true
$dialogLayout.FlowDirection = [System.Windows.Forms.FlowDirection]::TopDown
$dialogLayout.AutoSizeMode = [System.Windows.Forms.AutoSizeMode]::GrowAndShrink
$messageLabel = New-Object System.Windows.Forms.Label
$messageLabel.AutoSize = $true
$messageLabel.Anchor = [System.Windows.Forms.AnchorStyles]::Bottom
if ($chinese) {
$messageLabel.Text = "HMCL 需要 Java 运行时环境才能正常运行,是否自动下载安装 Java"
} else {
$messageLabel.Text = "Running HMCL requires a Java runtime environment. `nDo you want to download and install Java automatically?"
}
$useMirrorCheckBox = New-Object System.Windows.Forms.CheckBox
$useMirrorCheckBox.AutoSize = $true
$useMirrorCheckBox.Anchor = [System.Windows.Forms.AnchorStyles]::Right
$useMirrorCheckBox.Checked = $false
if ($chinese) {
$useMirrorCheckBox.Text = '使用备用下载源(如果无法正常下载,请打开它再试一次)'
} else {
$useMirrorCheckBox.Text = 'Use the alternate download source'
}
$selectButtonPanel = New-Object System.Windows.Forms.FlowLayoutPanel
$selectButtonPanel.AutoSize = $true
$selectButtonPanel.Anchor = [System.Windows.Forms.AnchorStyles]::Right
$selectButtonPanel.FlowDirection = [System.Windows.Forms.FlowDirection]::LeftToRight
$selectButtonPanel.AutoSizeMode = [System.Windows.Forms.AutoSizeMode]::GrowAndShrink
$yesButton = New-Object System.Windows.Forms.Button
$noButton = New-Object System.Windows.Forms.Button
$yesButton.DialogResult = [System.Windows.Forms.DialogResult]::Yes
$noButton.DialogResult = [System.Windows.Forms.DialogResult]::No
if ($chinese) {
$yesButton.Text = '是'
$noButton.Text = '否'
} else {
$yesButton.Text = 'Yes'
$noButton.Text = 'No'
}
$selectButtonPanel.Controls.Add($yesButton)
$selectButtonPanel.Controls.Add($noButton)
$dialogLayout.Controls.Add($messageLabel)
$dialogLayout.Controls.Add($useMirrorCheckBox)
$dialogLayout.Controls.Add($selectButtonPanel)
$dialog.Controls.Add($dialogLayout)
$result = $dialog.ShowDialog()
if ($result -ne [System.Windows.Forms.DialogResult]::Yes) {
exit 0
}
if ($useMirrorCheckBox.Checked) {
switch ($Arch) {
'x86-64' {
$script:url = 'https://download.bell-sw.com/java/17.0.2+9/bellsoft-jre17.0.2+9-windows-amd64-full.zip'
}
'x86' {
$script:url = 'https://download.bell-sw.com/java/17.0.2+9/bellsoft-jre17.0.2+9-windows-i586-full.zip'
}
default { exit 1 }
}
} else {
switch ($Arch) {
'x86-64' {
$script:url = 'https://cdn.azul.com/zulu/bin/zulu17.32.13-ca-fx-jre17.0.2-win_x64.zip'
}
'x86' {
$script:url = 'https://cdn.azul.com/zulu/bin/zulu17.32.13-ca-fx-jre17.0.2-win_i686.zip'
}
default { exit 1 }
}
}
$securityProtocol = [System.Net.ServicePointManager]::SecurityProtocol.value__
if (($securityProtocol -ne 0) -and (($securityProtocol -band 0x00000C00) -eq 0)) { # Try using HTTP when the platform does not support TLS 1.2
$script:url = $script:url -replace '^https:', 'http:'
}
# Download Winodw
do {
$tempFileName = "hmcl-java-$(Get-Random).zip"
$script:tempFile = Join-Path ([System.IO.Path]::GetTempPath()) $tempFileName
} while (Test-Path $script:tempFile)
$form = New-Object System.Windows.Forms.Form
$form.AutoSize = $true
$form.AutoSizeMode = [System.Windows.Forms.AutoSizeMode]::GrowAndShrink
if ($chinese) {
$form.Text = '正在下载 Java 中'
} else {
$form.Text = 'Downloading Java'
}
$tip = New-Object System.Windows.Forms.Label
$tip.AutoSize = $true
if ($chinese) {
$tip.Text = '正在下载 Java。这需要一段时间请耐心等待。'
} else {
$tip.Text = 'Downloading Java. Please wait patiently for the download to complete.'
}
$layout = New-Object System.Windows.Forms.FlowLayoutPanel
$layout.AutoSize = $true
$layout.FlowDirection = [System.Windows.Forms.FlowDirection]::TopDown
$layout.AutoSizeMode = [System.Windows.Forms.AutoSizeMode]::GrowAndShrink
$progressBar = New-Object System.Windows.Forms.ProgressBar
$progressBar.Maximum = 100
$label = New-Object System.Windows.Forms.Label
$label.Anchor = [System.Windows.Forms.AnchorStyles]::Bottom
if ($chinese) {
$label.Text = '准备下载'
} else {
$label.Text = 'In preparation'
}
$box = New-Object System.Windows.Forms.FlowLayoutPanel
$box.AutoSize = $true
$box.FlowDirection = [System.Windows.Forms.FlowDirection]::LeftToRight
$box.AutoSizeMode = [System.Windows.Forms.AutoSizeMode]::GrowAndShrink
$box.Controls.Add($progressBar)
$box.Controls.Add($label)
$cancelButton = New-Object System.Windows.Forms.Button
$cancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
$cancelButton.Anchor = [System.Windows.Forms.AnchorStyles]::Right
if ($chinese) {
$cancelButton.Text = '取消'
} else {
$cancelButton.Text = 'Cancel'
}
$layout.Controls.Add($tip)
$layout.Controls.Add($box)
$box.Controls.Add($cancelButton)
$form.Controls.Add($layout)
[System.Net.DownloadProgressChangedEventHandler]$progressChangedEventHandler = {
param($sender, [System.Net.DownloadProgressChangedEventArgs]$ChangedEventArgs)
$bytesReceived = $ChangedEventArgs.BytesReceived
$totalBytes = $ChangedEventArgs.TotalBytesToReceive
$percentage = ([double]$bytesReceived)/([double]$totalBytes) * 100
$progressBar.Value = [int][System.Math]::Truncate($percentage)
$label.Text = [string]::Format("{0:0.00}%", $percentage)
}
[System.ComponentModel.AsyncCompletedEventHandler]$downloadFileCompletedEventHandler = {
param($sender, [System.ComponentModel.AsyncCompletedEventArgs]$CompletedEventArgs)
if (!$form.IsDisposed) {
$label.Refresh()
if ($CompletedEventArgs.Cancelled) {
$form.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
} elseif ($CompletedEventArgs.Error -ne $null) {
if ($chinese) {
[System.Windows.Forms.MessageBox]::Show($CompletedEventArgs.Error.Message, '下载失败', [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Exclamation)
} else {
[System.Windows.Forms.MessageBox]::Show($CompletedEventArgs.Error.Message, 'Download failed', [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Exclamation)
}
$form.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
} else {
$form.DialogResult = [System.Windows.Forms.DialogResult]::OK
}
}
}
$client = New-Object System.Net.WebClient
$client.Headers.Add('User-Agent', 'Wget/1.20.3 (linux-gnu)')
$client.add_DownloadProgressChanged($progressChangedEventHandler)
$client.add_DownloadFileCompleted($downloadFileCompletedEventHandler)
$client.DownloadFileAsync($script:url, $script:tempFile)
$result = $form.ShowDialog()
$client.CancelAsync()
$form.Dispose()
if ($result -eq [System.Windows.Forms.DialogResult]::OK) {
$null = New-Item -Type Directory -Force $JavaDir
$app = New-Object -ComObject Shell.Application
$items = $app.NameSpace($script:tempFile).items()
foreach ($item in $items) {
$app.NameSpace($JavaDir).copyHere($item)
}
}
if ([System.IO.File]::Exists($script:tempFile)) {
try {
[System.IO.File]::Delete($script:tempFile)
} catch {
Write-Error $_
}
}

View File

@ -6,9 +6,7 @@
#define ERROR_PROMPT L"The Java runtime environment is required to run HMCL and Minecraft,\n"\ #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"Click 'OK' to start downloading java.\n"\
L"Please restart HMCL after installing Java.\n"\ L"Please restart HMCL after installing Java."
L"Click 'Help' go for help."
#define ERROR_PROMPT_ZH L"运行 HMCL 以及 Minecraft 需要 Java 运行时环境,点击“确定”开始下载。\n"\ #define ERROR_PROMPT_ZH L"运行 HMCL 以及 Minecraft 需要 Java 运行时环境,点击“确定”开始下载。\n"\
L"请在安装 Java 完成后重新启动 HMCL。\n"\ L"请在安装 Java 完成后重新启动 HMCL。"
L"点击“帮助”寻求帮助。"

View File

@ -75,12 +75,11 @@ int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
bool useChinese = GetUserDefaultUILanguage() == 2052; // zh-CN bool useChinese = GetUserDefaultUILanguage() == 2052; // zh-CN
SYSTEM_INFO systemInfo; MyArchitecture architecture = MyGetArchitecture();
GetNativeSystemInfo(&systemInfo);
// TODO: check whether the bundled JRE is valid.
// First try the Java packaged together. // First try the Java packaged together.
bool isX64 = (systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64); bool isX64 = architecture == MyArchitecture::X86_64;
bool isARM64 = (systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM64); bool isARM64 = architecture == MyArchitecture::ARM64;
if (isARM64) { if (isARM64) {
RawLaunchJVM(L"jre-arm64\\bin\\javaw.exe", workdir, exeName, jvmOptions); RawLaunchJVM(L"jre-arm64\\bin\\javaw.exe", workdir, exeName, jvmOptions);
@ -143,7 +142,7 @@ int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
if (isARM64) { if (isARM64) {
downloadLink = L"https://docs.hmcl.net/downloads/windows/arm64.html"; downloadLink = L"https://docs.hmcl.net/downloads/windows/arm64.html";
} if (isX64) { } else if (isX64) {
downloadLink = L"https://docs.hmcl.net/downloads/windows/x86_64.html"; downloadLink = L"https://docs.hmcl.net/downloads/windows/x86_64.html";
} else { } else {
downloadLink = L"https://docs.hmcl.net/downloads/windows/x86.html"; downloadLink = L"https://docs.hmcl.net/downloads/windows/x86.html";

View File

@ -1,6 +1,41 @@
#include "stdafx.h" #include "stdafx.h"
#include "os.h" #include "os.h"
typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS2) (HANDLE, PUSHORT, PUSHORT);
MyArchitecture MyGetArchitecture() {
LPFN_ISWOW64PROCESS2 fnIsWow64Process2 = (LPFN_ISWOW64PROCESS2)GetProcAddress(
GetModuleHandle(L"Kernel32.dll"), "IsWow64Process2");
if (NULL != fnIsWow64Process2) {
USHORT uProcessMachine = 0;
USHORT uNativeMachine = 0;
if (fnIsWow64Process2(GetCurrentProcess(), &uProcessMachine, &uNativeMachine)) {
if (uNativeMachine == 0xAA64) {
return MyArchitecture::ARM64;
}
if (uNativeMachine == 0x8664) {
return MyArchitecture::X86_64;
}
return MyArchitecture::X86;
}
}
SYSTEM_INFO systemInfo;
GetNativeSystemInfo(&systemInfo);
if (systemInfo.wProcessorArchitecture == 12) { // PROCESSOR_ARCHITECTURE_ARM64
return MyArchitecture::ARM64;
}
if (systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) {
return MyArchitecture::X86_64;
}
return MyArchitecture::X86;
}
LSTATUS MyRegQueryValue(HKEY hKey, LPCWSTR subKey, DWORD dwType, LSTATUS MyRegQueryValue(HKEY hKey, LPCWSTR subKey, DWORD dwType,
std::wstring &out) { std::wstring &out) {
DWORD dwSize = 0; DWORD dwSize = 0;

View File

@ -8,9 +8,13 @@
const int MAX_KEY_LENGTH = 255; const int MAX_KEY_LENGTH = 255;
const int MAX_VALUE_NAME = 16383; const int MAX_VALUE_NAME = 16383;
#ifndef PROCESSOR_ARCHITECTURE_ARM64 enum MyArchitecture {
#define PROCESSOR_ARCHITECTURE_ARM64 12 X86,
#endif X86_64,
ARM64
};
MyArchitecture MyGetArchitecture();
// Query registry value of class root hKey, key path subKey, stores result in // Query registry value of class root hKey, key path subKey, stores result in
// parameter out. // parameter out.