【发布时间】:2017-07-13 12:06:27
【问题描述】:
首先,我是使用 Windows 的 C++ API 的新手,所以我可能缺少一些明显的东西。
我正在尝试在 Windows 的 C++ 中启动提升的子进程。我设法编写了这段代码,它启动了一个提升的子进程,将 2 个参数传递给它,然后子进程会弹出一个带有这些参数的窗口:
#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;
}
}
它大部分都有效,但它会破坏非 ASCII 字符:
我应该改变什么以使其正确处理 unicode?p>
【问题讨论】:
-
你打电话给
ShellExecuteExW或ShellExecuteExA? -
你可以在我调用的代码中看到
ShellExecuteEx -
不,
ShellExecuteEx不存在。这是扩展为ShellExecuteExW或ShellExecuteExA的宏。你需要打电话ShellExecuteExW -
感谢您的提示。我打电话给
ShellExecuteW,当我把它改成ShellExecuteA它工作了。 -
但调用任何 api 的 A 版本 - 糟糕的选择 - 你几乎总是需要调用 W 版本并将宽字符串参数传递给它(蝙蝠不是ansi 字符串)