Skip to content
Permalink
Browse files

Merge pull request #8217 from CookiePLMonster/windows-updater-improve…

…ments

Updates to auto-updater on Windows
  • Loading branch information...
stenzek committed Jul 23, 2019
2 parents 66e7a11 + baab660 commit 8f6b237e119b5bfb1317cb36b6fac6c71245b4f0
@@ -95,6 +95,11 @@ void Updater::OnUpdateAvailable(const NewVersionInformation& info)
AutoUpdateChecker::RestartMode::RESTART_AFTER_UPDATE);

if (!later)
m_parent->close();
{
RunOnObject(m_parent, [this] {
m_parent->close();
return 0;
});
}
}
}
@@ -234,12 +234,16 @@ void AutoUpdateChecker::TriggerUpdate(const AutoUpdateChecker::NewVersionInforma
INFO_LOG(COMMON, "Updater command line: %s", command_line.c_str());

#ifdef _WIN32
STARTUPINFO sinfo = {sizeof(info)};
STARTUPINFO sinfo = {sizeof(sinfo)};
sinfo.dwFlags = STARTF_FORCEOFFFEEDBACK; // No hourglass cursor after starting the process.
PROCESS_INFORMATION pinfo;
if (!CreateProcessW(UTF8ToUTF16(reloc_updater_path).c_str(),
const_cast<wchar_t*>(UTF8ToUTF16(command_line).c_str()), nullptr, nullptr,
FALSE, 0, nullptr, nullptr, &sinfo, &pinfo))
if (CreateProcessW(UTF8ToUTF16(reloc_updater_path).c_str(), UTF8ToUTF16(command_line).data(),
nullptr, nullptr, FALSE, 0, nullptr, nullptr, &sinfo, &pinfo))
{
CloseHandle(pinfo.hThread);
CloseHandle(pinfo.hProcess);
}
else
{
ERROR_LOG(COMMON, "Could not start updater process: error=%d", GetLastError());
}
@@ -16,6 +16,7 @@
#include "Common/CommonPaths.h"
#include "Common/FileUtil.h"
#include "Common/HttpRequest.h"
#include "Common/ScopeGuard.h"
#include "Common/StringUtil.h"
#include "UpdaterCommon/UI.h"

@@ -498,7 +499,6 @@ void FatalError(const std::string& message)

UI::SetVisible(true);
UI::Error(message);
UI::Stop();
}

std::optional<Manifest> ParseManifest(const std::string& manifest)
@@ -686,6 +686,7 @@ bool RunUpdater(std::vector<std::string> args)
UI::Init();
UI::SetVisible(false);

Common::ScopeGuard ui_guard{[] { UI::Stop(); }};
Options opts = std::move(*maybe_opts);

if (opts.log_file)
@@ -777,7 +778,5 @@ bool RunUpdater(std::vector<std::string> args)
UI::LaunchApplication(opts.binary_to_restart.value());
}

UI::Stop();

return true;
}
@@ -6,6 +6,7 @@
#include <ShlObj.h>
#include <shellapi.h>

#include <optional>
#include <string>
#include <vector>

@@ -32,6 +33,28 @@ std::vector<std::string> CommandLineToUtf8Argv(PCWSTR command_line)
LocalFree(tokenized);
return argv;
}

std::optional<std::wstring> GetModuleName(HINSTANCE hInstance)
{
std::wstring name;
DWORD max_size = 50; // Start with space for 50 characters and grow if needed
name.resize(max_size);

DWORD size;
while ((size = GetModuleFileNameW(hInstance, name.data(), max_size)) == max_size &&
GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
max_size *= 2;
name.resize(max_size);
}

if (size == 0)
{
return {};
}
name.resize(size);
return name;
}
}; // namespace

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
@@ -64,15 +87,15 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine
return 1;
}

wchar_t path[MAX_PATH];
if (GetModuleFileName(hInstance, path, sizeof(path)) == 0)
auto path = GetModuleName(hInstance);
if (!path)
{
MessageBox(nullptr, L"Failed to get updater filename.", L"Error", MB_ICONERROR);
return 1;
}

// Relaunch the updater as administrator
ShellExecuteW(nullptr, L"runas", path, pCmdLine, NULL, SW_SHOW);
ShellExecuteW(nullptr, L"runas", path->c_str(), pCmdLine, NULL, SW_SHOW);
return 0;
}

@@ -12,7 +12,6 @@
#include <ShObjIdl.h>
#include <shellapi.h>

#include "Common/Flag.h"
#include "Common/StringUtil.h"

namespace
@@ -23,8 +22,7 @@ HWND total_progressbar_handle = nullptr;
HWND current_progressbar_handle = nullptr;
ITaskbarList3* taskbar_list = nullptr;

Common::Flag running;
Common::Flag request_stop;
std::thread ui_thread;

int GetWindowHeight(HWND hwnd)
{
@@ -33,6 +31,17 @@ int GetWindowHeight(HWND hwnd)

return rect.bottom - rect.top;
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
}; // namespace

constexpr int PROGRESSBAR_FLAGS = WS_VISIBLE | WS_CHILD | PBS_SMOOTH | PBS_SMOOTHREVERSE;
@@ -46,7 +55,7 @@ bool InitWindow()
InitCommonControls();

WNDCLASS wndcl = {};
wndcl.lpfnWndProc = DefWindowProcW;
wndcl.lpfnWndProc = WindowProc;
wndcl.hbrBackground = GetSysColorBrush(COLOR_MENU);
wndcl.lpszClassName = L"UPDATER";

@@ -124,14 +133,6 @@ bool InitWindow()
return true;
}

void Destroy()
{
DestroyWindow(window_handle);
DestroyWindow(label_handle);
DestroyWindow(total_progressbar_handle);
DestroyWindow(current_progressbar_handle);
}

void SetTotalMarquee(bool marquee)
{
SetWindowLong(total_progressbar_handle, GWL_STYLE,
@@ -199,49 +200,40 @@ void SetDescription(const std::string& text)

void MessageLoop()
{
request_stop.Clear();
running.Set();

if (!InitWindow())
{
running.Clear();
MessageBox(nullptr, L"Window init failed!", L"", MB_ICONERROR);
// Destroying the parent (if exists) destroys all children windows
if (window_handle)
{
DestroyWindow(window_handle);
window_handle = nullptr;
}
return;
}

SetTotalMarquee(true);
SetCurrentMarquee(true);

while (!request_stop.IsSet())
MSG msg;
while (GetMessage(&msg, nullptr, 0, 0))
{
MSG msg;
while (PeekMessage(&msg, window_handle, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}

running.Clear();

Destroy();
}

void Init()
{
std::thread thread(MessageLoop);
thread.detach();
ui_thread = std::thread(MessageLoop);
}

void Stop()
{
if (!running.IsSet())
return;
if (window_handle)
PostMessage(window_handle, WM_CLOSE, 0, 0);

request_stop.Set();

while (running.IsSet())
{
}
ui_thread.join();
}

void LaunchApplication(std::string path)
@@ -259,8 +251,11 @@ void Sleep(int sleep)
void WaitForPID(u32 pid)
{
HANDLE parent_handle = OpenProcess(SYNCHRONIZE, FALSE, static_cast<DWORD>(pid));
WaitForSingleObject(parent_handle, INFINITE);
CloseHandle(parent_handle);
if (parent_handle)
{
WaitForSingleObject(parent_handle, INFINITE);
CloseHandle(parent_handle);
}
}

void SetVisible(bool visible)

0 comments on commit 8f6b237

Please sign in to comment.
You can’t perform that action at this time.