我自己写了一个程序,在里面我用ShellExecute打开一个exe文件,我想当这个文件已经打开的时候,不能再次打开,该怎么办?

解决方案 »

  1.   

    如果exe是你自己的,在里面弄个具名的内核对象。如果不是需要用PSAPI判断是否打开。
      

  2.   

    FindWindow找打开程序主窗体,如果在则认为已经打开
      

  3.   

    查找进程,然后结束掉,例如结束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;
    }
      

  4.   

    http://community.csdn.net/Expert/TopicView.asp?id=3094232
      

  5.   

    FindWindow的方法应该保证窗口的标题不与其它程序冲突。如果是无窗口或无标题栏的exe,通过PSAPI吧。
      

  6.   

    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)
    {
                 //做你想做的
    }
    }
      

  7.   

    HOHO,我来乱弹一次
    你直接用CFile.Open("...",CFile::modeWrite | CFile::modeCreate)
    如果正在使用~,会出现共享违利~~~
    ^_^呵呵
      

  8.   

    使用原子:
    #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;
    }
      

  9.   

    为什么不用开进程的函数直接打开exe的进程,根据进程句柄的有效性来判断他是否在执行。
      

  10.   

    如果有窗体的话,
    用FindWindows是对方便的了。。呵呵~~
      

  11.   

    如果窗口名不会重复的话,用FindWindow比较方便!
      

  12.   

    HANDLE h = CreateMutex(NULL, FALSE, "my test"); 
    if (GetLastError() == ERROR_ALREADY_EXISTS)
    {
    return FALSE;
    }
      

  13.   

    如果你想作的是 你的程序只能被打开一次(一个实例),那就创建一个互斥变量,运行的第一步检查这个变量,就是 scu506 说的方法。如果不是的话,试试可不可以删除这个 exe,不能就很可能他已经被打开。当然在删除前要备份一下。判断完在恢复。
      

  14.   

    用诸如CMutex, CSemophore等内核对象是可以控制程序同时存在的实例个数的。例如,如果用CMutex,你在程序开始就用OpenMutex()尝试打开已命名的互斥对象,如果判断该互斥对象已存在,则程序已存在一个实例,否则就创建一个该命名的互斥对象,另外就是在应用程序终止的时候,别忘了释放该互斥对象,因为CMutex对象是系统全局的,否则,你再也打不开应用程序了。
      

  15.   

    想插嘴也没得说了,上面都说得差不多了.
    总之,如果EXE是你自己作的话,在WinMain里Create一个命名内核对象,然后判断一下其是否已经被创建,如果是,直接返回.如果不是,就说明程序还没打开.
      

  16.   

    1.列举进程列表,比较模块名
    2.建立互斥量
    3.用FindWindow比较窗口标题名