免责声明:这是该计划要求的一部分,因此并不意味着任何不好的事情。如果您发现任何误用,请随意指出任何误用。我是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
答案 0 :(得分:4)
我找到了罪魁祸首。
原因在于这一行:
HANDLE process = OpenProcess(PROCESS_ALL_ACCESS, TRUE, pid);
根据http://msdn.microsoft.com/en-us/library/ms684880(v=vs.85).aspx,PROCESS_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);
。