mirror of
https://github.com/yuzu-emu/liftinstall.git
synced 2024-11-22 16:15:40 +01:00
native: fix uninstall self-destruction behavior...... by not showing the command prompt window and fork-spawning the cmd
This commit is contained in:
parent
5603981af1
commit
4578450bff
@ -8,6 +8,7 @@
|
|||||||
#include "objbase.h"
|
#include "objbase.h"
|
||||||
#include "objidl.h"
|
#include "objidl.h"
|
||||||
#include "shlguid.h"
|
#include "shlguid.h"
|
||||||
|
#include "shlobj.h"
|
||||||
|
|
||||||
// https://stackoverflow.com/questions/52101827/windows-10-getsyscolor-does-not-get-dark-ui-color-theme
|
// https://stackoverflow.com/questions/52101827/windows-10-getsyscolor-does-not-get-dark-ui-color-theme
|
||||||
extern "C" int isDarkThemeActive() {
|
extern "C" int isDarkThemeActive() {
|
||||||
@ -32,60 +33,65 @@ extern "C" int saveShortcut(
|
|||||||
const char *description,
|
const char *description,
|
||||||
const char *path,
|
const char *path,
|
||||||
const char *args,
|
const char *args,
|
||||||
const char *workingDir) {
|
const char *workingDir)
|
||||||
char* errStr = NULL;
|
{
|
||||||
|
char *errStr = NULL;
|
||||||
HRESULT h;
|
HRESULT h;
|
||||||
IShellLink* shellLink = NULL;
|
IShellLink *shellLink = NULL;
|
||||||
IPersistFile* persistFile = NULL;
|
IPersistFile *persistFile = NULL;
|
||||||
|
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
wchar_t wName[MAX_PATH+1];
|
wchar_t wName[MAX_PATH + 1];
|
||||||
#else
|
#else
|
||||||
WORD wName[MAX_PATH+1];
|
WORD wName[MAX_PATH + 1];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int id;
|
int id;
|
||||||
|
|
||||||
// Initialize the COM library
|
// Initialize the COM library
|
||||||
h = CoInitialize(NULL);
|
h = CoInitialize(NULL);
|
||||||
if (FAILED(h)) {
|
if (FAILED(h))
|
||||||
|
{
|
||||||
errStr = "Failed to initialize COM library";
|
errStr = "Failed to initialize COM library";
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
h = CoCreateInstance( CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
|
h = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
|
||||||
IID_IShellLink, (PVOID*)&shellLink );
|
IID_IShellLink, (PVOID *)&shellLink);
|
||||||
if (FAILED(h)) {
|
if (FAILED(h))
|
||||||
|
{
|
||||||
errStr = "Failed to create IShellLink";
|
errStr = "Failed to create IShellLink";
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
h = shellLink->QueryInterface(IID_IPersistFile, (PVOID*)&persistFile);
|
h = shellLink->QueryInterface(IID_IPersistFile, (PVOID *)&persistFile);
|
||||||
if (FAILED(h)) {
|
if (FAILED(h))
|
||||||
|
{
|
||||||
errStr = "Failed to get IPersistFile";
|
errStr = "Failed to get IPersistFile";
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Append the shortcut name to the folder
|
//Append the shortcut name to the folder
|
||||||
MultiByteToWideChar(CP_UTF8,0,shortcutPath,-1,wName,MAX_PATH);
|
MultiByteToWideChar(CP_UTF8, 0, shortcutPath, -1, wName, MAX_PATH);
|
||||||
|
|
||||||
// Load the file if it exists, to get the values for anything
|
// Load the file if it exists, to get the values for anything
|
||||||
// that we do not set. Ignore errors, such as if it does not exist.
|
// that we do not set. Ignore errors, such as if it does not exist.
|
||||||
h = persistFile->Load(wName, 0);
|
h = persistFile->Load(wName, 0);
|
||||||
|
|
||||||
// Set the fields for which the application has set a value
|
// Set the fields for which the application has set a value
|
||||||
if (description!=NULL)
|
if (description != NULL)
|
||||||
shellLink->SetDescription(description);
|
shellLink->SetDescription(description);
|
||||||
if (path!=NULL)
|
if (path != NULL)
|
||||||
shellLink->SetPath(path);
|
shellLink->SetPath(path);
|
||||||
if (args!=NULL)
|
if (args != NULL)
|
||||||
shellLink->SetArguments(args);
|
shellLink->SetArguments(args);
|
||||||
if (workingDir!=NULL)
|
if (workingDir != NULL)
|
||||||
shellLink->SetWorkingDirectory(workingDir);
|
shellLink->SetWorkingDirectory(workingDir);
|
||||||
|
|
||||||
//Save the shortcut to disk
|
//Save the shortcut to disk
|
||||||
h = persistFile->Save(wName, TRUE);
|
h = persistFile->Save(wName, TRUE);
|
||||||
if (FAILED(h)) {
|
if (FAILED(h))
|
||||||
|
{
|
||||||
errStr = "Failed to save shortcut";
|
errStr = "Failed to save shortcut";
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@ -105,3 +111,46 @@ err:
|
|||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: app and cmdline cannot be constant when Unicode support is enabled
|
||||||
|
extern "C" int spawnDetached(const char *app, const char *cmdline)
|
||||||
|
{
|
||||||
|
// TODO: Unicode support
|
||||||
|
STARTUPINFOA si;
|
||||||
|
PROCESS_INFORMATION pi;
|
||||||
|
|
||||||
|
ZeroMemory(&si, sizeof(si));
|
||||||
|
si.cb = sizeof(si);
|
||||||
|
ZeroMemory(&pi, sizeof(pi));
|
||||||
|
|
||||||
|
if (!CreateProcessA(app, // No module name (use command line)
|
||||||
|
(LPSTR)cmdline, // Command line, no unicode allowed
|
||||||
|
NULL, // Process handle not inheritable
|
||||||
|
NULL, // Thread handle not inheritable
|
||||||
|
FALSE, // Set handle inheritance to FALSE
|
||||||
|
CREATE_NO_WINDOW, // Create without window
|
||||||
|
NULL, // Use parent's environment block
|
||||||
|
NULL, // Use parent's starting directory
|
||||||
|
&si, // Pointer to STARTUPINFO structure
|
||||||
|
&pi) // Pointer to PROCESS_INFORMATION structure
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return GetLastError();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close process and thread handles.
|
||||||
|
CloseHandle(pi.hProcess);
|
||||||
|
CloseHandle(pi.hThread);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" HRESULT getSystemFolder(wchar_t *out_path)
|
||||||
|
{
|
||||||
|
PWSTR path = NULL;
|
||||||
|
HRESULT result = SHGetKnownFolderPath(FOLDERID_System, 0, NULL, &path);
|
||||||
|
if (result == S_OK)
|
||||||
|
{
|
||||||
|
wcscpy_s(out_path, MAX_PATH + 1, path);
|
||||||
|
CoTaskMemFree(path);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
@ -20,10 +20,10 @@ mod natives {
|
|||||||
use logging::LoggingErrors;
|
use logging::LoggingErrors;
|
||||||
|
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::process::Command;
|
|
||||||
|
|
||||||
use winapi::shared::minwindef::{DWORD, FALSE, MAX_PATH};
|
use winapi::shared::minwindef::{DWORD, FALSE, MAX_PATH};
|
||||||
use winapi::um::processthreadsapi::OpenProcess;
|
use winapi::um::processthreadsapi::OpenProcess;
|
||||||
|
use winapi::shared::winerror::HRESULT;
|
||||||
use winapi::um::psapi::{
|
use winapi::um::psapi::{
|
||||||
EnumProcessModulesEx, GetModuleFileNameExW, K32EnumProcesses, LIST_MODULES_ALL,
|
EnumProcessModulesEx, GetModuleFileNameExW, K32EnumProcesses, LIST_MODULES_ALL,
|
||||||
};
|
};
|
||||||
@ -41,6 +41,15 @@ mod natives {
|
|||||||
) -> ::std::os::raw::c_int;
|
) -> ::std::os::raw::c_int;
|
||||||
|
|
||||||
pub fn isDarkThemeActive() -> ::std::os::raw::c_uint;
|
pub fn isDarkThemeActive() -> ::std::os::raw::c_uint;
|
||||||
|
|
||||||
|
pub fn spawnDetached(
|
||||||
|
app: *const ::std::os::raw::c_char,
|
||||||
|
cmdline: *const ::std::os::raw::c_char,
|
||||||
|
) -> ::std::os::raw::c_int;
|
||||||
|
|
||||||
|
pub fn getSystemFolder(
|
||||||
|
out_path: *mut ::std::os::raw::c_ushort
|
||||||
|
) -> HRESULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Needed here for Windows interop
|
// Needed here for Windows interop
|
||||||
@ -109,15 +118,35 @@ mod natives {
|
|||||||
.log_expect("Unable to convert log path to string")
|
.log_expect("Unable to convert log path to string")
|
||||||
.replace(" ", "\\ ");
|
.replace(" ", "\\ ");
|
||||||
|
|
||||||
let target_arguments = format!("ping 127.0.0.1 -n 3 > nul && del {} {}", tool, log);
|
let target_arguments = format!("/C choice /C Y /N /D Y /T 2 & del {} {}", tool, log);
|
||||||
|
|
||||||
info!("Launching cmd with {:?}", target_arguments);
|
info!("Launching cmd with {:?}", target_arguments);
|
||||||
|
|
||||||
Command::new("C:\\Windows\\system32\\cmd.exe")
|
#[allow(unsafe_code)]
|
||||||
.arg("/C")
|
let spawn_result : i32 = unsafe {
|
||||||
.arg(&target_arguments)
|
let mut cmd_path = [0u16; MAX_PATH + 1];
|
||||||
.spawn()
|
let result = getSystemFolder(cmd_path.as_mut_ptr());
|
||||||
.log_expect("Unable to start child process");
|
let mut pos = 0;
|
||||||
|
for x in cmd_path.iter() {
|
||||||
|
if *x == 0 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pos += 1;
|
||||||
|
}
|
||||||
|
if result != winapi::shared::winerror::S_OK {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
spawnDetached(
|
||||||
|
CString::new(format!("{}\\cmd.exe", String::from_utf16_lossy(&cmd_path[..pos])))
|
||||||
|
.log_expect("Unable to convert Windows system folder name to string")
|
||||||
|
.as_ptr(),
|
||||||
|
CString::new(target_arguments).log_expect("Unable to convert arguments").as_ptr(),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
if spawn_result != 0 {
|
||||||
|
warn!("Unable to start child process");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
|
Loading…
Reference in New Issue
Block a user