请问怎样获取多次运行相同程序时,获取上一次的程序句柄。
--其实我的目的是,想程序重启,想等第二个程序启动后再去关闭第一个程序,以免用户等。

解决方案 »

  1.   

    通过对话框标题(GETWINDOWTEXT)去判断,论坛里这种帖子应该有,一查即可
      

  2.   

    当然,如果不是窗口类的进程,去遍历一下PROCINFO一定能成
      

  3.   

    用这个方法吧,遍历所有进程INFO,找到那个名字和自己一样(可执行程序名)但不是自己的进程,杀掉 HANDLE    hSnapShot = NULL;//进程映像
    DWORD myProcID= GetCurrentProcessId(); // 当前进程(自己)的PID

    int iNum;
    CString myCmd =CommandLineToArgvW(GetCommandLine(),&iNum)[0];//得到当前程序命令行的第一个参数
    int iStart = 0;
    int iEnd = 0;
    while (iStart >= 0)
    {
    iEnd = iStart;
    iStart = myCmd.Find(_T("\\"),iStart +1);
    }
    if (myCmd.Find(_T("\\"),0) <0) iEnd = -1;
    myCmd = myCmd.Right(myCmd.GetLength() - iEnd - 1);// 实际运行文件名,不含路径 hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);//获取当前进程快照
    PROCESSENTRY32 prosInfo;//定义PROCESSENTRY32结构
    prosInfo.dwSize = sizeof(prosInfo);//设置PROCESSENTRY32结构大小 BOOL bStatus = Process32First(hSnapShot, &prosInfo);//获得第一个进程的句柄
    while(bStatus)
    {
    CString  scTmp=prosInfo.szExeFile;//获得进程全名
    if (scTmp.CompareNoCase(myCmd) ==0 ) //不区分大小写
    {
    if (prosInfo.th32ProcessID != myProcID) //别杀了自己
    {
    AfxMessageBox( scTmp + _T("--- Kill it ----"));
    HANDLE hProc = OpenProcess(PROCESS_TERMINATE,FALSE,prosInfo.th32ProcessID); //// 得到进程HANDLE
    if (hProc !=NULL)
    if (TerminateProcess(hProc,0)) // 通过HANDLE杀进程
    AfxMessageBox(_T("Killed"));
    else
    AfxMessageBox(_T("Not Killed"));
    }
    }
    bStatus = Process32Next(hSnapShot, &prosInfo);//下一个
    } CloseHandle(hSnapShot);//关闭快照
      

  4.   

    谢谢楼上的,虽然我用你的方法不行,但是我自己搞定了。但是想法是学习的。我使用内存共享,把上一次的进程ID或者查询句柄(往上一次程序发送消息--关闭消息)保存在一个区域内,下一次在读出来,有就关闭再打开 ,没有就直接打开。我也做过查找所有的标题相同的而非自己的也可以,不过不好。还是内存共享好点,我第一次写,可能不好// 获取程序句柄往其发送关闭消息
    BOOL ReStartControl()
    {
    CString strNewTitle;// 当前窗体名
    GetWindowText(strNewTitle); m_hMutex = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, strNewTitle); char* pView = (char*)MapViewOfFile(m_hMutex, FILE_MAP_ALL_ACCESS, 0, 0, 0); if(m_hMutex != NULL)
    {
    CString strTemp;
    strTemp.Format(_T("%s"), pView); int nNum; // 获取句柄字符串的长度(多次运行程序会有用的)
    sscanf_s(strTemp.Mid(0, 2), _T("%d"), &nNum);

    // 存在的句柄
    HWND hWnd;
    // 句柄字符串
    strTemp = strTemp.Mid(2, nNum); sscanf_s(strTemp, _T("%d"), &hWnd); // 发送窗体销毁消息
    ::PostMessage(hWnd, WM_DESTROY, NULL, NULL); UnmapViewOfFile(pView);
    CloseHandle(m_hMutex);
    DWORD lpExitCode;
    GetExitCodeProcess(m_hMutex, &lpExitCode);
    TerminateProcess(m_hMutex, lpExitCode);
    } m_hMutex = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 256, strNewTitle); ::CreateMutex(NULL, TRUE, strNewTitle);
    char* pDestination = (char*)MapViewOfFile(m_hMutex, FILE_MAP_ALL_ACCESS, 0, 0, 0); CString strHwnd;
    strHwnd.Format("%d", m_hWnd); CString strLength; // 句柄转换成字符串后的长度。(多次运行程序会有用的)
    strLength.Format(_T("%02d"), strHwnd.GetLength()); // 保存到内存的最终字符串
    strHwnd = strLength + strHwnd; // 保存窗体句柄
    CopyMemory((PVOID)pDestination, strHwnd, strlen(strHwnd));
    return TRUE;}
    LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
    {
    if (WM_DESTROY == message)
    {
    CDialog::OnClose();
    CDialog::OnCancel();
    }
    return CDialog::WindowProc(message, wParam, lParam);
    }///获取进程,使用关闭进程
    BOOL ReStartControl()
    {
    CString strNewTitle;// 当前窗体名
    GetWindowText(strNewTitle); m_hMutex = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, strNewTitle); char* pView = (char*)MapViewOfFile(m_hMutex, FILE_MAP_ALL_ACCESS, 0, 0, 0); if(m_hMutex != NULL)
    {
    CString strTemp;
    strTemp.Format(_T("%s"), pView); int nNum; // 获取进程ID字符串的长度(多次运行程序会有用的)
    sscanf_s(strTemp.Mid(0, 2), _T("%d"), &nNum);

    // 存在的进程ID
    DWORD dwProcessID; // 进程ID字符串
    strTemp = strTemp.Mid(2, nNum); sscanf_s(strTemp, _T("%d"), &dwProcessID); HANDLE hProc = OpenProcess(PROCESS_TERMINATE, FALSE, dwProcessID); // 得到进程HANDLE UnmapViewOfFile(pView);
    CloseHandle(m_hMutex);
    TerminateProcess(hProc, 0);
    } m_hMutex = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 256, strNewTitle); ::CreateMutex(NULL, TRUE, strNewTitle);
    char* pDestination = (char*)MapViewOfFile(m_hMutex, FILE_MAP_ALL_ACCESS, 0, 0, 0); DWORD myProcID = GetCurrentProcessId(); // 当前进程(自己)的PID CString strProcessID; // 转换为进程字符串
    strProcessID.Format("%d", myProcID); CString strLength; // 进程转换成字符串后的长度。(多次运行程序会有用的)
    strLength.Format(_T("%02d"), strProcessID.GetLength()); // 保存到内存的最终字符串
    strProcessID = strLength + strProcessID; // 保存进程ID
    CopyMemory((PVOID)pDestination, strProcessID, strlen(strProcessID)); return TRUE;
    }
      

  5.   

    内存映射文件当然是一个好办法。还有一个简单的方法是使用共享段。把应用程序实例句柄放在共享段就可以了。关于怎么使用共享段,参考http://hi.baidu.com/chendeping/blog/item/71d2c4ef7731e914fdfa3c25.html