You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
========================== MAJOR FEATURES + CHANGES ========================== Change 2718441 on 2015/10/06 by Ben.Marsh@Ben.Marsh_T3245_Stream Allow nodes to be added with an "explicit" frequency, meaning that they'll only be part of manually triggered builds (not CIS). Change 2718698 on 2015/10/06 by Ben.Marsh@Ben.Marsh_T3245_Stream Add a type of node that can execute an arbitrary sequence of tasks, and allow constructing graphs of such nodes from an XML file. Change 2723013 on 2015/10/09 by Ben.Marsh@Ben.Marsh_T3245_Stream Small utility to quickly capture a workspace, or delete files to restore the workspace to a previously captured state (and output a p4 sync list to restore it) Change 2744521 on 2015/10/28 by Matthew.Griffin@Matthew.Griffin_G5772_BuildStream Adding config entries to determine which platforms/configurations are available Currently only written out as part of the Rocket Build process but could be done elsewhere for other types of installed build. A near identical singleton class is used in both C++ and C# to load the config section and check whether configuration/platform combinations are valid. Change 2773723 on 2015/11/19 by Ben.Marsh@Ben.Marsh_T3245_Stream Copying UnrealGameSync into Engine/Source/Programs. Change 2773914 on 2015/11/19 by Ben.Marsh@Ben.Marsh_T3245_Stream PR #1687: [GitDependencies] New feature: ignore file support (.gitdepsignore) (Contributed by nbjk667) Change 2775317 on 2015/11/20 by Ben.Marsh@Ben.Marsh_T3245_Stream Add a -listtps option to UBT, which will find all the TPS files in any directory that's compiled into a target. Change 2780832 on 2015/11/25 by Ben.Marsh@Ben.Marsh_T3245_Stream Allow compiling a single file in UBT. Pass -singlefile=<Path> on command line to UBT to use. Change 2781071 on 2015/11/25 by Ben.Marsh@Ben.Marsh_T3245_Stream Precompile all valid engine modules for Rocket by default. Modules may set the PrecompileForTargets field to control which configurations they should be compiled for. Modules which currently fail to compile have this set to PrecompileTargetsType.None. #codereview Matthew.Griffin Change 2784469 on 2015/12/01 by Matthew.Griffin@Matthew.Griffin_G5772_BuildStream Added -FastPDB commandline parameter for UBT, so that we can make use of the /DEBUG:FASTLINK option in VS2015 Change 2784722 on 2015/12/01 by Matthew.Griffin@Matthew.Griffin_G5772_BuildStream Made -FastPDB option part of BuildConfiguration instead of checking commandline at each place it's used. Also added option to override if someone doesn't want it automatically added to their project files. Change 2787501 on 2015/12/02 by Ben.Marsh@Ben.Marsh_T3245_Stream Restore change to gather VC environment directly from registry. #lockdown Nick.Penwarden [CL 2790002 by Ben Marsh in Main branch]
176 lines
5.1 KiB
C++
176 lines
5.1 KiB
C++
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "BootstrapPackagedGame.h"
|
|
|
|
#define IDI_EXEC_FILE 201
|
|
#define IDI_EXEC_ARGS 202
|
|
|
|
WCHAR* ReadResourceString(HMODULE ModuleHandle, LPCWSTR Name)
|
|
{
|
|
WCHAR* Result = NULL;
|
|
|
|
HRSRC ResourceHandle = FindResource(ModuleHandle, Name, RT_RCDATA);
|
|
if(ResourceHandle != NULL)
|
|
{
|
|
HGLOBAL AllocHandle = LoadResource(ModuleHandle, ResourceHandle);
|
|
if(AllocHandle != NULL)
|
|
{
|
|
WCHAR* Data = (WCHAR*)LockResource(AllocHandle);
|
|
DWORD DataLen = SizeofResource(ModuleHandle, ResourceHandle) / sizeof(WCHAR);
|
|
|
|
Result = new WCHAR[DataLen + 1];
|
|
memcpy(Result, Data, DataLen * sizeof(WCHAR));
|
|
Result[DataLen] = 0;
|
|
}
|
|
}
|
|
|
|
return Result;
|
|
}
|
|
|
|
int InstallMissingPrerequisites(const WCHAR* BaseDirectory)
|
|
{
|
|
// Look for missing prerequisites
|
|
WCHAR MissingPrerequisites[1024] = { 0, };
|
|
if(LoadLibrary(L"MSVCP120.DLL") == NULL || LoadLibrary(L"MSVCR120.DLL") == NULL)
|
|
{
|
|
wcscat_s(MissingPrerequisites, TEXT("Microsoft Visual C++ 2013 Runtime\n"));
|
|
}
|
|
if(LoadLibrary(L"MSVCP140.DLL") == NULL || LoadLibrary(L"ucrtbase.dll") == NULL)
|
|
{
|
|
wcscat_s(MissingPrerequisites, TEXT("Microsoft Visual C++ 2015 Runtime\n"));
|
|
}
|
|
if(LoadLibrary(L"XINPUT1_3.DLL") == NULL)
|
|
{
|
|
wcscat_s(MissingPrerequisites, TEXT("DirectX Runtime\n"));
|
|
}
|
|
|
|
// Check if there's anything missing
|
|
if(MissingPrerequisites[0] != 0)
|
|
{
|
|
WCHAR MissingPrerequisitesMsg[1024];
|
|
wsprintf(MissingPrerequisitesMsg, L"The following component(s) are required to run this program:\n\n%s", MissingPrerequisites);
|
|
|
|
// If we don't have the installer, just notify the user and quit
|
|
WCHAR PrereqInstaller[MAX_PATH];
|
|
#ifdef _M_X64
|
|
PathCombine(PrereqInstaller, BaseDirectory, L"Engine\\Extras\\Redist\\en-us\\UE4PrereqSetup_x64.exe");
|
|
#else
|
|
PathCombine(PrereqInstaller, BaseDirectory, L"Engine\\Extras\\Redist\\en-us\\UE4PrereqSetup_x86.exe");
|
|
#endif
|
|
if(GetFileAttributes(PrereqInstaller) == INVALID_FILE_ATTRIBUTES)
|
|
{
|
|
MessageBox(NULL, MissingPrerequisitesMsg, NULL, MB_OK);
|
|
return 9001;
|
|
}
|
|
|
|
// Otherwise ask them if they want to install them
|
|
wcscat_s(MissingPrerequisitesMsg, L"\nWould you like to install them now?");
|
|
if(MessageBox(NULL, MissingPrerequisitesMsg, NULL, MB_YESNO) == IDNO)
|
|
{
|
|
return 9002;
|
|
}
|
|
|
|
// Start the installer
|
|
SHELLEXECUTEINFO ShellExecuteInfo;
|
|
ZeroMemory(&ShellExecuteInfo, sizeof(ShellExecuteInfo));
|
|
ShellExecuteInfo.cbSize = sizeof(ShellExecuteInfo);
|
|
ShellExecuteInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
|
|
ShellExecuteInfo.nShow = SW_SHOWNORMAL;
|
|
ShellExecuteInfo.lpFile = PrereqInstaller;
|
|
if(!ShellExecuteExW(&ShellExecuteInfo))
|
|
{
|
|
return 9003;
|
|
}
|
|
|
|
// Wait for the process to complete, then get its exit code
|
|
DWORD ExitCode = 0;
|
|
WaitForSingleObject(ShellExecuteInfo.hProcess, INFINITE);
|
|
GetExitCodeProcess(ShellExecuteInfo.hProcess, &ExitCode);
|
|
CloseHandle(ShellExecuteInfo.hProcess);
|
|
if(ExitCode != 0)
|
|
{
|
|
return 9004;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int SpawnTarget(WCHAR* CmdLine)
|
|
{
|
|
STARTUPINFO StartupInfo;
|
|
ZeroMemory(&StartupInfo, sizeof(StartupInfo));
|
|
StartupInfo.cb = sizeof(StartupInfo);
|
|
|
|
PROCESS_INFORMATION ProcessInfo;
|
|
ZeroMemory(&ProcessInfo, sizeof(ProcessInfo));
|
|
|
|
if(!CreateProcess(NULL, CmdLine, NULL, NULL, FALSE, 0, NULL, NULL, &StartupInfo, &ProcessInfo))
|
|
{
|
|
DWORD ErrorCode = GetLastError();
|
|
|
|
WCHAR* Buffer = new WCHAR[wcslen(CmdLine) + 50];
|
|
wsprintf(Buffer, L"Couldn't start:\n%s\nCreateProcess() returned %x.", CmdLine, ErrorCode);
|
|
MessageBoxW(NULL, Buffer, NULL, MB_OK);
|
|
delete Buffer;
|
|
|
|
return 9005;
|
|
}
|
|
|
|
WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
|
|
DWORD ExitCode = 9006;
|
|
GetExitCodeProcess(ProcessInfo.hProcess, &ExitCode);
|
|
|
|
CloseHandle(ProcessInfo.hThread);
|
|
CloseHandle(ProcessInfo.hProcess);
|
|
return (int)ExitCode;
|
|
}
|
|
|
|
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, TCHAR* CmdLine, int ShowCmd)
|
|
{
|
|
(void)hPrevInstance;
|
|
(void)ShowCmd;
|
|
|
|
// Get the current module filename
|
|
WCHAR CurrentModuleFile[MAX_PATH];
|
|
GetModuleFileNameW(hInstance, CurrentModuleFile, sizeof(CurrentModuleFile));
|
|
|
|
// Get the base directory from the current module filename
|
|
WCHAR BaseDirectory[MAX_PATH];
|
|
PathCanonicalize(BaseDirectory, CurrentModuleFile);
|
|
PathRemoveFileSpec(BaseDirectory);
|
|
|
|
// Get the executable to run
|
|
WCHAR* ExecFile = ReadResourceString(hInstance, MAKEINTRESOURCE(IDI_EXEC_FILE));
|
|
if(ExecFile == NULL)
|
|
{
|
|
MessageBoxW(NULL, L"This program is used for packaged games and is not meant to be run directly.", NULL, MB_OK);
|
|
return 9000;
|
|
}
|
|
|
|
// Create a full command line for the program to run
|
|
WCHAR* BaseArgs = ReadResourceString(hInstance, MAKEINTRESOURCE(IDI_EXEC_ARGS));
|
|
WCHAR* ChildCmdLine = new WCHAR[wcslen(BaseDirectory) + wcslen(ExecFile) + wcslen(BaseArgs) + wcslen(CmdLine) + 20];
|
|
wsprintf(ChildCmdLine, L"\"%s\\%s\" %s %s", BaseDirectory, ExecFile, BaseArgs, CmdLine);
|
|
delete BaseArgs;
|
|
delete ExecFile;
|
|
|
|
// Install the prerequisites
|
|
int ExitCode = InstallMissingPrerequisites(BaseDirectory);
|
|
if(ExitCode != 0)
|
|
{
|
|
delete ChildCmdLine;
|
|
return ExitCode;
|
|
}
|
|
|
|
// Spawn the target executable
|
|
ExitCode = SpawnTarget(ChildCmdLine);
|
|
if(ExitCode != 0)
|
|
{
|
|
delete ChildCmdLine;
|
|
return ExitCode;
|
|
}
|
|
|
|
delete ChildCmdLine;
|
|
return ExitCode;
|
|
}
|