HANDLE   hSem   =   CreateSemaphore(NULL,   1,   1,   "只能开一个");     
while( GetLastError() ==  ERROR_ALREADY_EXISTS)
{
AfxMessageBox("已启动一个程序!"   ,  MB_ICONINFORMATION|MB_OK);
// 能否通过信号量找到创建该信号量的进程,并激活到最前面显示???
return FALSE;
}

解决方案 »

  1.   

    OpenSemaphore()函数即可用来根据信号 量名打开在其他进程中创建的信号量,函数原型如下:
    HANDLE OpenSemaphore(
    DWORD dwDesiredAccess, // 访问标志
    BOOL bInheritHandle, // 继承标志
    LPCTSTR lpName // 信号量名
    ); 
      

  2.   


    HANDLE   hSem   =   CreateSemaphore(NULL,   1,   1,   "1111");     
    if( GetLastError() ==  ERROR_ALREADY_EXISTS)
    {
    HWND hwnd=FindWindow("#32770", NULL);
    if (IsWindow(hwnd))
    {
    AfxMessageBox("getit");
    } LRESULT hr = SendMessage(hwnd, WM_CLOSE, 0, 0);
    BOOL bSuccess = DestroyWindow(hwnd); 

    find成功:getit 弹出message对话框我试着关闭他,但是失败了 sendmessage的LResult为0,证明发送成功; bSuccess为0,销毁失败。
    激活到前面的消息估计会有类同的结果
      

  3.   

    DestroyWindow当然会失败,DestroyWindow只对当前线程的窗口有效
    如果你的窗口类不是自己建的,就不要用这种方法
    使用其他方法来进程间通信,比如mailslot
      

  4.   

    可以这样终止进程:if(GetWindowThreadProcessId(hWnd,   &ProcessID) !=0)
    {
    hProcess=OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessID);
            TerminateProcess(hProcess,   0);
    }
      

  5.   

    HWND hwnd=FindWindow("#32770", NULL);请问一下,此句是否会导致找到的不是自己期望的窗口啊。#32770,似乎好多对话框都是这个类名!?
      

  6.   

    有什么API可以通过process handle取到程序所在的路径?  
    初步想法是 通过判断该程序路径下的是否有特定文件去反证取得的窗口是我所期望的。
      

  7.   

    http://topic.csdn.net/u/20120303/23/1be6efdf-02af-491a-b8da-e55b8abf64d5.html
      

  8.   

    大概这么处理了一下HANDLE   hSem   =   CreateSemaphore(NULL,   1,   1,   "xxxxxx");     
    if( GetLastError() ==  ERROR_ALREADY_EXISTS)
    {
    //  通过类名找到进程
    HWND hWnd=FindWindow("#32770", NULL);
    while (IsWindow(hWnd))
    {
    if(GetWindowThreadProcessId(hWnd,   &ProcessID) !=0)
    {
    hProcess=OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessID);
    char strFileName[256];
    if ( GetModuleFileNameEx(hProcess, NULL, strFileName, 256)  != 0)
    {
    // 进程全路径
    CString strPath;
    strPath.Format("%s", strFileName);
    int   nPos =strPath.ReverseFind( '\\');
    strPath=strPath.Left(nPos); 

    CString  strxxxFile  =   strPath + "\\xxxx.dll";
    if ( PathFileExists(strxxxFile) )  // 文件存在
    {
    //然后kill掉进程并退出循环
    TerminateProcess(hProcess,   0);
    break;
    }
    }
    hWnd=FindWindow("#32770", NULL);
    }
    }
    }
      

  9.   

    GetModuleFileNameEx 在64位操作系统上可能有问题,最好还是使用 GetProcessImageFileName获取到DOS格式的盘符路径,如"\Device\HarddiskVolume1\Windows\system32\notepad.exe",然后再进行转换。
      

  10.   

    用findwindows不合适,最好还是用enumwindowBOOL CALLBACK EnumWindowsProc(HWND hwnd,LPARAM lParam)
    {
        //窗口是否可视
        if (!IsWindowVisible(hwnd))
            return TRUE;    //窗口是否可激活
        if (!IsWindowEnabled(hwnd))
            return TRUE;    //窗口是否 WS_POPUP 与 WS_CAPTION 共存
            //一些可切换的窗体同时具有 WS_POPUP 与 WS_CAPTION,因而有 WS_POPUP 却无 WS_CAPTION 的应被过滤
        //据 Spy++ 观察,符合如 OneNote TrayIcon 等程序可通过此方式过滤
         LONG gwl_style = GetWindowLong(hwnd,GWL_STYLE);
        if ((gwl_style & WS_POPUP) && !(gwl_style & WS_CAPTION))
            return TRUE;    //窗口是否具有父窗口?
         HWND hParent = (HWND)GetWindowLong(hwnd,GWL_HWNDPARENT);
        //父窗口是否可激活?
        //据 Spy++ 观察,如“运行”对话框等被应列入列表的程序有一个隐藏的,具有 WS_DISABLED 的父窗口
        if (IsWindowEnabled(hParent))
            return TRUE;
        //父窗口是否可视?
        if (IsWindowVisible(hParent))
            return TRUE;    //一个非常奇怪的问题在于,任务栏 Shell_TrayWnd 符合上述过滤条件但是无法被过滤。
            //因而在这里单独列出。
         TCHAR szClassName[MAX_LOADSTRING];
         GetClassName(hwnd,szClassName,MAX_LOADSTRING);
        if (!wcscmp(szClassName,L"Shell_TrayWnd"))
            return TRUE;