mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-08-03 19:36:53 -04:00
拆分 HMCLauncher 至独立项目 (#3840)
This commit is contained in:
parent
84b3312ebb
commit
9d0c8da310
46
.github/workflows/build-launcher.yml
vendored
46
.github/workflows/build-launcher.yml
vendored
@ -1,46 +0,0 @@
|
|||||||
name: Build HMCLauncher
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
paths:
|
|
||||||
- 'HMCLauncher/**'
|
|
||||||
- '.github/workflows/build-launcher.yml'
|
|
||||||
pull_request:
|
|
||||||
paths:
|
|
||||||
- 'HMCLauncher/**'
|
|
||||||
- '.github/workflows/build-launcher.yml'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: windows-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- name: Add msbuild to PATH
|
|
||||||
uses: microsoft/setup-msbuild@v2
|
|
||||||
with:
|
|
||||||
msbuild-architecture: x86
|
|
||||||
- name: Build HMCLauncher
|
|
||||||
run: msbuild /p:Configuration=Release /t:Rebuild /verbosity:detailed .\HMCLauncher\
|
|
||||||
- name: Copy HMCLauncher to assets
|
|
||||||
run: Copy-Item .\HMCLauncher\Release\HMCLauncher.exe -Destination .\HMCL\src\main\resources\assets\HMCLauncher.exe
|
|
||||||
- name: Set up JDK 11
|
|
||||||
uses: actions/setup-java@v4
|
|
||||||
with:
|
|
||||||
distribution: 'zulu'
|
|
||||||
java-version: '11'
|
|
||||||
java-package: 'jdk+fx'
|
|
||||||
- name: Build with Gradle
|
|
||||||
run: .\gradlew makeExecutables --no-daemon
|
|
||||||
env:
|
|
||||||
MICROSOFT_AUTH_ID: ${{ secrets.MICROSOFT_AUTH_ID }}
|
|
||||||
MICROSOFT_AUTH_SECRET: ${{ secrets.MICROSOFT_AUTH_SECRET }}
|
|
||||||
CURSEFORGE_API_KEY: ${{ secrets.CURSEFORGE_API_KEY }}
|
|
||||||
- name: Get short SHA
|
|
||||||
run: echo "SHORT_SHA=$("${{ github.sha }}".SubString(0, 7))" >> $env:GITHUB_ENV
|
|
||||||
- name: Copy HMCLauncher to libs
|
|
||||||
run: Copy-Item .\HMCLauncher\Release\HMCLauncher.exe -Destination .\HMCL\build\libs\HMCLauncher.exe
|
|
||||||
- name: Upload Artifacts
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: HMCLauncher-${{ env.SHORT_SHA }}
|
|
||||||
path: HMCL/build/libs/*.exe
|
|
1
.github/workflows/gradle.yml
vendored
1
.github/workflows/gradle.yml
vendored
@ -5,7 +5,6 @@ on:
|
|||||||
pull_request:
|
pull_request:
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- '**.md'
|
- '**.md'
|
||||||
- 'HMCLauncher/**'
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -42,7 +42,6 @@ minecraft-exported-crash-info*
|
|||||||
.nb-gradle
|
.nb-gradle
|
||||||
|
|
||||||
*.exe
|
*.exe
|
||||||
!/HMCL/src/main/resources/assets/HMCLauncher.exe
|
|
||||||
|
|
||||||
# macos
|
# macos
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
@ -33,12 +33,18 @@ val microsoftAuthId = System.getenv("MICROSOFT_AUTH_ID") ?: ""
|
|||||||
val microsoftAuthSecret = System.getenv("MICROSOFT_AUTH_SECRET") ?: ""
|
val microsoftAuthSecret = System.getenv("MICROSOFT_AUTH_SECRET") ?: ""
|
||||||
val curseForgeApiKey = System.getenv("CURSEFORGE_API_KEY") ?: ""
|
val curseForgeApiKey = System.getenv("CURSEFORGE_API_KEY") ?: ""
|
||||||
|
|
||||||
|
val launcherExe = System.getenv("HMCL_LAUNCHER_EXE")
|
||||||
|
|
||||||
version = "$versionRoot.$buildNumber"
|
version = "$versionRoot.$buildNumber"
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(project(":HMCLCore"))
|
implementation(project(":HMCLCore"))
|
||||||
implementation("libs:JFoenix")
|
implementation("libs:JFoenix")
|
||||||
implementation("com.twelvemonkeys.imageio:imageio-webp:3.12.0")
|
implementation("com.twelvemonkeys.imageio:imageio-webp:3.12.0")
|
||||||
|
|
||||||
|
if (launcherExe == null) {
|
||||||
|
implementation("org.glavo.hmcl:HMCLauncher:3.6.0.1")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun digest(algorithm: String, bytes: ByteArray): ByteArray = MessageDigest.getInstance(algorithm).digest(bytes)
|
fun digest(algorithm: String, bytes: ByteArray): ByteArray = MessageDigest.getInstance(algorithm).digest(bytes)
|
||||||
@ -154,23 +160,18 @@ tasks.getByName<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar>("sha
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (launcherExe != null) {
|
||||||
|
into("assets") {
|
||||||
|
from(file(launcherExe))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
doLast {
|
doLast {
|
||||||
attachSignature(jarPath)
|
attachSignature(jarPath)
|
||||||
createChecksum(jarPath)
|
createChecksum(jarPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createExecutable(suffix: String, header: String) {
|
|
||||||
val output = File(jarPath.parentFile, jarPath.nameWithoutExtension + '.' + suffix)
|
|
||||||
|
|
||||||
output.outputStream().use {
|
|
||||||
it.write(File(project.projectDir, header).readBytes())
|
|
||||||
it.write(jarPath.readBytes())
|
|
||||||
}
|
|
||||||
|
|
||||||
createChecksum(output)
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks.processResources {
|
tasks.processResources {
|
||||||
into("META-INF/versions/11") {
|
into("META-INF/versions/11") {
|
||||||
from(sourceSets["java11"].output)
|
from(sourceSets["java11"].output)
|
||||||
@ -179,10 +180,30 @@ tasks.processResources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val makeExecutables = tasks.create("makeExecutables") {
|
val makeExecutables = tasks.create("makeExecutables") {
|
||||||
|
val extensions = listOf("exe", "sh")
|
||||||
|
|
||||||
dependsOn(tasks.jar)
|
dependsOn(tasks.jar)
|
||||||
|
|
||||||
|
inputs.file(jarPath)
|
||||||
|
outputs.files(extensions.map { File(jarPath.parentFile, jarPath.nameWithoutExtension + '.' + it) })
|
||||||
|
|
||||||
doLast {
|
doLast {
|
||||||
createExecutable("exe", "src/main/resources/assets/HMCLauncher.exe")
|
val jarContent = jarPath.readBytes()
|
||||||
createExecutable("sh", "src/main/resources/assets/HMCLauncher.sh")
|
|
||||||
|
ZipFile(jarPath).use { zipFile ->
|
||||||
|
for (extension in extensions) {
|
||||||
|
val output = File(jarPath.parentFile, jarPath.nameWithoutExtension + '.' + extension)
|
||||||
|
val entry = zipFile.getEntry("assets/HMCLauncher.$extension")
|
||||||
|
?: throw GradleException("HMCLauncher.$extension not found")
|
||||||
|
|
||||||
|
output.outputStream().use { outputStream ->
|
||||||
|
zipFile.getInputStream(entry).use { it.copyTo(outputStream) }
|
||||||
|
outputStream.write(jarContent)
|
||||||
|
}
|
||||||
|
|
||||||
|
createChecksum(output)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -256,8 +277,10 @@ tasks.create<JavaExec>("run") {
|
|||||||
|
|
||||||
val hmclJavaHome = System.getenv("HMCL_JAVA_HOME")
|
val hmclJavaHome = System.getenv("HMCL_JAVA_HOME")
|
||||||
if (hmclJavaHome != null) {
|
if (hmclJavaHome != null) {
|
||||||
this.executable(file(hmclJavaHome).resolve("bin")
|
this.executable(
|
||||||
.resolve(if (System.getProperty("os.name").lowercase().startsWith("windows")) "java.exe" else "java"))
|
file(hmclJavaHome).resolve("bin")
|
||||||
|
.resolve(if (System.getProperty("os.name").lowercase().startsWith("windows")) "java.exe" else "java")
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
doFirst {
|
doFirst {
|
||||||
|
Binary file not shown.
@ -1,4 +0,0 @@
|
|||||||
# Use the Google style in this project.
|
|
||||||
BasedOnStyle: Google
|
|
||||||
|
|
||||||
SortIncludes: false
|
|
5
HMCLauncher/.gitignore
vendored
5
HMCLauncher/.gitignore
vendored
@ -1,5 +0,0 @@
|
|||||||
Debug
|
|
||||||
Release
|
|
||||||
.vs
|
|
||||||
*.APS
|
|
||||||
cmake-build-*/
|
|
@ -1,18 +0,0 @@
|
|||||||
cmake_minimum_required(VERSION 3.25)
|
|
||||||
project(HMCLauncher)
|
|
||||||
if(MSVC)
|
|
||||||
add_definitions(-DUNICODE -D_UNICODE)
|
|
||||||
add_compile_options(/utf-8 /W4)
|
|
||||||
add_link_options(/ENTRY:wWinMainCRTStartup)
|
|
||||||
else()
|
|
||||||
add_compile_options(-municode -Wall -Wextra -Wpedantic)
|
|
||||||
add_link_options(-municode)
|
|
||||||
endif()
|
|
||||||
OPTION(ENABLE_MINGW_STATIC_LINK_LIBSTDCXX "Link the C++ standard library statically to the executable file(mingw only)." ON)
|
|
||||||
if(ENABLE_MINGW_STATIC_LINK_LIBSTDCXX AND MINGW)
|
|
||||||
add_link_options(-static)
|
|
||||||
endif()
|
|
||||||
set(CMAKE_WIN32_EXECUTABLE ON)
|
|
||||||
add_executable(HMCLauncher WIN32 HMCL/HMCL.rc HMCL/java.cpp HMCL/main.cpp HMCL/os.cpp HMCL/stdafx.cpp HMCL/Version.cpp)
|
|
||||||
target_link_libraries(HMCLauncher Version)
|
|
||||||
install(TARGETS HMCLauncher)
|
|
Binary file not shown.
Before Width: | Height: | Size: 50 KiB |
@ -1,143 +0,0 @@
|
|||||||
// Microsoft Visual C++ generated resource script.
|
|
||||||
//
|
|
||||||
#include "resource.h"
|
|
||||||
|
|
||||||
#define APSTUDIO_READONLY_SYMBOLS
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Generated from the TEXTINCLUDE 2 resource.
|
|
||||||
//
|
|
||||||
#ifndef APSTUDIO_INVOKED
|
|
||||||
#include "targetver.h"
|
|
||||||
#endif
|
|
||||||
#define APSTUDIO_HIDDEN_SYMBOLS
|
|
||||||
#include "windows.h"
|
|
||||||
#undef APSTUDIO_HIDDEN_SYMBOLS
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
#undef APSTUDIO_READONLY_SYMBOLS
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// 中文(简体,中国) resources
|
|
||||||
|
|
||||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
|
|
||||||
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Icon
|
|
||||||
//
|
|
||||||
|
|
||||||
// Icon with lowest ID value placed first to ensure application icon
|
|
||||||
// remains consistent on all systems.
|
|
||||||
IDI_HMCL ICON "HMCL.ico"
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Accelerator
|
|
||||||
//
|
|
||||||
|
|
||||||
IDC_HMCL ACCELERATORS
|
|
||||||
BEGIN
|
|
||||||
"?", IDM_ABOUT, ASCII, ALT
|
|
||||||
"/", IDM_ABOUT, ASCII, ALT
|
|
||||||
END
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef APSTUDIO_INVOKED
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// TEXTINCLUDE
|
|
||||||
//
|
|
||||||
|
|
||||||
1 TEXTINCLUDE
|
|
||||||
BEGIN
|
|
||||||
"resource.h\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
2 TEXTINCLUDE
|
|
||||||
BEGIN
|
|
||||||
"#ifndef APSTUDIO_INVOKED\r\n"
|
|
||||||
"#include ""targetver.h""\r\n"
|
|
||||||
"#endif\r\n"
|
|
||||||
"#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
|
|
||||||
"#include ""windows.h""\r\n"
|
|
||||||
"#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
|
|
||||||
"\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
3 TEXTINCLUDE
|
|
||||||
BEGIN
|
|
||||||
"\r\n"
|
|
||||||
"\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
#endif // APSTUDIO_INVOKED
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Version
|
|
||||||
//
|
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
|
||||||
FILEVERSION 3,5,0,0
|
|
||||||
PRODUCTVERSION 3,5,0,0
|
|
||||||
FILEFLAGSMASK 0x3fL
|
|
||||||
#ifdef _DEBUG
|
|
||||||
FILEFLAGS 0x1L
|
|
||||||
#else
|
|
||||||
FILEFLAGS 0x0L
|
|
||||||
#endif
|
|
||||||
FILEOS 0x40004L
|
|
||||||
FILETYPE 0x1L
|
|
||||||
FILESUBTYPE 0x0L
|
|
||||||
BEGIN
|
|
||||||
BLOCK "StringFileInfo"
|
|
||||||
BEGIN
|
|
||||||
BLOCK "080404b0"
|
|
||||||
BEGIN
|
|
||||||
VALUE "CompanyName", "huanghongxun"
|
|
||||||
VALUE "FileDescription", "Hello Minecraft! Launcher For Windows"
|
|
||||||
VALUE "FileVersion", "3.5.0.0"
|
|
||||||
VALUE "InternalName", "HMCL.exe"
|
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2021 huangyuhui"
|
|
||||||
VALUE "OriginalFilename", "HMCL.exe"
|
|
||||||
VALUE "ProductName", "Hello Minecraft! Launcher"
|
|
||||||
VALUE "ProductVersion", "3.5.0.0"
|
|
||||||
END
|
|
||||||
END
|
|
||||||
BLOCK "VarFileInfo"
|
|
||||||
BEGIN
|
|
||||||
VALUE "Translation", 0x804, 1200
|
|
||||||
END
|
|
||||||
END
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// String Table
|
|
||||||
//
|
|
||||||
|
|
||||||
STRINGTABLE
|
|
||||||
BEGIN
|
|
||||||
IDS_APP_TITLE "HMCL"
|
|
||||||
IDC_HMCL "HMCL"
|
|
||||||
END
|
|
||||||
|
|
||||||
#endif // 中文(简体,中国) resources
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef APSTUDIO_INVOKED
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Generated from the TEXTINCLUDE 3 resource.
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
#endif // not APSTUDIO_INVOKED
|
|
||||||
|
|
@ -1,192 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
|
||||||
<Configuration>Debug</Configuration>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
<ProjectConfiguration Include="Release|Win32">
|
|
||||||
<Configuration>Release</Configuration>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
<ProjectConfiguration Include="Debug|x64">
|
|
||||||
<Configuration>Debug</Configuration>
|
|
||||||
<Platform>x64</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
<ProjectConfiguration Include="Release|x64">
|
|
||||||
<Configuration>Release</Configuration>
|
|
||||||
<Platform>x64</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
</ItemGroup>
|
|
||||||
<PropertyGroup Label="Globals">
|
|
||||||
<VCProjectVersion>15.0</VCProjectVersion>
|
|
||||||
<ProjectGuid>{672B1019-E741-4C0D-A986-627E2ACE157B}</ProjectGuid>
|
|
||||||
<Keyword>Win32Proj</Keyword>
|
|
||||||
<RootNamespace>HMCL</RootNamespace>
|
|
||||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
|
||||||
<ProjectName>HMCLauncher</ProjectName>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
|
||||||
<PlatformToolset>v143</PlatformToolset>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
|
||||||
<PlatformToolset>v143</PlatformToolset>
|
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
|
||||||
<PlatformToolset>v143</PlatformToolset>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
|
||||||
<PlatformToolset>v143</PlatformToolset>
|
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
|
||||||
<ImportGroup Label="ExtensionSettings">
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="Shared">
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<PropertyGroup Label="UserMacros" />
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<LinkIncremental>true</LinkIncremental>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
|
||||||
<LinkIncremental>true</LinkIncremental>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<LinkIncremental>false</LinkIncremental>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
|
||||||
<LinkIncremental>false</LinkIncremental>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<Optimization>Disabled</Optimization>
|
|
||||||
<SDLCheck>true</SDLCheck>
|
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<ConformanceMode>false</ConformanceMode>
|
|
||||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<SubSystem>Windows</SubSystem>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
<AdditionalDependencies>version.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
|
||||||
<ClCompile>
|
|
||||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<Optimization>Disabled</Optimization>
|
|
||||||
<SDLCheck>true</SDLCheck>
|
|
||||||
<PreprocessorDefinitions>_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<ConformanceMode>false</ConformanceMode>
|
|
||||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<SubSystem>Windows</SubSystem>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<Optimization>MinSpace</Optimization>
|
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
|
||||||
<IntrinsicFunctions>false</IntrinsicFunctions>
|
|
||||||
<SDLCheck>true</SDLCheck>
|
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS</PreprocessorDefinitions>
|
|
||||||
<ConformanceMode>false</ConformanceMode>
|
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
|
||||||
<InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
|
|
||||||
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
|
|
||||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<SubSystem>Windows</SubSystem>
|
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
<AdditionalDependencies>version.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
|
||||||
<ClCompile>
|
|
||||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<Optimization>MinSpace</Optimization>
|
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
|
||||||
<IntrinsicFunctions>false</IntrinsicFunctions>
|
|
||||||
<SDLCheck>true</SDLCheck>
|
|
||||||
<PreprocessorDefinitions>NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<ConformanceMode>false</ConformanceMode>
|
|
||||||
<InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
|
|
||||||
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
|
|
||||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<SubSystem>Windows</SubSystem>
|
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClInclude Include="java.h" />
|
|
||||||
<ClInclude Include="lang.h" />
|
|
||||||
<ClInclude Include="main.h" />
|
|
||||||
<ClInclude Include="os.h" />
|
|
||||||
<ClInclude Include="Resource.h" />
|
|
||||||
<ClInclude Include="stdafx.h" />
|
|
||||||
<ClInclude Include="targetver.h" />
|
|
||||||
<ClInclude Include="version.h" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClCompile Include="java.cpp" />
|
|
||||||
<ClCompile Include="main.cpp" />
|
|
||||||
<ClCompile Include="os.cpp" />
|
|
||||||
<ClCompile Include="stdafx.cpp">
|
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="version.cpp" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ResourceCompile Include="HMCL.rc" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<Image Include="HMCL.ico" />
|
|
||||||
</ItemGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
|
||||||
<ImportGroup Label="ExtensionTargets">
|
|
||||||
</ImportGroup>
|
|
||||||
</Project>
|
|
@ -1,70 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<ItemGroup>
|
|
||||||
<Filter Include="源文件">
|
|
||||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
|
||||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="头文件">
|
|
||||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
|
||||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="资源文件">
|
|
||||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
|
||||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
|
||||||
</Filter>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClInclude Include="stdafx.h">
|
|
||||||
<Filter>头文件</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="targetver.h">
|
|
||||||
<Filter>头文件</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="Resource.h">
|
|
||||||
<Filter>头文件</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="main.h">
|
|
||||||
<Filter>头文件</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="version.h">
|
|
||||||
<Filter>头文件</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="java.h">
|
|
||||||
<Filter>头文件</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="os.h">
|
|
||||||
<Filter>头文件</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="lang.h">
|
|
||||||
<Filter>头文件</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClCompile Include="stdafx.cpp">
|
|
||||||
<Filter>源文件</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="main.cpp">
|
|
||||||
<Filter>源文件</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="version.cpp">
|
|
||||||
<Filter>源文件</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="java.cpp">
|
|
||||||
<Filter>源文件</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="os.cpp">
|
|
||||||
<Filter>源文件</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ResourceCompile Include="HMCL.rc">
|
|
||||||
<Filter>资源文件</Filter>
|
|
||||||
</ResourceCompile>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<Image Include="HMCL.ico">
|
|
||||||
<Filter>资源文件</Filter>
|
|
||||||
</Image>
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
@ -1,4 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<PropertyGroup />
|
|
||||||
</Project>
|
|
@ -1,16 +0,0 @@
|
|||||||
#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');
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
class Version {
|
|
||||||
public:
|
|
||||||
int ver[4];
|
|
||||||
|
|
||||||
Version(const std::wstring &rawString);
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
Version(std::initializer_list<T> ver_list) {
|
|
||||||
int i = 0;
|
|
||||||
for (const auto &data : ver_list) {
|
|
||||||
if (i >= 4) break;
|
|
||||||
ver[i++] = data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 true;
|
|
||||||
}
|
|
||||||
};
|
|
@ -1,84 +0,0 @@
|
|||||||
#include "stdafx.h"
|
|
||||||
#include "java.h"
|
|
||||||
#include "os.h"
|
|
||||||
#include "version.h"
|
|
||||||
|
|
||||||
const Version JAVA_8(L"1.8"), JAVA_11(L"11");
|
|
||||||
|
|
||||||
const LPCWSTR JDK_NEW = L"SOFTWARE\\JavaSoft\\JDK";
|
|
||||||
const LPCWSTR JRE_NEW = L"SOFTWARE\\JavaSoft\\JRE";
|
|
||||||
const LPCWSTR JDK_OLD = L"SOFTWARE\\JavaSoft\\Java Development Kit";
|
|
||||||
const LPCWSTR JRE_OLD = L"SOFTWARE\\JavaSoft\\Java Runtime Environment";
|
|
||||||
|
|
||||||
bool oldJavaFound = 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
|
|
||||||
flag = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flag) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
RegCloseKey(hKey);
|
|
||||||
|
|
||||||
return flag;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FindJavaInRegistry(std::wstring& path) {
|
|
||||||
return FindJavaByRegistryKey(HKEY_LOCAL_MACHINE, JDK_NEW, path) ||
|
|
||||||
FindJavaByRegistryKey(HKEY_LOCAL_MACHINE, JRE_NEW, path) ||
|
|
||||||
FindJavaByRegistryKey(HKEY_LOCAL_MACHINE, JDK_OLD, path) ||
|
|
||||||
FindJavaByRegistryKey(HKEY_LOCAL_MACHINE, JRE_OLD, path);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FindJava(std::wstring& path) {
|
|
||||||
return ERROR_SUCCESS == MyGetEnvironmentVariable(L"HMCL_JAVA_HOME", path) ||
|
|
||||||
ERROR_SUCCESS == MyGetEnvironmentVariable(L"JAVA_HOME", path) ||
|
|
||||||
FindJavaInRegistry(path);
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <windows.h>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
// Find Java installation in system registry
|
|
||||||
bool FindJavaInRegistry(std::wstring &path);
|
|
||||||
|
|
||||||
// Find Java Installation in registry and environment variable
|
|
||||||
bool FindJava(std::wstring &path);
|
|
@ -1,12 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#define ERROR_TITLE L"Java not found"
|
|
||||||
|
|
||||||
#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。"
|
|
@ -1,155 +0,0 @@
|
|||||||
#include "stdafx.h"
|
|
||||||
#include "main.h"
|
|
||||||
#include "os.h"
|
|
||||||
#include "java.h"
|
|
||||||
#include "lang.h"
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
Version J8(TEXT("8"));
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
__declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
|
|
||||||
__declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001;
|
|
||||||
}
|
|
||||||
|
|
||||||
LPCWSTR VENDOR_DIRS[] = {
|
|
||||||
L"Java", L"Microsoft", L"BellSoft", L"Zulu", L"Eclipse Foundation", L"AdoptOpenJDK", L"Semeru"
|
|
||||||
};
|
|
||||||
|
|
||||||
void RawLaunchJVM(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))
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LaunchJVM(const std::wstring &javaPath, const std::wstring &workdir,
|
|
||||||
const std::wstring &jarPath, const std::wstring &jvmOptions) {
|
|
||||||
Version javaVersion(L"");
|
|
||||||
if (!MyGetFileVersionInfo(javaPath, javaVersion)) return;
|
|
||||||
|
|
||||||
if (J8 <= javaVersion) {
|
|
||||||
RawLaunchJVM(javaPath, workdir, jarPath, jvmOptions);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
HANDLE hFind = FindFirstFile(pattern.c_str(), &data); // Search all subdirectory
|
|
||||||
|
|
||||||
if (hFind != INVALID_HANDLE_VALUE) {
|
|
||||||
do {
|
|
||||||
std::wstring javaw = baseDir + data.cFileName + std::wstring(L"\\bin\\javaw.exe");
|
|
||||||
if (FindFirstFileExists(javaw.c_str(), 0)) {
|
|
||||||
LaunchJVM(javaw, workdir, jarPath, jvmOptions);
|
|
||||||
}
|
|
||||||
} while (FindNextFile(hFind, &data));
|
|
||||||
FindClose(hFind);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void OpenHelpPage() {
|
|
||||||
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) {
|
|
||||||
std::wstring path, exeName, jvmOptions;
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
|
|
||||||
std::wstring workdir;
|
|
||||||
size_t last_slash = exeName.find_last_of(L"/\\");
|
|
||||||
if (last_slash != std::wstring::npos && last_slash + 1 < exeName.size()) {
|
|
||||||
workdir = exeName.substr(0, last_slash);
|
|
||||||
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
|
|
||||||
|
|
||||||
MyArchitecture architecture = MyGetArchitecture();
|
|
||||||
|
|
||||||
// First try the Java packaged together.
|
|
||||||
bool isX64 = architecture == MyArchitecture::X86_64;
|
|
||||||
bool isARM64 = architecture == MyArchitecture::ARM64;
|
|
||||||
|
|
||||||
if (isARM64) {
|
|
||||||
RawLaunchJVM(L"jre-arm64\\bin\\javaw.exe", workdir, exeName, jvmOptions);
|
|
||||||
}
|
|
||||||
if (isX64) {
|
|
||||||
RawLaunchJVM(L"jre-x64\\bin\\javaw.exe", workdir, exeName, jvmOptions);
|
|
||||||
}
|
|
||||||
RawLaunchJVM(L"jre-x86\\bin\\javaw.exe", workdir, exeName, jvmOptions);
|
|
||||||
|
|
||||||
if (FindJava(path)) LaunchJVM(path + L"\\bin\\javaw.exe", workdir, exeName, jvmOptions);
|
|
||||||
|
|
||||||
std::wstring programFiles;
|
|
||||||
|
|
||||||
// Or we try to search Java in C:\Program Files
|
|
||||||
if (!SUCCEEDED(MySHGetFolderPath(CSIDL_PROGRAM_FILES, programFiles))) programFiles = L"C:\\Program Files\\";
|
|
||||||
for (LPCWSTR vendorDir : VENDOR_DIRS) {
|
|
||||||
std::wstring dir = programFiles;
|
|
||||||
MyPathAppend(dir, vendorDir);
|
|
||||||
MyPathAddBackslash(dir);
|
|
||||||
|
|
||||||
FindJavaInDirAndLaunchJVM(dir, workdir, exeName, jvmOptions);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Consider C:\Program Files (x86)
|
|
||||||
if (!SUCCEEDED(MySHGetFolderPath(CSIDL_PROGRAM_FILESX86, programFiles))) programFiles = L"C:\\Program Files (x86)\\";
|
|
||||||
for (LPCWSTR vendorDir : VENDOR_DIRS) {
|
|
||||||
std::wstring dir = programFiles;
|
|
||||||
MyPathAppend(dir, vendorDir);
|
|
||||||
MyPathAddBackslash(dir);
|
|
||||||
|
|
||||||
FindJavaInDirAndLaunchJVM(dir, workdir, exeName, jvmOptions);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try java in PATH
|
|
||||||
RawLaunchJVM(L"javaw", workdir, exeName, jvmOptions);
|
|
||||||
|
|
||||||
std::wstring hmclJavaDir;
|
|
||||||
{
|
|
||||||
std::wstring buffer;
|
|
||||||
if (SUCCEEDED(MySHGetFolderPath(CSIDL_APPDATA, buffer)) || SUCCEEDED(MySHGetFolderPath(CSIDL_PROFILE, buffer))) {
|
|
||||||
MyPathAppend(buffer, L".hmcl");
|
|
||||||
MyPathAppend(buffer, L"java");
|
|
||||||
if (isARM64) {
|
|
||||||
MyPathAppend(buffer, L"windows-arm64");
|
|
||||||
} else if (isX64) {
|
|
||||||
MyPathAppend(buffer, L"windows-x86_64");
|
|
||||||
} else {
|
|
||||||
MyPathAppend(buffer, L"windows-x86");
|
|
||||||
}
|
|
||||||
MyPathAddBackslash(buffer);
|
|
||||||
hmclJavaDir = buffer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hmclJavaDir.empty()) {
|
|
||||||
FindJavaInDirAndLaunchJVM(hmclJavaDir, workdir, exeName, jvmOptions);
|
|
||||||
}
|
|
||||||
|
|
||||||
LPCWSTR downloadLink;
|
|
||||||
|
|
||||||
if (isARM64) {
|
|
||||||
downloadLink = L"https://docs.hmcl.net/downloads/windows/arm64.html";
|
|
||||||
} else if (isX64) {
|
|
||||||
downloadLink = L"https://docs.hmcl.net/downloads/windows/x86_64.html";
|
|
||||||
} else {
|
|
||||||
downloadLink = L"https://docs.hmcl.net/downloads/windows/x86.html";
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "resource.h"
|
|
@ -1,203 +0,0 @@
|
|||||||
#include "stdafx.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,
|
|
||||||
std::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 = std::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 = std::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, const std::wstring &workdir) {
|
|
||||||
std::wstring writable_command = command;
|
|
||||||
STARTUPINFO si;
|
|
||||||
PROCESS_INFORMATION pi;
|
|
||||||
si.cb = sizeof(si);
|
|
||||||
ZeroMemory(&si, sizeof(si));
|
|
||||||
ZeroMemory(&pi, sizeof(pi));
|
|
||||||
|
|
||||||
if (workdir.empty()) {
|
|
||||||
return CreateProcess(NULL, &writable_command[0], NULL, NULL, false,
|
|
||||||
NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi);
|
|
||||||
} else {
|
|
||||||
return CreateProcess(NULL, &writable_command[0], NULL, NULL, false,
|
|
||||||
NORMAL_PRIORITY_CLASS, NULL, workdir.c_str(), &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 MyGetFileVersionInfo(const std::wstring &filePath, Version &version) {
|
|
||||||
DWORD verHandle = 0;
|
|
||||||
UINT size = 0;
|
|
||||||
LPBYTE lpBuffer = NULL;
|
|
||||||
VS_FIXEDFILEINFO *pFileInfo;
|
|
||||||
DWORD dwSize = GetFileVersionInfoSize(filePath.c_str(), NULL);
|
|
||||||
|
|
||||||
if (!dwSize) return false;
|
|
||||||
|
|
||||||
LPBYTE data = new BYTE[dwSize];
|
|
||||||
if (!GetFileVersionInfo(filePath.c_str(), 0, dwSize, data)) {
|
|
||||||
delete[] data;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!VerQueryValue(data, TEXT("\\"), (LPVOID *)&pFileInfo, &size)) {
|
|
||||||
delete[] data;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
version = Version{(pFileInfo->dwFileVersionMS >> 16) & 0xFFFF,
|
|
||||||
(pFileInfo->dwFileVersionMS >> 0) & 0xFFFF,
|
|
||||||
(pFileInfo->dwFileVersionLS >> 16) & 0xFFFF,
|
|
||||||
(pFileInfo->dwFileVersionLS >> 0) & 0xFFFF};
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT MySHGetFolderPath(int csidl, std::wstring &out) {
|
|
||||||
out = std::wstring();
|
|
||||||
out.resize(MAX_PATH);
|
|
||||||
|
|
||||||
HRESULT res = SHGetFolderPath(NULL, csidl, NULL, 0, &out[0]);
|
|
||||||
if (SUCCEEDED(res)) {
|
|
||||||
out.resize(wcslen(&out[0]));
|
|
||||||
} else {
|
|
||||||
out.resize(0);
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MyPathAppend(std::wstring &filePath, const std::wstring &more) {
|
|
||||||
if (filePath.back() != L'\\') {
|
|
||||||
filePath += L'\\';
|
|
||||||
}
|
|
||||||
|
|
||||||
filePath += more;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MyPathAddBackslash(std::wstring &filePath) {
|
|
||||||
if (filePath.back() != L'\\') {
|
|
||||||
filePath += L'\\';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LSTATUS MyGetTempFile(const std::wstring &prefixString, const std::wstring &ext, std::wstring &out) {
|
|
||||||
out.resize(MAX_PATH);
|
|
||||||
DWORD res = GetTempPath(MAX_PATH, &out[0]);
|
|
||||||
if (res == 0) {
|
|
||||||
return GetLastError();
|
|
||||||
}
|
|
||||||
|
|
||||||
out.resize(res);
|
|
||||||
|
|
||||||
GUID guid;
|
|
||||||
CoCreateGuid(&guid);
|
|
||||||
|
|
||||||
WCHAR buffer[MAX_PATH];
|
|
||||||
int n = StringFromGUID2(guid, buffer, MAX_PATH);
|
|
||||||
if (n == 0) {
|
|
||||||
return CO_E_PATHTOOLONG;
|
|
||||||
}
|
|
||||||
|
|
||||||
MyPathAddBackslash(out);
|
|
||||||
out += prefixString;
|
|
||||||
out += buffer;
|
|
||||||
out += L'.';
|
|
||||||
out += ext;
|
|
||||||
|
|
||||||
return ERROR_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MyAppendPathToCommandLine(std::wstring &commandLine, const std::wstring &path) {
|
|
||||||
commandLine += L'"';
|
|
||||||
for (size_t i = 0; i < path.size(); i++) {
|
|
||||||
WCHAR ch = path[i];
|
|
||||||
if (ch == L'\\' && (i + 1 == path.size() || path[i + 1] == L'"')) {
|
|
||||||
commandLine += L"\\\\";
|
|
||||||
} else if (ch == L'"') {
|
|
||||||
commandLine += L"\\\"";
|
|
||||||
} else {
|
|
||||||
commandLine += ch;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
commandLine += L'"';
|
|
||||||
}
|
|
@ -1,47 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <string>
|
|
||||||
#include <windows.h>
|
|
||||||
#include <shlobj.h>
|
|
||||||
#include <Objbase.h>
|
|
||||||
#include "Version.h"
|
|
||||||
|
|
||||||
const int MAX_KEY_LENGTH = 255;
|
|
||||||
const int MAX_VALUE_NAME = 16383;
|
|
||||||
|
|
||||||
enum MyArchitecture {
|
|
||||||
X86,
|
|
||||||
X86_64,
|
|
||||||
ARM64
|
|
||||||
};
|
|
||||||
|
|
||||||
MyArchitecture MyGetArchitecture();
|
|
||||||
|
|
||||||
// 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, const std::wstring &workdir);
|
|
||||||
|
|
||||||
// Check if file lpPath exists.
|
|
||||||
bool FindFirstFileExists(LPCWSTR lpPath, DWORD dwFilter);
|
|
||||||
|
|
||||||
bool MyGetFileVersionInfo(const std::wstring &filePath, Version &version);
|
|
||||||
|
|
||||||
HRESULT MySHGetFolderPath(int csidl, std::wstring &out);
|
|
||||||
|
|
||||||
void MyPathAppend(std::wstring &filePath, const std::wstring &more);
|
|
||||||
|
|
||||||
void MyPathAddBackslash(std::wstring &filePath);
|
|
||||||
|
|
||||||
LSTATUS MyGetTempFile(const std::wstring &prefixString, const std::wstring &ext, std::wstring &out);
|
|
||||||
|
|
||||||
void MyAppendPathToCommandLine(std::wstring &commandLine, const std::wstring &path);
|
|
@ -1,25 +0,0 @@
|
|||||||
//{{NO_DEPENDENCIES}}
|
|
||||||
// Microsoft Visual C++ 生成的包含文件。
|
|
||||||
// 供 HMCL.rc 使用
|
|
||||||
//
|
|
||||||
#define IDC_MYICON 2
|
|
||||||
#define IDD_HMCL_DIALOG 102
|
|
||||||
#define IDS_APP_TITLE 103
|
|
||||||
#define IDM_ABOUT 104
|
|
||||||
#define IDI_HMCL 107
|
|
||||||
#define IDC_HMCL 109
|
|
||||||
#define IDR_MAINFRAME 128
|
|
||||||
#define ID_SCRIPT_DOWNLOAD_JAVA 160
|
|
||||||
#define IDC_STATIC -1
|
|
||||||
|
|
||||||
// Next default values for new objects
|
|
||||||
//
|
|
||||||
#ifdef APSTUDIO_INVOKED
|
|
||||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
|
||||||
#define _APS_NO_MFC 1
|
|
||||||
#define _APS_NEXT_RESOURCE_VALUE 129
|
|
||||||
#define _APS_NEXT_COMMAND_VALUE 32771
|
|
||||||
#define _APS_NEXT_CONTROL_VALUE 1000
|
|
||||||
#define _APS_NEXT_SYMED_VALUE 110
|
|
||||||
#endif
|
|
||||||
#endif
|
|
@ -1,8 +0,0 @@
|
|||||||
// stdafx.cpp : 只包括标准包含文件的源文件
|
|
||||||
// HMCL.pch 将作为预编译标头
|
|
||||||
// stdafx.obj 将包含预编译类型信息
|
|
||||||
|
|
||||||
#include "stdafx.h"
|
|
||||||
|
|
||||||
// TODO: 在 STDAFX.H 中引用任何所需的附加头文件,
|
|
||||||
//而不是在此文件中引用
|
|
@ -1,7 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "targetver.h"
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string>
|
|
@ -1,8 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
// Windows 7
|
|
||||||
|
|
||||||
#define WINVER 0x0601
|
|
||||||
#define _WIN32_WINNT 0x0601
|
|
||||||
|
|
||||||
#include <SDKDDKVer.h>
|
|
@ -1,25 +0,0 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
|
||||||
# Visual Studio 15
|
|
||||||
VisualStudioVersion = 15.0.27428.2005
|
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HMCL", "HMCL\HMCL.vcxproj", "{672B1019-E741-4C0D-A986-627E2ACE157B}"
|
|
||||||
EndProject
|
|
||||||
Global
|
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
|
||||||
Debug|x86 = Debug|x86
|
|
||||||
Release|x86 = Release|x86
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
|
||||||
{672B1019-E741-4C0D-A986-627E2ACE157B}.Debug|x86.ActiveCfg = Debug|Win32
|
|
||||||
{672B1019-E741-4C0D-A986-627E2ACE157B}.Debug|x86.Build.0 = Debug|Win32
|
|
||||||
{672B1019-E741-4C0D-A986-627E2ACE157B}.Release|x86.ActiveCfg = Release|Win32
|
|
||||||
{672B1019-E741-4C0D-A986-627E2ACE157B}.Release|x86.Build.0 = Release|Win32
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
|
||||||
HideSolutionNode = FALSE
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
|
||||||
SolutionGuid = {FE40055B-673D-42F5-8AE4-6DF2C87EB659}
|
|
||||||
EndGlobalSection
|
|
||||||
EndGlobal
|
|
Loading…
x
Reference in New Issue
Block a user