TerminateProcess 上的 ERROR_INVALID_HANDLE (VS C++)
免责声明:这是该计划要求的一部分,因此并不意味着有什么坏处。如果您发现任何误用,请随时指出。我是 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我找到了罪魁祸首。
原因在于这一行:
根据 http:// /msdn.microsoft.com/en-us/library/ms684880(v=vs.85).aspx,
PROCESS_ALL_ACCESS
对于 Windows XP/NT 系统来说太大,或更多详细信息:当然我是在 7 上编译这个程序,而在 XP 上运行肯定会导致这个问题。
所以解决方案是,将
PROCESS_ALL_ACCESS
更改为PROCESS_TERMINATE
,即完成!
感谢@DReJ 的快速回复:)
I found the culprit.
The reason lies in this line:
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: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
toPROCESS_TERMINATE
, whichDone!
Thanks @DReJ for quick replies :)
我了解到您希望 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.
您的问题可能与这段代码有关
首先,使用
GetExitCodeProcess
您会获得状态STILL_ACTIVE
,之后您会以这种状态终止进程,我认为这是不正确的。从代码中删除GetExitCodeProcess
并尝试使用TerminateProcess(process, 0);
。Your problem maybe related to this piece of code
First, with
GetExitCodeProcess
you get statusSTILL_ACTIVE
and after that you terminate process with this status which is not proper I think. RemoveGetExitCodeProcess
from you code and tryTerminateProcess(process, 0);
instead.