diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ae2965f..3f522b1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,16 +5,17 @@ jobs: strategy: matrix: platform: [ x64, Win32, ARM64 ] + configuration: [ Release, Debug ] runs-on: windows-2022 steps: - uses: actions/checkout@v2 - uses: microsoft/setup-msbuild@v1.1 with: msbuild-architecture: x64 - - run: msbuild.exe fabric-installer-native-bootstrap.sln /property:Configuration=Release /p:Platform=${{ matrix.platform }} + - run: msbuild.exe fabric-installer-native-bootstrap.sln /property:Configuration=${{ matrix.configuration }} /p:Platform=${{ matrix.platform }} - uses: actions/upload-artifact@v2 with: - name: Artifacts ${{ matrix.platform }} + name: Artifacts ${{ matrix.platform }} ${{ matrix.configuration }} path: | - ${{ matrix.platform }}/Release/fabric-installer-native-bootstrap.exe - ${{ matrix.platform }}/Release/fabric-installer-native-bootstrap.pdb \ No newline at end of file + ${{ matrix.platform }}/${{ matrix.configuration }}/fabric-installer-native-bootstrap.exe + ${{ matrix.platform }}/${{ matrix.configuration }}/fabric-installer-native-bootstrap.pdb \ No newline at end of file diff --git a/fabric-installer-native-bootstrap.vcxproj b/fabric-installer-native-bootstrap.vcxproj index 95b15bb..d95e7a8 100644 --- a/fabric-installer-native-bootstrap.vcxproj +++ b/fabric-installer-native-bootstrap.vcxproj @@ -101,6 +101,8 @@ true $(SolutionDir)$(Platform)\$(Configuration)\ $(Platform)\$(Configuration)\ + true + NativeRecommendedRules.ruleset false @@ -109,9 +111,13 @@ true + true + NativeRecommendedRules.ruleset true + true + NativeRecommendedRules.ruleset false @@ -121,13 +127,15 @@ - Level3 + Level4 true WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true stdcpp20 MultiThreadedDebug - Guard + false + true + true Windows @@ -140,7 +148,7 @@ - Level3 + Level4 true true true @@ -149,12 +157,14 @@ stdcpp20 MultiThreaded Guard + true Windows true true true + true $(ProjectDir)fabric-installer-native-bootstrap.manifest %(AdditionalManifestFiles) @@ -162,13 +172,15 @@ - Level3 + Level4 true _DEBUG;_CONSOLE;%(PreprocessorDefinitions) true stdcpp20 MultiThreadedDebug - Guard + false + true + true Windows @@ -181,13 +193,15 @@ - Level3 + Level4 true _DEBUG;_CONSOLE;%(PreprocessorDefinitions) true stdcpp20 MultiThreadedDebug - Guard + false + true + true Windows @@ -200,7 +214,7 @@ - Level3 + Level4 true true true @@ -209,12 +223,14 @@ MultiThreaded stdcpp20 Guard + true Windows true true true + true $(ProjectDir)fabric-installer-native-bootstrap.manifest %(AdditionalManifestFiles) @@ -222,7 +238,7 @@ - Level3 + Level4 true true true @@ -231,12 +247,14 @@ MultiThreaded stdcpp20 Guard + true Windows true true true + false $(ProjectDir)fabric-installer-native-bootstrap.manifest %(AdditionalManifestFiles) diff --git a/src/Bootstrap.cpp b/src/Bootstrap.cpp index f69c5a7..51258f1 100644 --- a/src/Bootstrap.cpp +++ b/src/Bootstrap.cpp @@ -3,27 +3,29 @@ #include #include -constexpr LPCWSTR ERROR_TITLE = L"Fabric Installer"; -constexpr LPCWSTR ERROR_MESSAGE = L"The Fabric Installer could not find a valid Java installation.\n\nWould you like to open the Fabric wiki to find out how to fix this?\n\nURL: https://fabricmc.net/wiki/player:tutorials:java:windows"; -constexpr LPCWSTR ERROR_URL = L"https://fabricmc.net/wiki/player:tutorials:java:windows"; - -constexpr LPCWSTR MC_LAUNCH_REG_PATH = LR"(SOFTWARE\Mojang\InstalledProducts\Minecraft Launcher)"; -constexpr LPCWSTR MC_LAUNCH_REG_KEY = L"InstallLocation"; - -static const LPCWSTR UWP_PATH = LR"(\Packages\Microsoft.4297127D64EC6_8wekyb3d8bbwe\LocalCache\Local\)"; - -static const std::vector MC_JAVA_PATHS = { - LR"(runtime\java-runtime-gamma\windows-x64\java-runtime-gamma\bin\javaw.exe)", // Java 17.0.3 - LR"(runtime\java-runtime-gamma\windows-x86\java-runtime-gamma\bin\javaw.exe)", - LR"(runtime\java-runtime-beta\windows-x64\java-runtime-beta\bin\javaw.exe)", // Java 17.0.1 - LR"(runtime\java-runtime-beta\windows-x86\java-runtime-beta\bin\javaw.exe)", - LR"(runtime\java-runtime-alpha\windows-x64\java-runtime-alpha\bin\javaw.exe)", // Java 16 - LR"(runtime\java-runtime-alpha\windows-x86\java-runtime-alpha\bin\javaw.exe)", - LR"(runtime\jre-legacy\windows-x64\jre-legacy\bin\javaw.exe)", // Java 8 new location - LR"(runtime\jre-legacy\windows-x86\jre-legacy\bin\javaw.exe)", - LR"(runtime\jre-x64\bin\javaw.exe)", // Java 8 old location - LR"(runtime\jre-x86\bin\javaw.exe)", -}; +namespace { + constexpr LPCWSTR ERROR_TITLE = L"Fabric Installer"; + constexpr LPCWSTR ERROR_MESSAGE = L"The Fabric Installer could not find a valid Java installation.\n\nWould you like to open the Fabric wiki to find out how to fix this?\n\nURL: https://fabricmc.net/wiki/player:tutorials:java:windows"; + constexpr LPCWSTR ERROR_URL = L"https://fabricmc.net/wiki/player:tutorials:java:windows"; + + constexpr LPCWSTR MC_LAUNCH_REG_PATH = LR"(SOFTWARE\Mojang\InstalledProducts\Minecraft Launcher)"; + constexpr LPCWSTR MC_LAUNCH_REG_KEY = L"InstallLocation"; + + constexpr const LPCWSTR UWP_PATH = LR"(\Packages\Microsoft.4297127D64EC6_8wekyb3d8bbwe\LocalCache\Local\)"; + + static const std::vector MC_JAVA_PATHS = { + LR"(runtime\java-runtime-gamma\windows-x64\java-runtime-gamma\bin\javaw.exe)", // Java 17.0.8 + LR"(runtime\java-runtime-gamma\windows-x86\java-runtime-gamma\bin\javaw.exe)", + LR"(runtime\java-runtime-beta\windows-x64\java-runtime-beta\bin\javaw.exe)", // Java 17.0.1 + LR"(runtime\java-runtime-beta\windows-x86\java-runtime-beta\bin\javaw.exe)", + LR"(runtime\java-runtime-alpha\windows-x64\java-runtime-alpha\bin\javaw.exe)", // Java 16 + LR"(runtime\java-runtime-alpha\windows-x86\java-runtime-alpha\bin\javaw.exe)", + LR"(runtime\jre-legacy\windows-x64\jre-legacy\bin\javaw.exe)", // Java 8 new location + LR"(runtime\jre-legacy\windows-x86\jre-legacy\bin\javaw.exe)", + LR"(runtime\jre-x64\bin\javaw.exe)", // Java 8 old location + LR"(runtime\jre-x86\bin\javaw.exe)", + }; +} Bootstrap::Bootstrap(const std::shared_ptr& systemHelper) : systemHelper(systemHelper) {} @@ -116,20 +118,18 @@ bool Bootstrap::attemptLaunch(const std::wstring& path, bool checkExists) { std::wcout << "Testing for valid java @ (" << path << ")" << std::endl; DWORD exit = systemHelper->createProcess({ path, L"-version" }); - if (exit == 0) { - // -version returned a successful exit code. - std::wcout << "Found valid java @ (" << path << ")" << std::endl; + if (exit != 0) { + std::wcout << "Java @ (" << path << ") returned an exit code of: " << std::to_wstring(exit) << std::endl; + return false; + } - if (systemHelper->createProcess({ path, L"-jar", systemHelper->getBootstrapFilename(), L"-fabricInstallerBootstrap", L"true" }) != 0) { - // The installer returned a none 0 exit code, meaning that most likely the installer crashed. - throw std::runtime_error("Installer returned a none 0 exit code"); - } + std::wcout << "Found valid java @ (" << path << ")" << std::endl; - return true; - } - else { - std::wcout << "Java @ (" << path << ") returned an exit code of: " << std::to_wstring(exit) << std::endl; + exit = systemHelper->createProcess({ path, L"-jar", systemHelper->getBootstrapFilename(), L"-fabricInstallerBootstrap", L"true" }); + if (exit != 0) { + // The installer returned a none 0 exit code, meaning that most likely the installer crashed. + throw std::runtime_error("Installer returned a none 0 exit code: " + exit); } - return false; + return true; } \ No newline at end of file diff --git a/src/SystemHelper.cpp b/src/SystemHelper.cpp index 2bca0cc..9848c94 100644 --- a/src/SystemHelper.cpp +++ b/src/SystemHelper.cpp @@ -19,8 +19,8 @@ std::optional SystemHelper::getRegValue(HKEY hive, const std::wstr return std::nullopt; } - std::wstring data; - data.resize(dataSize / sizeof(wchar_t)); + std::wstring value; + value.resize(dataSize / sizeof(wchar_t)); retCode = ::RegGetValueW( hive, @@ -28,7 +28,7 @@ std::optional SystemHelper::getRegValue(HKEY hive, const std::wstr key.c_str(), RRF_RT_REG_SZ, nullptr, - &data[0], + value.data(), &dataSize ); @@ -38,9 +38,8 @@ std::optional SystemHelper::getRegValue(HKEY hive, const std::wstr DWORD stringLengthInWchars = dataSize / sizeof(wchar_t); stringLengthInWchars--; // Exclude the NUL written by the Win32 API - data.resize(stringLengthInWchars); - - return data; + value.resize(stringLengthInWchars); + return value; } std::optional SystemHelper::getEnvVar(const std::wstring& key) @@ -53,7 +52,7 @@ std::optional SystemHelper::getEnvVar(const std::wstring& key) // Read the env var std::wstring value(size, L'\0'); - size = ::GetEnvironmentVariableW(key.c_str(), &value[0], size); + size = ::GetEnvironmentVariableW(key.c_str(), value.data(), size); if (!size || size >= value.size()) { return std::nullopt; } @@ -63,7 +62,7 @@ std::optional SystemHelper::getEnvVar(const std::wstring& key) } void SystemHelper::showErrorMessage(const std::wstring& title, const std::wstring& message, const std::wstring& url) { - int result = MessageBoxW( + const int result = ::MessageBoxW( nullptr, message.c_str(), title.c_str(), @@ -71,7 +70,7 @@ void SystemHelper::showErrorMessage(const std::wstring& title, const std::wstrin ); if (result == IDYES) { - ShellExecuteW(nullptr, nullptr, url.c_str(), nullptr, nullptr, SW_SHOW); + ::ShellExecuteW(nullptr, nullptr, url.c_str(), nullptr, nullptr, SW_SHOW); } } @@ -117,7 +116,7 @@ DWORD SystemHelper::createProcess(std::vector args) } else { std::string msg = "Failed to create process: " + std::to_string(GetLastError()); - return -1; + return 255; // throw std::exception(msg.c_str()); } } diff --git a/src/main.cpp b/src/main.cpp index bb83f66..dbaa267 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,16 +1,30 @@ #include "Bootstrap.h" #include "SystemHelper.h" -int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow) { - // https://docs.microsoft.com/en-us/windows/win32/api/heapapi/nf-heapapi-heapsetinformation - HeapSetInformation(GetProcessHeap(), HeapEnableTerminationOnCorruption, NULL, 0); +#include +#include + +_Use_decl_annotations_ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow) { + UNREFERENCED_PARAMETER(hInstance); + UNREFERENCED_PARAMETER(hPrevInstance); + UNREFERENCED_PARAMETER(pCmdLine); + UNREFERENCED_PARAMETER(nCmdShow); + // We dont want to try and load DLLs from the current directory (Quite often the downloads dir) - SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_SYSTEM32); + ::SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_SYSTEM32); + // https://docs.microsoft.com/en-us/windows/win32/api/heapapi/nf-heapapi-heapsetinformation + ::HeapSetInformation(::GetProcessHeap(), HeapEnableTerminationOnCorruption, NULL, 0); const auto systemHelper = std::make_shared(); auto bs = Bootstrap(systemHelper); - bs.launch(); + + try { + bs.launch(); + } catch (const std::runtime_error& error) { + std::cout << error.what() << std::endl; + return 1; + } return 0; }