mirror of
https://github.com/WinampDesktop/winamp.git
synced 2025-06-10 18:25:45 -04:00
Add update installer program (Windows only for now)
This commit is contained in:
@ -8,6 +8,9 @@ add_subdirectory(scmversion)
|
||||
|
||||
if(NOT BUILD_LIBRETRO_CORE)
|
||||
add_subdirectory(common-tests)
|
||||
if(WIN32)
|
||||
add_subdirectory(updater)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(ANDROID OR BUILD_SDL_FRONTEND OR BUILD_QT_FRONTEND OR BUILD_LIBRETRO_CORE)
|
||||
|
12
src/updater/CMakeLists.txt
Normal file
12
src/updater/CMakeLists.txt
Normal file
@ -0,0 +1,12 @@
|
||||
add_executable(updater
|
||||
updater.cpp
|
||||
updater.h
|
||||
)
|
||||
|
||||
target_link_libraries(updater PRIVATE common minizip zlib)
|
||||
|
||||
if(WIN32)
|
||||
target_sources(updater PRIVATE
|
||||
win32_main.cpp
|
||||
)
|
||||
endif()
|
289
src/updater/updater.cpp
Normal file
289
src/updater/updater.cpp
Normal file
@ -0,0 +1,289 @@
|
||||
#include "updater.h"
|
||||
#include "common/file_system.h"
|
||||
#include "common/log.h"
|
||||
#include "common/minizip_helpers.h"
|
||||
#include "common/string_util.h"
|
||||
#include "common/win32_progress_callback.h"
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
Updater::Updater(ProgressCallback* progress) : m_progress(progress)
|
||||
{
|
||||
progress->SetTitle("DuckStation Update Installer");
|
||||
}
|
||||
|
||||
Updater::~Updater()
|
||||
{
|
||||
if (m_zf)
|
||||
unzClose(m_zf);
|
||||
}
|
||||
|
||||
bool Updater::Initialize(std::string destination_directory)
|
||||
{
|
||||
m_destination_directory = std::move(destination_directory);
|
||||
m_staging_directory = StringUtil::StdStringFromFormat("%s%c%s", m_destination_directory.c_str(),
|
||||
FS_OSPATH_SEPERATOR_CHARACTER, "UPDATE_STAGING");
|
||||
m_progress->DisplayFormattedDebugMessage("Destination directory: '%s'", m_destination_directory.c_str());
|
||||
m_progress->DisplayFormattedDebugMessage("Staging directory: '%s'", m_staging_directory.c_str());
|
||||
|
||||
// log everything to file as well
|
||||
Log::SetFileOutputParams(true, StringUtil::StdStringFromFormat("%s%cupdater.log", m_destination_directory.c_str(),
|
||||
FS_OSPATH_SEPERATOR_CHARACTER)
|
||||
.c_str());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Updater::OpenUpdateZip(const char* path)
|
||||
{
|
||||
m_zf = MinizipHelpers::OpenUnzFile(path);
|
||||
if (!m_zf)
|
||||
return false;
|
||||
|
||||
return ParseZip();
|
||||
}
|
||||
|
||||
bool Updater::ParseZip()
|
||||
{
|
||||
if (unzGoToFirstFile(m_zf) != UNZ_OK)
|
||||
{
|
||||
m_progress->ModalError("unzGoToFirstFile() failed");
|
||||
return {};
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
char zip_filename_buffer[256];
|
||||
unz_file_info64 file_info;
|
||||
if (unzGetCurrentFileInfo64(m_zf, &file_info, zip_filename_buffer, sizeof(zip_filename_buffer), nullptr, 0, nullptr,
|
||||
0) != UNZ_OK)
|
||||
{
|
||||
m_progress->ModalError("unzGetCurrentFileInfo64() failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
FileToUpdate entry;
|
||||
entry.original_zip_filename = zip_filename_buffer;
|
||||
|
||||
// replace forward slashes with backslashes
|
||||
size_t len = std::strlen(zip_filename_buffer);
|
||||
for (size_t i = 0; i < len; i++)
|
||||
{
|
||||
if (zip_filename_buffer[i] == '/' || zip_filename_buffer[i] == '\\')
|
||||
zip_filename_buffer[i] = FS_OSPATH_SEPERATOR_CHARACTER;
|
||||
}
|
||||
|
||||
// should never have a leading slash. just in case.
|
||||
while (zip_filename_buffer[0] == FS_OSPATH_SEPERATOR_CHARACTER)
|
||||
std::memmove(&zip_filename_buffer[1], &zip_filename_buffer[0], --len);
|
||||
|
||||
// skip directories (we sort them out later)
|
||||
if (len > 0 && zip_filename_buffer[len - 1] != FS_OSPATH_SEPERATOR_CHARACTER)
|
||||
{
|
||||
// skip updater itself, since it was already pre-extracted.
|
||||
if (StringUtil::Strcasecmp(zip_filename_buffer, "updater.exe") == 0)
|
||||
continue;
|
||||
|
||||
entry.destination_filename = zip_filename_buffer;
|
||||
m_progress->DisplayFormattedDebugMessage("Found file in zip: '%s'", entry.destination_filename.c_str());
|
||||
m_update_paths.push_back(std::move(entry));
|
||||
}
|
||||
|
||||
int res = unzGoToNextFile(m_zf);
|
||||
if (res == UNZ_END_OF_LIST_OF_FILE)
|
||||
break;
|
||||
if (res != UNZ_OK)
|
||||
{
|
||||
m_progress->ModalError("unzGoToNextFile() failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_update_paths.empty())
|
||||
{
|
||||
m_progress->ModalError("No files found in update zip.");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const FileToUpdate& ftu : m_update_paths)
|
||||
{
|
||||
const size_t len = ftu.destination_filename.length();
|
||||
for (size_t i = 0; i < len; i++)
|
||||
{
|
||||
if (ftu.destination_filename[i] == FS_OSPATH_SEPERATOR_CHARACTER)
|
||||
{
|
||||
std::string dir(ftu.destination_filename.begin(), ftu.destination_filename.begin() + i);
|
||||
while (!dir.empty() && dir[dir.length() - 1] == FS_OSPATH_SEPERATOR_CHARACTER)
|
||||
dir.erase(dir.length() - 1);
|
||||
|
||||
if (std::find(m_update_directories.begin(), m_update_directories.end(), dir) == m_update_directories.end())
|
||||
m_update_directories.push_back(std::move(dir));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::sort(m_update_directories.begin(), m_update_directories.end());
|
||||
for (const std::string& dir : m_update_directories)
|
||||
m_progress->DisplayFormattedDebugMessage("Directory: %s", dir.c_str());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Updater::PrepareStagingDirectory()
|
||||
{
|
||||
if (FileSystem::DirectoryExists(m_staging_directory.c_str()))
|
||||
{
|
||||
m_progress->DisplayFormattedWarning("Update staging directory already exists, removing");
|
||||
FileSystem::DeleteDirectory(m_staging_directory.c_str(), true);
|
||||
if (FileSystem::DirectoryExists(m_staging_directory.c_str()))
|
||||
{
|
||||
m_progress->ModalError("Failed to remove old staging directory");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!FileSystem::CreateDirectory(m_staging_directory.c_str(), false))
|
||||
{
|
||||
m_progress->DisplayFormattedModalError("Failed to create staging directory %s", m_staging_directory.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
// create subdirectories in staging directory
|
||||
for (const std::string& subdir : m_update_directories)
|
||||
{
|
||||
m_progress->DisplayFormattedInformation("Creating subdirectory in staging: %s", subdir.c_str());
|
||||
|
||||
const std::string staging_subdir = StringUtil::StdStringFromFormat("%s%c%s", m_staging_directory.c_str(),
|
||||
FS_OSPATH_SEPERATOR_CHARACTER, subdir.c_str());
|
||||
if (!FileSystem::CreateDirectory(staging_subdir.c_str(), false))
|
||||
{
|
||||
m_progress->DisplayFormattedModalError("Failed to create staging subdirectory %s", staging_subdir.c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Updater::StageUpdate()
|
||||
{
|
||||
m_progress->SetProgressRange(static_cast<u32>(m_update_paths.size()));
|
||||
m_progress->SetProgressValue(0);
|
||||
|
||||
for (const FileToUpdate& ftu : m_update_paths)
|
||||
{
|
||||
m_progress->SetFormattedStatusText("Extracting '%s'...", ftu.original_zip_filename.c_str());
|
||||
|
||||
if (unzLocateFile(m_zf, ftu.original_zip_filename.c_str(), 0) != UNZ_OK)
|
||||
{
|
||||
m_progress->DisplayFormattedModalError("Unable to locate file '%s' in zip", ftu.original_zip_filename.c_str());
|
||||
return false;
|
||||
}
|
||||
else if (unzOpenCurrentFile(m_zf) != UNZ_OK)
|
||||
{
|
||||
m_progress->DisplayFormattedModalError("Failed to open file '%s' in zip", ftu.original_zip_filename.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
m_progress->DisplayFormattedInformation("Extracting '%s'...", ftu.destination_filename.c_str());
|
||||
|
||||
const std::string destination_file = StringUtil::StdStringFromFormat(
|
||||
"%s%c%s", m_staging_directory.c_str(), FS_OSPATH_SEPERATOR_CHARACTER, ftu.destination_filename.c_str());
|
||||
std::FILE* fp = FileSystem::OpenCFile(destination_file.c_str(), "wb");
|
||||
if (!fp)
|
||||
{
|
||||
m_progress->DisplayFormattedModalError("Failed to open staging output file '%s'", destination_file.c_str());
|
||||
unzCloseCurrentFile(m_zf);
|
||||
return false;
|
||||
}
|
||||
|
||||
static constexpr u32 CHUNK_SIZE = 4096;
|
||||
u8 buffer[CHUNK_SIZE];
|
||||
for (;;)
|
||||
{
|
||||
int byte_count = unzReadCurrentFile(m_zf, buffer, CHUNK_SIZE);
|
||||
if (byte_count < 0)
|
||||
{
|
||||
m_progress->DisplayFormattedModalError("Failed to read file '%s' from zip", ftu.original_zip_filename.c_str());
|
||||
std::fclose(fp);
|
||||
FileSystem::DeleteFile(destination_file.c_str());
|
||||
unzCloseCurrentFile(m_zf);
|
||||
return false;
|
||||
}
|
||||
else if (byte_count == 0)
|
||||
{
|
||||
// end of file
|
||||
break;
|
||||
}
|
||||
|
||||
if (std::fwrite(buffer, static_cast<size_t>(byte_count), 1, fp) != 1)
|
||||
{
|
||||
m_progress->DisplayFormattedModalError("Failed to write to file '%s'", destination_file.c_str());
|
||||
std::fclose(fp);
|
||||
FileSystem::DeleteFile(destination_file.c_str());
|
||||
unzCloseCurrentFile(m_zf);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::fclose(fp);
|
||||
unzCloseCurrentFile(m_zf);
|
||||
m_progress->IncrementProgressValue();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Updater::CommitUpdate()
|
||||
{
|
||||
m_progress->SetStatusText("Committing update...");
|
||||
|
||||
// create directories in target
|
||||
for (const std::string& subdir : m_update_directories)
|
||||
{
|
||||
const std::string dest_subdir = StringUtil::StdStringFromFormat("%s%c%s", m_destination_directory.c_str(),
|
||||
FS_OSPATH_SEPERATOR_CHARACTER, subdir.c_str());
|
||||
|
||||
if (!FileSystem::DirectoryExists(dest_subdir.c_str()) && !FileSystem::CreateDirectory(dest_subdir.c_str(), false))
|
||||
{
|
||||
m_progress->DisplayFormattedModalError("Failed to create target directory '%s'", dest_subdir.c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// move files to target
|
||||
for (const FileToUpdate& ftu : m_update_paths)
|
||||
{
|
||||
const std::string staging_file_name = StringUtil::StdStringFromFormat(
|
||||
"%s%c%s", m_staging_directory.c_str(), FS_OSPATH_SEPERATOR_CHARACTER, ftu.destination_filename.c_str());
|
||||
const std::string dest_file_name = StringUtil::StdStringFromFormat(
|
||||
"%s%c%s", m_destination_directory.c_str(), FS_OSPATH_SEPERATOR_CHARACTER, ftu.destination_filename.c_str());
|
||||
m_progress->DisplayFormattedDebugMessage("Moving '%s' to '%s'", staging_file_name.c_str(), dest_file_name.c_str());
|
||||
#ifdef WIN32
|
||||
const bool result =
|
||||
MoveFileExW(StringUtil::UTF8StringToWideString(staging_file_name).c_str(),
|
||||
StringUtil::UTF8StringToWideString(dest_file_name).c_str(), MOVEFILE_REPLACE_EXISTING);
|
||||
#else
|
||||
const bool result = (rename(staging_file_name.c_str(), dest_file_name.c_str()) == 0);
|
||||
#endif
|
||||
if (!result)
|
||||
{
|
||||
m_progress->DisplayFormattedModalError("Failed to rename '%s' to '%s'", staging_file_name.c_str(),
|
||||
dest_file_name.c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Updater::CleanupStagingDirectory()
|
||||
{
|
||||
// remove staging directory itself
|
||||
if (!FileSystem::DeleteDirectory(m_staging_directory.c_str(), true))
|
||||
m_progress->DisplayFormattedError("Failed to remove staging directory '%s'", m_staging_directory.c_str());
|
||||
}
|
38
src/updater/updater.h
Normal file
38
src/updater/updater.h
Normal file
@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
#include "common/progress_callback.h"
|
||||
#include "unzip.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class Updater
|
||||
{
|
||||
public:
|
||||
Updater(ProgressCallback* progress);
|
||||
~Updater();
|
||||
|
||||
bool Initialize(std::string destination_directory);
|
||||
|
||||
bool OpenUpdateZip(const char* path);
|
||||
bool PrepareStagingDirectory();
|
||||
bool StageUpdate();
|
||||
bool CommitUpdate();
|
||||
void CleanupStagingDirectory();
|
||||
|
||||
private:
|
||||
struct FileToUpdate
|
||||
{
|
||||
std::string original_zip_filename;
|
||||
std::string destination_filename;
|
||||
};
|
||||
|
||||
bool ParseZip();
|
||||
|
||||
std::string m_destination_directory;
|
||||
std::string m_staging_directory;
|
||||
|
||||
std::vector<FileToUpdate> m_update_paths;
|
||||
std::vector<std::string> m_update_directories;
|
||||
|
||||
ProgressCallback* m_progress;
|
||||
unzFile m_zf = nullptr;
|
||||
};
|
22
src/updater/updater.manifest
Normal file
22
src/updater/updater.manifest
Normal file
@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||
<assemblyIdentity
|
||||
version="1.0.0.0"
|
||||
processorArchitecture="*"
|
||||
name="com.github.stenzek.duckstation.updater"
|
||||
type="win32"
|
||||
/>
|
||||
<description>DuckStation Updater</description>
|
||||
<dependency>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity
|
||||
type="win32"
|
||||
name="Microsoft.Windows.Common-Controls"
|
||||
version="6.0.0.0"
|
||||
processorArchitecture="*"
|
||||
publicKeyToken="6595b64144ccf1df"
|
||||
language="*"
|
||||
/>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
</assembly>
|
382
src/updater/updater.vcxproj
Normal file
382
src/updater/updater.vcxproj
Normal file
@ -0,0 +1,382 @@
|
||||
<?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="DebugFast|Win32">
|
||||
<Configuration>DebugFast</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="DebugFast|x64">
|
||||
<Configuration>DebugFast</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="ReleaseLTCG|Win32">
|
||||
<Configuration>ReleaseLTCG</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="ReleaseLTCG|x64">
|
||||
<Configuration>ReleaseLTCG</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\dep\minizip\minizip.vcxproj">
|
||||
<Project>{8bda439c-6358-45fb-9994-2ff083babe06}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\dep\zlib\zlib.vcxproj">
|
||||
<Project>{7ff9fdb9-d504-47db-a16a-b08071999620}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\common\common.vcxproj">
|
||||
<Project>{ee054e08-3799-4a59-a422-18259c105ffd}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="win32_main.cpp" />
|
||||
<ClCompile Include="updater.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Manifest Include="updater.manifest" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="updater.h" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{32EEAF44-57F8-4C6C-A6F0-DE5667123DD5}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>updater</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugFast|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugFast|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<SpectreMitigation>false</SpectreMitigation>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTCG|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<SpectreMitigation>false</SpectreMitigation>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<SpectreMitigation>false</SpectreMitigation>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTCG|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<SpectreMitigation>false</SpectreMitigation>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</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 Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugFast|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugFast|x64'" Label="PropertySheets">
|
||||
<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 Condition="'$(Configuration)|$(Platform)'=='ReleaseLTCG|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTCG|x64'" Label="PropertySheets">
|
||||
<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>
|
||||
<OutDir>$(SolutionDir)bin\$(Platform)\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\$(ProjectName)-$(Platform)-$(Configuration)\</IntDir>
|
||||
<TargetName>$(ProjectName)-$(Platform)-$(Configuration)</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<IntDir>$(SolutionDir)build\$(ProjectName)-$(Platform)-$(Configuration)\</IntDir>
|
||||
<TargetName>$(ProjectName)-$(Platform)-$(Configuration)</TargetName>
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)bin\$(Platform)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugFast|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)bin\$(Platform)\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\$(ProjectName)-$(Platform)-$(Configuration)\</IntDir>
|
||||
<TargetName>$(ProjectName)-$(Platform)-$(Configuration)</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugFast|x64'">
|
||||
<IntDir>$(SolutionDir)build\$(ProjectName)-$(Platform)-$(Configuration)\</IntDir>
|
||||
<TargetName>$(ProjectName)-$(Platform)-$(Configuration)</TargetName>
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)bin\$(Platform)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>$(SolutionDir)bin\$(Platform)\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\$(ProjectName)-$(Platform)-$(Configuration)\</IntDir>
|
||||
<TargetName>$(ProjectName)-$(Platform)-$(Configuration)</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTCG|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)bin\$(Platform)\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\$(ProjectName)-$(Platform)-$(Configuration)\</IntDir>
|
||||
<TargetName>$(ProjectName)-$(Platform)-$(Configuration)</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<IntDir>$(SolutionDir)build\$(ProjectName)-$(Platform)-$(Configuration)\</IntDir>
|
||||
<TargetName>$(ProjectName)-$(Platform)-$(Configuration)</TargetName>
|
||||
<OutDir>$(SolutionDir)bin\$(Platform)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTCG|x64'">
|
||||
<IntDir>$(SolutionDir)build\$(ProjectName)-$(Platform)-$(Configuration)\</IntDir>
|
||||
<TargetName>$(ProjectName)-$(Platform)-$(Configuration)</TargetName>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)bin\$(Platform)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)dep\zlib\include;$(SolutionDir)dep\minizip\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>d3d11.lib;dxgi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)dep\zlib\include;$(SolutionDir)dep\minizip\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>d3d11.lib;dxgi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugFast|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_ITERATOR_DEBUG_LEVEL=1;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUGFAST;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)dep\zlib\include;$(SolutionDir)dep\minizip\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>d3d11.lib;dxgi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugFast|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_ITERATOR_DEBUG_LEVEL=1;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUGFAST;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)dep\zlib\include;$(SolutionDir)dep\minizip\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>d3d11.lib;dxgi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)dep\zlib\include;$(SolutionDir)dep\minizip\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>d3d11.lib;dxgi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTCG|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)dep\zlib\include;$(SolutionDir)dep\minizip\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<OmitFramePointers>true</OmitFramePointers>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>d3d11.lib;dxgi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)dep\zlib\include;$(SolutionDir)dep\minizip\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>d3d11.lib;dxgi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTCG|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)dep\zlib\include;$(SolutionDir)dep\minizip\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<OmitFramePointers>true</OmitFramePointers>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>d3d11.lib;dxgi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
13
src/updater/updater.vcxproj.filters
Normal file
13
src/updater/updater.vcxproj.filters
Normal file
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<ClCompile Include="updater.cpp" />
|
||||
<ClCompile Include="win32_main.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Manifest Include="updater.manifest" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="updater.h" />
|
||||
</ItemGroup>
|
||||
</Project>
|
93
src/updater/win32_main.cpp
Normal file
93
src/updater/win32_main.cpp
Normal file
@ -0,0 +1,93 @@
|
||||
#include "common/file_system.h"
|
||||
#include "common/log.h"
|
||||
#include "common/string_util.h"
|
||||
#include "common/win32_progress_callback.h"
|
||||
#include "common/windows_headers.h"
|
||||
#include "updater.h"
|
||||
#include <shellapi.h>
|
||||
|
||||
static void WaitForProcessToExit(int process_id)
|
||||
{
|
||||
HANDLE hProcess = OpenProcess(SYNCHRONIZE, FALSE, process_id);
|
||||
if (!hProcess)
|
||||
return;
|
||||
|
||||
WaitForSingleObject(hProcess, INFINITE);
|
||||
CloseHandle(hProcess);
|
||||
}
|
||||
|
||||
int wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd)
|
||||
{
|
||||
Log::SetConsoleOutputParams(true);
|
||||
|
||||
Win32ProgressCallback progress;
|
||||
|
||||
int argc = 0;
|
||||
LPWSTR* argv = CommandLineToArgvW(lpCmdLine, &argc);
|
||||
if (!argv || argc <= 0)
|
||||
{
|
||||
progress.ModalError("Failed to parse command line.");
|
||||
return 1;
|
||||
}
|
||||
if (argc != 4)
|
||||
{
|
||||
progress.ModalError("Expected 4 arguments: parent process id, output directory, update zip, program to launch.");
|
||||
LocalFree(argv);
|
||||
return 1;
|
||||
}
|
||||
|
||||
const int parent_process_id = StringUtil::FromChars<int>(StringUtil::WideStringToUTF8String(argv[0])).value_or(0);
|
||||
const std::string destination_directory = StringUtil::WideStringToUTF8String(argv[1]);
|
||||
const std::string zip_path = StringUtil::WideStringToUTF8String(argv[2]);
|
||||
const std::string program_to_launch = StringUtil::WideStringToUTF8String(argv[3]);
|
||||
LocalFree(argv);
|
||||
|
||||
if (parent_process_id <= 0 || destination_directory.empty() || zip_path.empty() || program_to_launch.empty())
|
||||
{
|
||||
progress.ModalError("One or more parameters is empty.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
progress.SetFormattedStatusText("Waiting for parent process %d to exit...", parent_process_id);
|
||||
WaitForProcessToExit(parent_process_id);
|
||||
|
||||
Updater updater(&progress);
|
||||
if (!updater.Initialize(destination_directory))
|
||||
{
|
||||
progress.ModalError("Failed to initialize updater.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!updater.OpenUpdateZip(zip_path.c_str()))
|
||||
{
|
||||
progress.DisplayFormattedModalError("Could not open update zip '%s'. Update not installed.", zip_path.c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!updater.PrepareStagingDirectory())
|
||||
{
|
||||
progress.ModalError("Failed to prepare staging directory. Update not installed.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!updater.StageUpdate())
|
||||
{
|
||||
progress.ModalError("Failed to stage update. Update not installed.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!updater.CommitUpdate())
|
||||
{
|
||||
progress.ModalError(
|
||||
"Failed to commit update. Your installation may be corrupted, please re-download a fresh version from GitHub.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
updater.CleanupStagingDirectory();
|
||||
|
||||
progress.ModalInformation("Update complete.");
|
||||
|
||||
progress.DisplayFormattedInformation("Launching '%s'...", program_to_launch.c_str());
|
||||
ShellExecuteA(nullptr, "open", program_to_launch.c_str(), nullptr, nullptr, SW_SHOWNORMAL);
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user