Qt学习笔记:清除用QAxObject创建的Office进程

2 篇文章 0 订阅

环境

系统:Windows10 64位 家庭中文版
Qt版本:5.6.0 msvc2013 32位
编译器:Visual Studio 2013 专业版

目的

在Qt中,当程序非正常关闭时,用QAxObject创建的Office进程不会随着程序的关闭而关闭,导致进程残留。我们需要及时地清理这些进程,注意:不能不加区分地清理Office的进程,因为Office进程有可能是Qt程序创建的也有可能是Office本身创建的。

步骤

1.获取残留的Office进程的Pid,关键代码:

//根据进程名获取pid
QList<int> Widget::getListPidByName(const char *strName)
{
    QList<int> lstPid;
    HANDLE hProcess;
    PROCESSENTRY32 processEntry;
    processEntry.dwSize = sizeof(PROCESSENTRY32);
    BOOL bRet;
    //进行进程快照
    hProcess = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); //TH32CS_SNAPPROCESS快照所有进程
    //开始进程查找
    bRet = Process32First(hProcess, &processEntry);
    //循环比较,得出ProcessID
    while(bRet)
    {
        QString temp = QString::fromWCharArray(processEntry.szExeFile);
        if(strcmp(strName, temp.toLocal8Bit()) == 0)
        {
            lstPid.append(processEntry.th32ProcessID);
        }
        bRet = Process32Next(hProcess, &processEntry);
    }
    return lstPid;
}

2.根据进程的Pid获取父Pid,关键代码:

//根据进程的Pid获取父Pid
DWORD Widget::getParentPidByPid(DWORD dwProcessId)
{
    LONG                        status = -1;
    DWORD                       dwParentPid = (DWORD)-1;
    HANDLE                      hProcess = NULL;
    PROCESS_BASIC_INFORMATION   processBasicInformation;

    PROCNTQSIP NtQueryInformationProcess = (PROCNTQSIP) GetProcAddress(
                GetModuleHandle(L"ntdll"), "NtQueryInformationProcess");

    if (NULL == NtQueryInformationProcess)
    {
        return (DWORD)-1;
    }
    // Get process handle
    hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwProcessId);
    if (!hProcess)
    {
        return (DWORD)-1;
    }

    // Retrieve information
    status = NtQueryInformationProcess(hProcess,
                                       ProcessBasicInformation,
                                       (PVOID)&processBasicInformation,
                                       sizeof(PROCESS_BASIC_INFORMATION),
                                       NULL
                                       );

    //注意:这里要用32位的编译器,64位的编译器得到的不是0而是 -1073741820
    if (!status)
    {
        dwParentPid = processBasicInformation.InheritedFromUniqueProcessId;
    }

    CloseHandle(hProcess);

    return dwParentPid;
}

3.根据父Pid来决定要不要杀死这个进程,关键代码:

//杀死进程
void Widget::killProcess(const QList<int> &lstSubPid, const QList<int> &lstParentPid)
{
    int nParentPid = -1;
    //遍历子进程
    for (int i = 0; i < lstSubPid.count(); ++i)
    {
        //获取子进程的父进程
        nParentPid = getParentPidByPid(lstSubPid.at(i));
        //如果这个进程是由某个父进程创建的,则杀死
        if (lstParentPid.contains(nParentPid))
        {
            HANDLE hProcess = NULL;
            //打开目标进程
            hProcess = OpenProcess(PROCESS_TERMINATE,FALSE, lstSubPid.at(i));
            if (hProcess == NULL)
            {
                qDebug()<<"Open Process fAiled ,error:"<<GetLastError();
            }
            //结束目标进程
            DWORD ret = TerminateProcess(hProcess,0);
            if(ret == 0)
            {
                qDebug()<<"kill task faild,error:"<<GetLastError();
            }
            else
            {
                qDebug()<<"kill task success ------------------------------------------------";
            }
        }
    }
}

注意:这里这样做的原因是:用QAxObject创建的Office进程的父进程和用Office创建的Office进程的父进程不是同一个进程。
示例源码

  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
Qt中使用QAxObject创建Excel文件的步骤如下: 首先,确保你已经安装了Microsoft Office软件,并且拥有Excel的许可证。 然后,你需要在Qt项目中添加以下代码段: ```cpp #include <QAxObject> ... QAxObject* excel = new QAxObject("Excel.Application", this); // 创建Excel应用程序对象 excel->dynamicCall("SetVisible(bool)", false); // 设置Excel应用程序不可见 QAxObject* workbooks = excel->querySubObject("Workbooks"); // 获取工作簿集合对象 QAxObject* workbook = workbooks->querySubObject("Add"); // 创建新工作簿 QAxObject* worksheets = workbook->querySubObject("Worksheets"); // 获取工作表集合对象 QAxObject* worksheet = worksheets->querySubObject("Item(int)", 1); // 获取第一个工作表 QAxObject* cells = worksheet->querySubObject("Cells"); // 获取单元格集合对象 // 在A1单元格中写入数据 QAxObject* cell = cells->querySubObject("Item(int,int)", 1, 1); cell->dynamicCall("SetValue(const QVariant&)", "Hello, Excel!"); workbook->dynamicCall("SaveAs(const QString&)", "C:/path/to/excel.xlsx"); // 保存工作簿 workbook->dynamicCall("Close()"); // 关闭工作簿 excel->dynamicCall("Quit()"); // 退出Excel应用程序 ``` 上述代码中,我们使用QAxObject创建Excel应用程序对象、工作簿、工作表、单元格等。你可以根据需要进行更多的操作,比如设置单元格格式、写入更多数据等。 最后,记得在结束程序前释放资源,可以在程序退出时执行以下代码: ```cpp delete excel; ``` 请确保将代码中的文件路径替换为你希望保存Excel文件的路径。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值