TerminateProcess上的ERROR_INVALID_HANDLE(VS C ++)

时间:2011-01-14 11:19:26

标签: c++ windows winapi process outlook

免责声明:这是该计划要求的一部分,因此并不意味着任何不好的事情。如果您发现任何误用,请随意指出任何误用。我是C ++的初学者。

基本上,我正在尝试使用C ++在Windows上重新启动Outlook.exe

这是我用来重启Outlook的代码。

#include <TlHelp32.h>
void RestartOutlook() {
    PROCESSENTRY32 Pc = { sizeof(PROCESSENTRY32) };
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);

    MODULEENTRY32 Mo = {sizeof (MODULEENTRY32) };

    if(Process32First(hSnapshot, &Pc)){
        do{
            if(!_stricmp(Pc.szExeFile, "outlook.exe")) {
                DWORD pid = Pc.th32ProcessID;

                HANDLE hModuleSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid);

                //kill outlook
                HANDLE process = OpenProcess(PROCESS_ALL_ACCESS, TRUE, pid);
                DWORD fdwExit = 0;
                GetExitCodeProcess(process, &fdwExit);
                TerminateProcess(process, fdwExit);

                char * path;
                if (Module32First(hModuleSnapshot, &Mo)) {
                    path = Mo.szExePath;

                    STARTUPINFO si;
                    PROCESS_INFORMATION pi;
                    ZeroMemory(&si, sizeof(si));
                    si.cb = sizeof (si);
                    CreateProcess(path, NULL, NULL, NULL, false, NORMAL_PRIORITY_CLASS,
                        NULL, NULL, &si, &pi);
                }


            }
        }while(Process32Next(hSnapshot, &Pc));
    }
}

有趣的是,这段代码在Windows 7上运行得非常好。在Windows XP(SP3)上,我得到了重复的Outlook。 GetLastError给了我6: ERROR_INVALID_HANDLE。经过数小时的研究,我真的很无能为力。

有什么想法吗?

无论如何,C ++不是我的领域。我做网:)

上面的代码是以下来源的混合:

  

1:http://www.istorya.net/forums/programming/107435-how-can-i-kill-a-process-using-c.html

     

2:http://code.activestate.com/recipes/576362-list-system-process-and-process-information-on-win/

环境:Windows 7,Windows XP,VS2010,Outlook 2003,Outlook 2007,Outlook 2010

3 个答案:

答案 0 :(得分:4)

我找到了罪魁祸首。

原因在于这一行:

HANDLE process = OpenProcess(PROCESS_ALL_ACCESS, TRUE, pid);

根据http://msdn.microsoft.com/en-us/library/ms684880(v=vs.85).aspxPROCESS_ALL_ACCESS对于Windows XP / NT系统来说太大了,或者更多细节:

  

在Windows Server 2008和Windows Vista上,PROCESS_ALL_ACCESS标志的大小增加。如果为Windows Server 2008和Windows Vista编译的应用程序在Windows Server 2003或Windows XP / 2000上运行,则PROCESS_ALL_ACCESS标志太大,并且指定此标志的函数将失败并显示ERROR_ACCESS_DENIED。要避免此问题,请指定操作所需的最小访问权限集。

我肯定在7上编译这个程序,而在XP上运行肯定会导致问题。

所以解决方法是,将PROCESS_ALL_ACCESS更改为PROCESS_TERMINATE,其中

HANDLE process = OpenProcess(PROCESS_TERMINATE, TRUE, pid);

完成!

感谢@DReJ快速回复:)

答案 1 :(得分:2)

我知道你希望Outlook重新启动但是在Outlook上调用TerminateProcess似乎是一个坏主意。如果它正在编写数据文件的中间怎么办?

更好的方法是找到属于Outlook的所有顶级窗口,向它们发送WM_CLOSE,然后等待进程退出。 (您可能还必须应对打开草稿消息的用户,这会导致“您确定”提示,但如果您首先执行此操作,那么我假设您知道用户不在某事物的中间? )

更好的方法是使用Outlook的自动化界面并告诉它明确关闭。

答案 2 :(得分:1)

你的问题可能与这段代码有关

DWORD fdwExit = 0;
GetExitCodeProcess(process, &fdwExit);
TerminateProcess(process, fdwExit);

首先,使用GetExitCodeProcess,您将获得状态STILL_ACTIVE,之后您将以此状态终止进程,我认为这是不正确的。从代码中删除GetExitCodeProcess,然后尝试使用TerminateProcess(process, 0);