怎么判断一个exe文件已经打开? 我自己写了一个程序,在里面我用ShellExecute打开一个exe文件,我想当这个文件已经打开的时候,不能再次打开,该怎么办? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 如果exe是你自己的,在里面弄个具名的内核对象。如果不是需要用PSAPI判断是否打开。 FindWindow找打开程序主窗体,如果在则认为已经打开 查找进程,然后结束掉,例如结束QQ#include <Afxtempl.h> //CArray类需要的头文件UINT KillProgram(LPVOID lpvoid);CArray<PROCESSENTRY32,PROCESSENTRY32 &> m_PEArray;//在进程列表中查找需要杀掉的程序,杀掉这个程序UINT KillProgram(LPVOID lParam){ while(1) { m_PEArray.RemoveAll(); HANDLE hProcessSnap=NULL; PROCESSENTRY32 pe32; hProcessSnap=::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); pe32.dwSize=sizeof(PROCESSENTRY32); if(::Process32First(hProcessSnap,&pe32)) { do { m_PEArray.Add(pe32); } while(::Process32Next(hProcessSnap,&pe32)); } int i; for(i=0;i<m_PEArray.GetSize();i++) { CString str; str.Format("%s",m_PEArray.GetAt(i).szExeFile); if(str.Find("QQ")!=-1) { HANDLE hProcess; DWORD ProcessID; ProcessID=m_PEArray.GetAt(i).th32ProcessID; hProcess=::OpenProcess(PROCESS_ALL_ACCESS,FALSE,ProcessID); ::TerminateProcess(hProcess,99); CloseHandle(hProcess); } } Sleep(500); } return 0;} http://community.csdn.net/Expert/TopicView.asp?id=3094232 FindWindow的方法应该保证窗口的标题不与其它程序冲突。如果是无窗口或无标题栏的exe,通过PSAPI吧。 void CInstallUserDLLApp::FindProgram(CString strExeName){ CString strExeNameToFind = strExeName; HANDLE SnapShot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); if(SnapShot==NULL) { //MessageBox("检测当前进程失败!"); return ; } SHFILEINFO shSmall; CString str,strTemp; PROCESSENTRY32 ProcessInfo;//声明进程信息变量 ProcessInfo.dwSize=sizeof(ProcessInfo);//设置ProcessInfo的大小 //返回系统中第一个进程的信息 BOOL Status=Process32First(SnapShot,&ProcessInfo); int m_nProcess=0; DWORD m_ProcessID=0; while(Status) { m_nProcess++; ZeroMemory(&shSmall,sizeof(shSmall)); //获取进程文件信息 SHGetFileInfo(ProcessInfo.szExeFile,0,&shSmall, sizeof(shSmall),SHGFI_ICON|SHGFI_SMALLICON); //在列表控件中添加映像名称 strTemp=ProcessInfo.szExeFile; strTemp.MakeUpper(); strExeNameToFind.MakeUpper(); if(strTemp.Find(strExeNameToFind,0) >= 0) { m_ProcessID=ProcessInfo.th32ProcessID; break; } //获取下一个进程的信息 Status=Process32Next(SnapShot,&ProcessInfo); } // TODO: Add extra validation here if(m_ProcessID!=0) { //做你想做的 }} HOHO,我来乱弹一次你直接用CFile.Open("...",CFile::modeWrite | CFile::modeCreate)如果正在使用~,会出现共享违利~~~^_^呵呵 使用原子:#define AtomName "MyProgramNameAtom" //这个字串可以自己取,尽量取得特殊些int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){ ATOM Atom; // 程序一开始,判断原子是否存在 if (GlobalFindAtom(AtomName)) return 1; // 程序已经运行,这儿直接退出 Atom = GlobalAddAtom(AtomName); //...... 你的代码 // 程序退出前,删除原子 GlobalDeleteAtom(Atom); return 1;} 为什么不用开进程的函数直接打开exe的进程,根据进程句柄的有效性来判断他是否在执行。 如果有窗体的话,用FindWindows是对方便的了。。呵呵~~ 如果窗口名不会重复的话,用FindWindow比较方便! HANDLE h = CreateMutex(NULL, FALSE, "my test"); if (GetLastError() == ERROR_ALREADY_EXISTS) { return FALSE; } 如果你想作的是 你的程序只能被打开一次(一个实例),那就创建一个互斥变量,运行的第一步检查这个变量,就是 scu506 说的方法。如果不是的话,试试可不可以删除这个 exe,不能就很可能他已经被打开。当然在删除前要备份一下。判断完在恢复。 用诸如CMutex, CSemophore等内核对象是可以控制程序同时存在的实例个数的。例如,如果用CMutex,你在程序开始就用OpenMutex()尝试打开已命名的互斥对象,如果判断该互斥对象已存在,则程序已存在一个实例,否则就创建一个该命名的互斥对象,另外就是在应用程序终止的时候,别忘了释放该互斥对象,因为CMutex对象是系统全局的,否则,你再也打不开应用程序了。 想插嘴也没得说了,上面都说得差不多了.总之,如果EXE是你自己作的话,在WinMain里Create一个命名内核对象,然后判断一下其是否已经被创建,如果是,直接返回.如果不是,就说明程序还没打开. 1.列举进程列表,比较模块名2.建立互斥量3.用FindWindow比较窗口标题名 vc++ 中 资源文件 .rc 里面中文乱码 分不够 - - 一个帖子问两个问题了 ListCtrl+CheckBox问题 怎么样去组织各个应用程序 两个紧急的MFC问题!!!!(请进来指教下) 急问:怎么样在vc中实现套打?? 求教高手:一个新手对多线程的几点疑惑,请不吝指点,不胜感激! 求教:怎样将SDI窗口的白色背景改为其它颜色? 讨论:如何自定义类window标准的打开、保存等标准对话框。 InstallShield怎能将两个软件打成一个包? 能用activex控件实现这样的功能么? 怎样模拟点击系统菜单?
#include <Afxtempl.h> //CArray类需要的头文件UINT KillProgram(LPVOID lpvoid);
CArray<PROCESSENTRY32,PROCESSENTRY32 &> m_PEArray;
//在进程列表中查找需要杀掉的程序,杀掉这个程序
UINT KillProgram(LPVOID lParam)
{
while(1)
{
m_PEArray.RemoveAll();
HANDLE hProcessSnap=NULL;
PROCESSENTRY32 pe32;
hProcessSnap=::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
pe32.dwSize=sizeof(PROCESSENTRY32);
if(::Process32First(hProcessSnap,&pe32))
{
do
{
m_PEArray.Add(pe32);
}
while(::Process32Next(hProcessSnap,&pe32));
}
int i;
for(i=0;i<m_PEArray.GetSize();i++)
{
CString str;
str.Format("%s",m_PEArray.GetAt(i).szExeFile);
if(str.Find("QQ")!=-1)
{
HANDLE hProcess;
DWORD ProcessID;
ProcessID=m_PEArray.GetAt(i).th32ProcessID;
hProcess=::OpenProcess(PROCESS_ALL_ACCESS,FALSE,ProcessID);
::TerminateProcess(hProcess,99);
CloseHandle(hProcess);
}
}
Sleep(500);
}
return 0;
}
{
CString strExeNameToFind = strExeName;
HANDLE SnapShot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
if(SnapShot==NULL)
{
//MessageBox("检测当前进程失败!");
return ;
}
SHFILEINFO shSmall;
CString str,strTemp;
PROCESSENTRY32 ProcessInfo;//声明进程信息变量
ProcessInfo.dwSize=sizeof(ProcessInfo);//设置ProcessInfo的大小
//返回系统中第一个进程的信息
BOOL Status=Process32First(SnapShot,&ProcessInfo);
int m_nProcess=0;
DWORD m_ProcessID=0;
while(Status)
{
m_nProcess++;
ZeroMemory(&shSmall,sizeof(shSmall));
//获取进程文件信息
SHGetFileInfo(ProcessInfo.szExeFile,0,&shSmall,
sizeof(shSmall),SHGFI_ICON|SHGFI_SMALLICON);
//在列表控件中添加映像名称
strTemp=ProcessInfo.szExeFile;
strTemp.MakeUpper();
strExeNameToFind.MakeUpper();
if(strTemp.Find(strExeNameToFind,0) >= 0)
{
m_ProcessID=ProcessInfo.th32ProcessID;
break;
}
//获取下一个进程的信息
Status=Process32Next(SnapShot,&ProcessInfo);
}
// TODO: Add extra validation here
if(m_ProcessID!=0)
{
//做你想做的
}
}
你直接用CFile.Open("...",CFile::modeWrite | CFile::modeCreate)
如果正在使用~,会出现共享违利~~~
^_^呵呵
#define AtomName "MyProgramNameAtom" //这个字串可以自己取,尽量取得特殊些
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
ATOM Atom;
// 程序一开始,判断原子是否存在
if (GlobalFindAtom(AtomName))
return 1; // 程序已经运行,这儿直接退出
Atom = GlobalAddAtom(AtomName);
//...... 你的代码
// 程序退出前,删除原子
GlobalDeleteAtom(Atom); return 1;
}
用FindWindows是对方便的了。。呵呵~~
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
return FALSE;
}
总之,如果EXE是你自己作的话,在WinMain里Create一个命名内核对象,然后判断一下其是否已经被创建,如果是,直接返回.如果不是,就说明程序还没打开.
2.建立互斥量
3.用FindWindow比较窗口标题名