First of all, I'm new to using Windows' C++ API, so there's probably something obvious I'm missing.
I'm trying to start an elevated subprocess in C++ in Windows. I managed to write this code which starts an elevated subprocess, passes 2 arguments to it and then the subprocess pops up a window with those arguments:
#include <shlobj.h>
#include <shlwapi.h>
#include <objbase.h>
#include <string>
#include <QString>
#include <QDebug>
#include <QMessageBox>
#include <QApplication>
auto getWinError()
{
auto dw =GetLastError();
LPTSTR* lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL );
auto str = QString::fromWCharArray(*lpMsgBuf);
LocalFree(*lpMsgBuf);
return str;
}
int main(int argc, char** argv)
{
if (argc == 1){
// start self as admin with 2 arguments
SHELLEXECUTEINFO info = {};
info.cbSize = sizeof(SHELLEXECUTEINFO);
info.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_UNICODE;
info.lpVerb = L"runas";
auto filestr = QString{argv[0]}.toStdWString();
info.lpFile = filestr.c_str();
info.lpParameters = LR"("first parameter" "żółć")";
info.nShow = SW_SHOW;
auto success = ShellExecuteEx(&info);
if (!success || (int)info.hInstApp <= 32){
qDebug()<<getWinError();
return -1;
}
HANDLE handle = info.hProcess;
auto exitCode = [handle]{
DWORD status;
GetExitCodeProcess(handle, &status);
return status;
};
while (exitCode() == STILL_ACTIVE) Sleep(100);
qDebug()<<"process exited with exit code "<<exitCode();
CloseHandle(handle);
return 0;
} else {
// show popup with arguments
QApplication a(argc, argv);
QStringList s;
for (int i = 1; i<argc; i++){
s += argv[i];
}
QMessageBox::information(0, "", s.join('\n'));
return 42;
}
}
It mostly works, but it mangles non-ASCII characters:
What should I change to make it handle unicode correctly?