65.9K
CodeProject 正在变化。 阅读更多。
Home

如何检查应用程序是否已在运行

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.86/5 (11投票s)

2009年3月27日

CPOL

1分钟阅读

viewsIcon

87119

如何确定应用程序是否已经在运行并切换到它。

引言

为了我自己的一个项目,我需要检查每次用户启动应用程序时,相同的应用程序是否已经在运行。如果应用程序已经在运行,则必须将其切换到前台,并关闭当前启动的进程。

使用代码

我使用的是 Visual C++ 9.0 标准版,项目类型是 MFC。我们将使用来自 <tlhelp32.h> 的函数。我使用的是 WinXP。

在您的资源的字符串表中,您必须有一个 ID 为 AFX_IDS_APP_TITLE 的字符串。

它必须包含您的可执行文件的应用程序名称,不带 .exe。例如,如果您的可执行文件名为“frTKO.exe”,则字符串资源必须为“frTKO”。

首先,我们将包含必要的头文件。

#include <tlhelp32.h>

执行此操作的函数如下

// Checks, if an application with this name is running
//
// bShow ..... TRUE: bring application to foreground, if running 
//             FALSE: only check, don't move to the application
//
// return: FALSE: application is not running
//         TRUE: application runs
BOOL AppIsAllreadyRunning(BOOL bShow/*=TRUE*/)
{
    BOOL bRunning=FALSE;
    CString strAppName;
    strAppName.LoadString(AFX_IDS_APP_TITLE);
    strAppName += _T(".exe");
    DWORD dwOwnPID = GetProcessId(GetCurrentProcess());
    HANDLE hSnapShot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
    PROCESSENTRY32* processInfo=new PROCESSENTRY32;
    processInfo->dwSize=sizeof(PROCESSENTRY32);
    int index=0;
    while(Process32Next(hSnapShot,processInfo)!=FALSE)
    {
        if (!strcmp(processInfo->szExeFile,strAppName))
        {
            if (processInfo->th32ProcessID != dwOwnPID)
            {
                if (bShow)
                    EnumWindows(ShowAppEnum,processInfo->th32ProcessID);
                bRunning=TRUE;
                break;
            }
        }
    }
    CloseHandle(hSnapShot);
    delete processInfo;
    return bRunning;
}

要访问正在运行的应用程序的窗口,我们使用 EnumWindows(),它需要一个辅助函数来枚举进程

// Helper callback-function for function AppIsAllreadyRunning()
// see description of EnumWindows() for details
BOOL CALLBACK ShowAppEnum (HWND hwnd, LPARAM lParam)
{
    DWORD dwID;
    CString strAppName;
    strAppName.LoadString(AFX_IDS_APP_TITLE);
    GetWindowThreadProcessId(hwnd, &dwID) ;
    if(dwID == (DWORD)lParam)
    {
        char title[256];
        CString strBuffer;
        GetWindowText(hwnd,title,256);
        strBuffer = title;
        if (strBuffer.Left(strAppName.GetLength()) == strAppName)
        {
            if (!IsWindowVisible(hwnd))
                ShowWindow(hwnd,SW_SHOW); 
            SetForegroundWindow(hwnd);
        }
    }
    return TRUE;
}

现在,您将对函数的调用放在应用程序类的 InitInstance() 中作为第一个调用。您可以检查函数的返回值,如果已经存在实例,则返回 FALSE

BOOL CfrTeakoApp::InitInstance()
{
#ifndef _DEBUG
    if (AppIsAllreadyRunning())
        return FALSE;
#endif

不要忘记在头文件中定义这些函数

BOOL AppIsAllreadyRunning(BOOL bShow=TRUE);
BOOL CALLBACK ShowAppEnum( HWND hwnd, LPARAM lParam );

就这样。

© . All rights reserved.