来自ShellExecuteEx的意外/不一致行为 我创建了一个自配置的软件工具,在QualC++(2015)中使用QT来运行其他第三方安装程序。当软件发现它需要不可用的库或驱动程序时,它将使用ShellExecuteEx调用相应的安装程序以打开相应的可执行文件
如果只需要安装一件东西(ShellExecuteEx只运行一次),那么一切都会正常运行。如果两个东西需要同时安装,那么大约25%的时间,一次安装程序将正确运行,另一个将打开包含可执行文件的文件夹,而不是运行可执行文件。对于是否正确运行第一个或第二个操作,没有一致性 ShellExecuteEx声称在这两种情况下都正确运行(返回true)。我已经验证了每次都提供了可执行文件(和工作目录)的正确路径。我尝试在ShellExecuteEx中同时使用动词“open”和“NULL”,但没有改变行为 如果有必要,两个可执行文件都请求管理权限。当一切正常时,他们都会如期完成。当一个失败时,它不会要求管理员权限 我找不到任何有类似问题的人的记录,这可能意味着我在某些基本方面滥用了ShellExecuteEx,但我没有看到它。提前感谢您的任何建议或建议 代码如下:来自ShellExecuteEx的意外/不一致行为 我创建了一个自配置的软件工具,在QualC++(2015)中使用QT来运行其他第三方安装程序。当软件发现它需要不可用的库或驱动程序时,它将使用ShellExecuteEx调用相应的安装程序以打开相应的可执行文件,c++,winapi,visual-c++,shellexecuteex,C++,Winapi,Visual C++,Shellexecuteex,如果只需要安装一件东西(ShellExecuteEx只运行一次),那么一切都会正常运行。如果两个东西需要同时安装,那么大约25%的时间,一次安装程序将正确运行,另一个将打开包含可执行文件的文件夹,而不是运行可执行文件。对于是否正确运行第一个或第二个操作,没有一致性 ShellExecuteEx声称在这两种情况下都正确运行(返回true)。我已经验证了每次都提供了可执行文件(和工作目录)的正确路径。我尝试在ShellExecuteEx中同时使用动词“open”和“NULL”,但没有改变行为 如果有
if(dummy1Required && !dummy1Present){
SHELLEXECUTEINFOA execinfo = {};
execinfo.cbSize = sizeof(SHELLEXECUTEINFOA);
execinfo.fMask = NULL;
execinfo.hwnd = NULL;
execinfo.lpVerb = NULL;
execinfo.lpFile = QDir::toNativeSeparators(QCoreApplication::applicationDirPath() + "/Drivers/dummy1/install.bat").toLocal8Bit().data();
execinfo.lpParameters = NULL;
execinfo.lpDirectory = QDir::toNativeSeparators(QCoreApplication::applicationDirPath() + "/Drivers/dummy1").toLocal8Bit().data();
printf("Dummy1 Executing: %s\n In directory:%s\n", QDir::toNativeSeparators(QCoreApplication::applicationDirPath() + "/Drivers/dummy1/install.bat").toLocal8Bit().data(), QDir::toNativeSeparators(QCoreApplication::applicationDirPath() + "/Drivers/dummy1").toLocal8Bit().data());
fflush(stdout);
execinfo.nShow = SW_SHOW;
execinfo.hInstApp = NULL;
execinfo.fMask = execinfo.fMask | SEE_MASK_NOCLOSEPROCESS;
if(ShellExecuteExA(&execinfo)){
WaitForSingleObject(execinfo.hProcess,INFINITE);
CloseHandle(execinfo.hProcess);
}else{
printf("Failed to launch dummy1 installer because...%lu\n", GetLastError());
fflush(stdout);
}
}
if(dummy2Required && !dummy2Present){
SHELLEXECUTEINFOA execinfo = {};
execinfo.cbSize = sizeof(SHELLEXECUTEINFOA);
execinfo.fMask = NULL;
execinfo.hwnd = NULL;
execinfo.lpVerb = NULL;
execinfo.lpFile = QDir::toNativeSeparators(QCoreApplication::applicationDirPath() + "/Drivers/dummy2/setup.exe").toLocal8Bit().data();
execinfo.lpParameters = "setupParamters.ini /qb /acceptlicenses y /norestart";
execinfo.lpDirectory = QDir::toNativeSeparators(QCoreApplication::applicationDirPath() + "/Drivers/dummy2").toLocal8Bit().data();
printf("Dummy2 Executing: %s\n In directory:%s\n", QDir::toNativeSeparators(QCoreApplication::applicationDirPath() + "/Drivers/dummy2/setup.exe").toLocal8Bit().data(), QDir::toNativeSeparators(QCoreApplication::applicationDirPath() + "/Drivers/dummy2").toLocal8Bit().data());
fflush(stdout);
execinfo.nShow = SW_SHOW;
execinfo.hInstApp = NULL;
execinfo.fMask = execinfo.fMask | SEE_MASK_NOCLOSEPROCESS;
if(ShellExecuteExA(&execinfo)){
WaitForSingleObject(execinfo.hProcess,INFINITE);
CloseHandle(execinfo.hProcess);
}else{
printf("Failed to launch dummy2 installer because...%lu\n", GetLastError());
fflush(stdout);
}
}
编辑:我错了。如果只运行一个可执行文件,我会观察到这种行为,因此它与运行两个操作没有内在联系
编辑2:PaulMckenzie指出我没有正确初始化结构,这很尴尬。不幸的是,修复它并没有改变行为。不过,谢谢 发布的代码中至少有两处错误
if(dummy1Required && !dummy1Present){
SHELLEXECUTEINFOA execinfo; // <-- Uninitialized
...
}
if(dummy2Required && !dummy2Present){
SHELLEXECUTEINFOA execinfo; // <-- Uninitialized
...
}
if(dummy1Required&!dummy1Present){
ShellExecuteInfo执行信息;//有一件事您没有做,那就是确保在使用前将结构(如ShellExecuteInfo
)归零。您永远不应该使用未初始化的结构,设置一些成员,然后再使用它。WinAPI调用很可能使用了未设置成员的垃圾值。ShellExecuteInfo执行信息={};
--这将自动将结构置零。如果这样做,函数是否一致工作?在C中,可以使用={0};