TerminateProcess 上的 ERROR_INVALID_HANDLE (VS C++)

发布于 2024-10-11 21:04:20 字数 2269 浏览 2 评论 0原文

免责声明:这是该计划要求的一部分,因此并不意味着有什么坏处。如果您发现任何误用,请随时指出。我是 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

Disclaimer: This is part of the requirement of the program, so it's not meant for anything bad. Feel free to point out any misuse if you spot one. I'm a beginner in C++.

Basically, I'm trying to restart Outlook.exe on Windows using C++.

And this is the code I used to restart 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));
    }
}

The funny part is, this piece of code works perfectly fine on Windows 7. While on Windows XP (SP3), I get duplicated Outlook. The GetLastError gives me 6: ERROR_INVALID_HANDLE. I am really clueless after hours of research.

Any idea?

Anyway, C++ is not my field. I do webs :)

And the code above is a mixture of the following sources:

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/

Environment: Windows 7, Windows XP, VS2010, Outlook 2003, Outlook 2007, Outlook 2010

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

折戟 2024-10-18 21:04:20

我找到了罪魁祸首。

原因在于这一行:

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 的快速回复:)

I found the culprit.

The reason lies in this line:

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

According to http://msdn.microsoft.com/en-us/library/ms684880(v=vs.85).aspx, PROCESS_ALL_ACCESS is too large for Windows XP/NT system, or more details:

The size of the PROCESS_ALL_ACCESS flag increased on Windows Server 2008 and Windows Vista. If an application compiled for Windows Server 2008 and Windows Vista is run on Windows Server 2003 or Windows XP/2000, the PROCESS_ALL_ACCESS flag is too large and the function specifying this flag fails with ERROR_ACCESS_DENIED. To avoid this problem, specify the minimum set of access rights required for the operation.

Definitely I'm compiling this program on 7, while running on XP definitely causing the problem.

So the solution is, change the PROCESS_ALL_ACCESS to PROCESS_TERMINATE, which

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

Done!

Thanks @DReJ for quick replies :)

风月客 2024-10-18 21:04:20

我了解到您希望 Outlook 重新启动,但在 Outlook 上调用 TerminateProcess 首先似乎是个坏主意。如果正在写入数据文件怎么办?

更好的方法是找到属于 Outlook 的所有顶级窗口,向它们发送 WM_CLOSE,然后等待进程退出。 (您可能还必须应对用户打开草稿消息的情况,这会导致“您确定吗”提示,尽管如果您首先这样做,那么我假设您知道用户没有在处理某些事情? )

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

I get that you want Outlook to restart but calling TerminateProcess on Outlook seems like a bad idea in the first place. What if it's in the middle of writing a data file?

A better way would be to find all top-level windows that belong to Outlook, send them a WM_CLOSE and then wait for the process to exit. (You may also have to cope with the user having draft messages open which result in "are you sure" prompts, although if you are doing this in the first place then I assume you know the user isn't in the middle of something?)

An even better way would be to use Outlook's automation interface and tell it to shutdown explicitly.

淡紫姑娘! 2024-10-18 21:04:20

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

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

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

Your problem maybe related to this piece of code

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

First, with GetExitCodeProcess you get status STILL_ACTIVE and after that you terminate process with this status which is not proper I think. Remove GetExitCodeProcess from you code and try TerminateProcess(process, 0); instead.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文