• 12700阅读
  • 14回复

[提问]ShellExecute打开exe文件问题 [复制链接]

上一主题 下一主题
离线yzpdsg
 

只看楼主 倒序阅读 楼主  发表于: 2011-08-22
我的系统是win7,使用QProcess打开程序时被UAC所组,提示"Process failed to start: 请求的操作需要提升。"
上网看了一下,需要使用ShellExecute来打开exe文件。可是我打开时总是返回0x2(ERROR_FILE_NOT_FOUND = 2; {文件名错误})
代码如下:

    QDir dir(programToStart);//programToStart="D:/G_Soft/AeroTimer/AeroTimer.exe"
    QString e = "open";
    wchar_t *operation = new wchar_t[e.size() + 1];
    e.toWCharArray(operation);

    e = dir.dirName();//e=AeroTimer.exe
    wchar_t *fileNameToOpen = new wchar_t[e.size() + 1];
    e.toWCharArray(fileNameToOpen);

    e = programToStart.remove(dir.dirName());//e="D:/G_Soft/AeroTimer/"
    wchar_t *openDirectory = new wchar_t[e.size() + 1];
    e.toWCharArray(openDirectory);
    qDebug()<<ShellExecute(NULL,operation,fileNameToOpen,NULL,openDirectory,SW_SHOWNORMAL);

我Debug了一下,发现*operation=111,*openDirectory=61571,*fileNameToOpen=110。不是我想要的字符串。是我转换时出问题了么?
离线wxj120bw

只看该作者 1楼 发表于: 2011-08-23
回 楼主(yzpdsg) 的帖子
ERROR_FILE_NOT_FOUND 文件没有找到 应该路径或者文件名出错 不过还是建议用QProcess 关闭UAC或者找其他绕过UAC方法
离线yzpdsg

只看该作者 2楼 发表于: 2011-08-23
回 1楼(wxj120bw) 的帖子
我不知道转换的结果是不是原来的值,即不知道转换结果是否正确。    
QString e = "open";
wchar_t *operation = new wchar_t[e.size() + 1];
e.toWCharArray(operation);
这样转换后operation里的值应该是open吧?为什么是111呢?
离线wxj120bw

只看该作者 3楼 发表于: 2011-08-23
回 3楼(yzpdsg) 的帖子
你用QString::toStdWString()函数尝试下
离线yzpdsg

只看该作者 4楼 发表于: 2011-08-23
回 4楼(wxj120bw) 的帖子
QString::toStdWString()的返回值是std::wstring,shellexecute()所需的参数是wchar_t*,我不懂如何转换。

刚才又摸索了一下,翻看stackoverflow的一篇帖子http://stackoverflow.com/questions/4526787/qprocessstartdetached-blocked-by-uac-running-an-updater

解决了。最后的代码是这样:

    QDir dir(programToStart);
    QString e = "runas";//这里按照文档写成open就会报0x2错误,不知为何。
    wchar_t *operation = new wchar_t[e.size() + 1];
    wchar_t *starter = new wchar_t[programToStart.size() + 1];
    programToStart.toWCharArray(starter);
    qDebug()<<ShellExecute(NULL,operation,starter,NULL,NULL,SW_SHOWNORMAL);

谢谢回复!

离线yzpdsg

只看该作者 5楼 发表于: 2011-08-23
回 4楼(wxj120bw) 的帖子
碰到了一个更加费解的问题:QProcess又可以触发UAC了。。。
就是说,通过QProcess来运行也会弹出UAC确认框而不是直接被拒绝了,这让我有点摸不着头脑了。莫非stackoverflow中提到的BUG是偶尔才出现的么?
离线wxj120bw

只看该作者 6楼 发表于: 2011-08-23
回 6楼(yzpdsg) 的帖子
UAC是用win7的户权限控制 可以关闭这个 用QProcess就不会遇到问题了 还有bug是什么
离线yzpdsg

只看该作者 7楼 发表于: 2011-08-23
回 7楼(wxj120bw) 的帖子
可是不太想关闭UAC
bug是这个https://bugreports.qt.nokia.com//browse/QTBUG-9761
离线wxj120bw

只看该作者 8楼 发表于: 2011-08-24
回 8楼(yzpdsg) 的帖子
看bug描述 在win7下双击程序 有时提示需要管理员的权限  那QProcess也需要这样的权限 因该总是弹出该对话框 没什么问题
离线yzpdsg

只看该作者 9楼 发表于: 2011-08-24
回 9楼(wxj120bw) 的帖子
我的意思大概是这样:

昨天我使用QProcess时是无法触发UAC对话框的,进程只会被粗暴的拒绝执行。
今天可能是使用了ShellExecute()的原因,QProcess启动的昨天被拒绝的同样的进程则可以触发UAC对话框了。
离线wxj120bw

只看该作者 10楼 发表于: 2011-08-24
回 10楼(yzpdsg) 的帖子
你尝试下重启电脑 再用QProcess运行 估计会被粗暴的拒绝执行
离线yzpdsg

只看该作者 11楼 发表于: 2011-08-24
回 11楼(wxj120bw) 的帖子
重启了,QProcess还是可以触发UAC。为了以防万一,我把代码改成 了下面这样:

    QProcess *p = new QProcess;
    p->start("\"" + programToStart + "\"");
    if(p->error() == QProcess::FailedToStart)
    {
        //如果因UAC的原因导致运行失败,则使用WINAPI再次尝试
        QString e = "runas";//这里不是doc中的open,必须是runas
        wchar_t *operation = new wchar_t[e.size() + 1];
        wchar_t *starter = new wchar_t[programToStart.size() + 1];
        programToStart.toWCharArray(starter);
        int result = (int)ShellExecute(NULL,operation,starter,NULL,NULL,SW_SHOWNORMAL);
        if(result < 32)//“If the function succeeds, it returns a value greater than 32.”
        {
            QMessageBox msgBox;
            msgBox.setText(tr("打开程序失败。"));
        }
    }
离线wxj120bw

只看该作者 12楼 发表于: 2011-08-24
回 12楼(yzpdsg) 的帖子
这个是不错的处理
离线roywillow

只看该作者 13楼 发表于: 2011-08-24
QString::toStdWString()返回std::string后,再用c_str()函数然后或许还要配合一下强制类型转换,就能出来wchar_t*了
之前在调用一些winapi的时候发现的
专业维修核潜艇,回收二手航母、二手航天飞机,大修核反应堆,拆洗导弹发动机更换机油,无人侦察机手动挡改自动,航天飞机保养换三滤,飞碟外太空年检 ,各型号导弹加装迎宾踏板,高空作业擦洗卫星表面除尘、打蜡及抛光,东风全系列巡航导弹。并提供原子对撞机。量大从优,有正规发票。
离线yzpdsg

只看该作者 14楼 发表于: 2011-08-25
回 14楼(roywillow) 的帖子
哦,谢谢!
快速回复
限100 字节
 
上一个 下一个