Updater: Use IFileOperation for cleanup

This commit is contained in:
Stenzek 2024-04-04 22:18:17 +10:00 committed by Connor McLaughlin
parent 29a961a407
commit dd82ee532c
3 changed files with 44 additions and 9 deletions

View File

@ -18,6 +18,8 @@
#include <vector> #include <vector>
#ifdef _WIN32 #ifdef _WIN32
#include "common/RedtapeWilCom.h"
#include <Shobjidl.h>
#include <shellapi.h> #include <shellapi.h>
#endif #endif
@ -136,16 +138,42 @@ void Updater::CloseUpdateZip()
bool Updater::RecursiveDeleteDirectory(const char* path) bool Updater::RecursiveDeleteDirectory(const char* path)
{ {
#ifdef _WIN32 #ifdef _WIN32
// making this safer on Win32... wil::com_ptr_nothrow<IFileOperation> fo;
std::wstring wpath = FileSystem::GetWin32Path(path); HRESULT hr = CoCreateInstance(CLSID_FileOperation, NULL, CLSCTX_ALL, IID_PPV_ARGS(fo.put()));
wpath += L'\0'; if (FAILED(hr))
{
m_progress->DisplayFormattedError("CoCreateInstance() for IFileOperation failed: %08X", hr);
return false;
}
SHFILEOPSTRUCTW op = {}; wil::com_ptr_nothrow<IShellItem> item;
op.wFunc = FO_DELETE; hr = SHCreateItemFromParsingName(StringUtil::UTF8StringToWideString(path).c_str(), NULL, IID_PPV_ARGS(item.put()));
op.pFrom = wpath.c_str(); if (FAILED(hr))
op.fFlags = FOF_NOCONFIRMATION; {
m_progress->DisplayFormattedError("SHCreateItemFromParsingName() for delete failed: %08X", hr);
return false;
}
return (SHFileOperationW(&op) == 0 && !op.fAnyOperationsAborted); hr = fo->SetOperationFlags(FOF_NOCONFIRMATION | FOF_SILENT);
if (FAILED(hr))
m_progress->DisplayFormattedWarning("IFileOperation::SetOperationFlags() failed: %08X", hr);
hr = fo->DeleteItem(item.get(), nullptr);
if (FAILED(hr))
{
m_progress->DisplayFormattedError("IFileOperation::DeleteItem() failed: %08X", hr);
return false;
}
item.reset();
hr = fo->PerformOperations();
if (FAILED(hr))
{
m_progress->DisplayFormattedError("IFileOperation::PerformOperations() failed: %08X", hr);
return false;
}
return true;
#else #else
return FileSystem::RecursiveDeleteDirectory(path); return FileSystem::RecursiveDeleteDirectory(path);
#endif #endif

View File

@ -33,7 +33,7 @@ public:
std::string FindPCSX2Exe() const; std::string FindPCSX2Exe() const;
private: private:
static bool RecursiveDeleteDirectory(const char* path); bool RecursiveDeleteDirectory(const char* path);
void CloseUpdateZip(); void CloseUpdateZip();

View File

@ -6,6 +6,7 @@
#include "common/FileSystem.h" #include "common/FileSystem.h"
#include "common/Console.h" #include "common/Console.h"
#include "common/ScopedGuard.h"
#include "common/StringUtil.h" #include "common/StringUtil.h"
#include "common/ProgressCallback.h" #include "common/ProgressCallback.h"
#include "common/RedtapeWindows.h" #include "common/RedtapeWindows.h"
@ -420,6 +421,12 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLi
{ {
Win32ProgressCallback progress; Win32ProgressCallback progress;
const bool com_initialized = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
const ScopedGuard com_guard = [com_initialized]() {
if (com_initialized)
CoUninitialize();
};
int argc = 0; int argc = 0;
wil::unique_hlocal_ptr<LPWSTR[]> argv(CommandLineToArgvW(GetCommandLineW(), &argc)); wil::unique_hlocal_ptr<LPWSTR[]> argv(CommandLineToArgvW(GetCommandLineW(), &argc));
if (!argv || argc <= 0) if (!argv || argc <= 0)