判斷指定的程序或程式是否存在方法小結(vc等)
阿新 • • 發佈:2018-12-30
一、判斷指定程式名的程序是否存在
BOOL EnumWindows( WNDENUMPROC lpEnumFunc, // pointer to callback function LPARAM lParam // application-defined value);
The EnumWindows function enumerates all top-level windows on the screen by passing the handle to each window, in turn, to an application-defined callback function. EnumWindows continues until the last top-level window is enumerated or the callback function returns FALSE.
複製程式碼程式碼如下:
BOOL CALLBACK IpEnumFunc(HWND hwnd,LPARAM lParam)
{
char wndName[100];
::GetWindowText(hwnd,wndName,sizeof(wndName));
if(wndName!="")
{
if(strcmp(wndName,name1)==0)
{
WndHnd=hwnd;
flag=1;
}
}
return 1;
}
二、判斷指定程序名的程序是否存在
複製程式碼程式碼如下:
DWORD GetProcessidFromName(LPCTSTR name)
{
PROCESSENTRY32 pe;
DWORD id=0;
HANDLE hSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
pe.dwSize=sizeof(PROCESSENTRY32);
if(!Process32First(hSnapshot,&pe))
return 0;
while(1)
{
pe.dwSize=sizeof(PROCESSENTRY32);
if(Process32Next(hSnapshot,&pe)==FALSE)
break;
if(strcmp(pe.szExeFile,name)==0)
{
id=pe.th32ProcessID;
break;
}
}
CloseHandle(hSnapshot);
return id;
}
如果返回值不為零,則存在,否則不存在。
三、VC判斷程式呼叫的外部程序是否結束
複製程式碼程式碼如下:
PROCESS_INFORMATION pi;
STARTUPINFO si;
memset(&si,0,sizeof(si));
si.cb=sizeof(si);
si.wShowWindow=SW_HIDE;
si.dwFlags=STARTF_USESHOWWINDOW;
bool fRet=CreateProcess(NULL,str.GetBuffer(str.GetLength()),NULL,FALSE,NULL,NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW,NULL,NULL,&si,&pi);
///判斷
DWORD ExitCode;
ExitCode=STILL_ACTIVE;
while(ExitCode==STILL_ACTIVE)
{
GetExitCodeProcess(pi.hProcess,&ExitCode);
}
四、VC判斷程序是否存在?比如我想知道記事本是否執行,要用到哪些函式?
複製程式碼程式碼如下:
enProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,aProcesses[i]);
// 取得特定PID的程序名
if (hProcess )
{
if ( EnumProcessModules(hProcess,&hMod,sizeof(hMod), &cbNeeded))
{
GetModuleBaseName( hProcess, hMod,szProcessName,sizeof(szProcessName));
//將取得的程序名與輸入的程序名比較,如相同則返回程序PID
if(!stricmp(szProcessName, InputProcessName))
{
CloseHandle(hProcess);
return aProcesses[i];
}
}
}//end of if (hProcess)
}//end of for
//沒有找到相應的程序名,返回0
CloseHandle(hProcess);
return 0;
}
也可以列舉得到所有程序的應用程式名,然後和知道應用程式名比較判斷。
五、實現程式只執行一次的方法
實現程式只執行一次的方法很多,但是原理都是一樣的,就是執行第一次的時候設定一個標記,每次執行的時候檢查該標記,如果有就說明已經運行了。
具體實現:
1、在程式初始化的時候 (InitInstance()) 列舉所有的視窗,查詢本程式的例項是否存在
2、在主視窗初始化的時候在本視窗的屬性列表中新增一個標記,以便程式查詢.
部分關鍵程式碼 :
1、在App的InitInstance()中列舉所有視窗,查詢本程式例項
複製程式碼程式碼如下:
HWND oldHWnd = NULL;
EnumWindows(EnumWndProc,(LPARAM)&oldHWnd); //列舉所有執行的視窗
if(oldHWnd != NULL)
{
AfxMessageBox( "本程式已經在運行了 ");
::ShowWindow(oldHWnd,SW_SHOWNORMAL); //啟用找到的前一個程式
::SetForegroundWindow(oldHWnd); //把它設為前景視窗
return false; //退出本次執行
}
2、新增EnumWndProc視窗過程函式://新增的標識只執行一次的屬性名
複製程式碼程式碼如下:
CString g_szPropName = "Your Prop Name "; //自己定義一個屬性名
HANDLE g_hValue = (HANDLE)1; //自己定義一個屬性值
BOOL CALLBACK EnumWndProc(HWND hwnd,LPARAM lParam)
{
HANDLE h = GetProp(hwnd,g_szPropName);
if( h == g_hValue)
{
*(HWND*)lParam = hwnd;
return false;
}
return true;
}
3、在主視窗的 OnInitDialog()中新增屬性 //設定視窗屬性
SetProp(m_hWnd,g_szPropName,g_hValue);
再次啟動時,先檢查當前存在的所有視窗,如果有標題相同的,則把先前執行的視窗當成當前視窗
我的程式如下:
複製程式碼程式碼如下:
HWND hWnd_Exist;
hWnd_Exist=::GetDesktopWindow();
hWnd_Exist=::GetWindow(hWnd_Exist,GW_CHILD);
for(;;)
{
if(hWnd_Exist==NULL)
{
break;
}
char s[256];
memset(s,0,256);
::SendMessage(hWnd_Exist,WM_GETTEXT,255,(LONG)s);
if(strstr(s, "****** ")!=NULL)
break;
hWnd_Exist=::GetWindow(hWnd_Exist,GW_HWNDNEXT);
}
if(hWnd_Exist != NULL)
{
::ShowWindow(hWnd_Exist,SW_SHOWNORMAL);
::SetForegroundWindow(hWnd_Exist);
exit(0);
}
宣告一個全域性 CMutex 變數:
--------------------------------------------------------------------------------
CMutex mutexApp(FALSE, _T( "VPOS2000Server ")); //用此互斥量阻止多個例項
在你的 CWinApp 類的過載函式: InitInstance 中加入如下程式碼:
複製程式碼程式碼如下:
if (!mutexApp.Lock(1))
return FALSE;
::CreateMutex(NULL, TRUE, m_pszExeName);
if(ERROR_ALREADY_EXISTS == GetLastError())
{
CWnd* pPrevHwnd = CWnd::GetDesktopWindow()-> GetWindow(GW_CHILD);
while(pPrevHwnd)
{
if(::GetProp(pPrevHwnd-> GetSafeHwnd(), m_pszExeName))
{
if(pPrevHwnd-> IsIconic())
{
pPrevHwnd-> ShowWindow(SW_RESTORE);
}
pPrevHwnd-> SetForegroundWindow();
pPrevHwnd-> GetLastActivePopup()-> SetForegroundWindow();
return FALSE;
}
pPrevHwnd = pPrevHwnd-> GetWindow(GW_HWNDNEXT);
}
TRACE( "Could not fond frevious instance main window ! ");
return FALSE;
}
建立一個全域性的互斥量,每次啟動時檢查是否存在。
複製程式碼程式碼如下:
BOOL CRTDBApp::OnlyOneInstance()
{
if(::CreateMutex(NULL, TRUE, "onlyone ") == NULL )
{
TRACE0( "CreateMutex error. ");
return FALSE;
};
if( ::GetLastError() == ERROR_ALREADY_EXISTS) {
CWnd* pPrevWnd = CWnd::FindWindow(NULL, "onlyonehwnd ");
if(pPrevWnd)
{
if( pPrevWnd-> IsIconic())
pPrevWnd-> ShowWindow(SW_RESTORE);
pPrevWnd-> SetForegroundWindow();
pPrevWnd-> GetLastActivePopup()-> SetForegroundWindow();
return FALSE;
}
};
return TRUE;
}
BOOL EnumWindows( WNDENUMPROC lpEnumFunc, // pointer to callback function LPARAM lParam // application-defined value);
The EnumWindows function enumerates all top-level windows on the screen by passing the handle to each window, in turn, to an application-defined callback function. EnumWindows continues until the last top-level window is enumerated or the callback function returns FALSE.
複製程式碼程式碼如下:
BOOL CALLBACK IpEnumFunc(HWND hwnd,LPARAM lParam)
{
char wndName[100];
::GetWindowText(hwnd,wndName,sizeof(wndName));
if(wndName!="")
{
if(strcmp(wndName,name1)==0)
{
WndHnd=hwnd;
flag=1;
}
}
return 1;
}
二、判斷指定程序名的程序是否存在
複製程式碼程式碼如下:
DWORD GetProcessidFromName(LPCTSTR name)
{
PROCESSENTRY32 pe;
DWORD id=0;
HANDLE hSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
pe.dwSize=sizeof(PROCESSENTRY32);
if(!Process32First(hSnapshot,&pe))
return 0;
while(1)
{
pe.dwSize=sizeof(PROCESSENTRY32);
if(Process32Next(hSnapshot,&pe)==FALSE)
break;
if(strcmp(pe.szExeFile,name)==0)
{
id=pe.th32ProcessID;
break;
}
}
CloseHandle(hSnapshot);
return id;
}
如果返回值不為零,則存在,否則不存在。
三、VC判斷程式呼叫的外部程序是否結束
複製程式碼程式碼如下:
PROCESS_INFORMATION pi;
STARTUPINFO si;
memset(&si,0,sizeof(si));
si.cb=sizeof(si);
si.wShowWindow=SW_HIDE;
si.dwFlags=STARTF_USESHOWWINDOW;
bool fRet=CreateProcess(NULL,str.GetBuffer(str.GetLength()),NULL,FALSE,NULL,NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW,NULL,NULL,&si,&pi);
///判斷
DWORD ExitCode;
ExitCode=STILL_ACTIVE;
while(ExitCode==STILL_ACTIVE)
{
GetExitCodeProcess(pi.hProcess,&ExitCode);
}
四、VC判斷程序是否存在?比如我想知道記事本是否執行,要用到哪些函式?
複製程式碼程式碼如下:
enProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,aProcesses[i]);
// 取得特定PID的程序名
if (hProcess )
{
if ( EnumProcessModules(hProcess,&hMod,sizeof(hMod), &cbNeeded))
{
GetModuleBaseName( hProcess, hMod,szProcessName,sizeof(szProcessName));
//將取得的程序名與輸入的程序名比較,如相同則返回程序PID
if(!stricmp(szProcessName, InputProcessName))
{
CloseHandle(hProcess);
return aProcesses[i];
}
}
}//end of if (hProcess)
}//end of for
//沒有找到相應的程序名,返回0
CloseHandle(hProcess);
return 0;
}
也可以列舉得到所有程序的應用程式名,然後和知道應用程式名比較判斷。
五、實現程式只執行一次的方法
實現程式只執行一次的方法很多,但是原理都是一樣的,就是執行第一次的時候設定一個標記,每次執行的時候檢查該標記,如果有就說明已經運行了。
具體實現:
1、在程式初始化的時候 (InitInstance()) 列舉所有的視窗,查詢本程式的例項是否存在
2、在主視窗初始化的時候在本視窗的屬性列表中新增一個標記,以便程式查詢.
部分關鍵程式碼 :
1、在App的InitInstance()中列舉所有視窗,查詢本程式例項
複製程式碼程式碼如下:
HWND oldHWnd = NULL;
EnumWindows(EnumWndProc,(LPARAM)&oldHWnd); //列舉所有執行的視窗
if(oldHWnd != NULL)
{
AfxMessageBox( "本程式已經在運行了 ");
::ShowWindow(oldHWnd,SW_SHOWNORMAL); //啟用找到的前一個程式
::SetForegroundWindow(oldHWnd); //把它設為前景視窗
return false; //退出本次執行
}
2、新增EnumWndProc視窗過程函式://新增的標識只執行一次的屬性名
複製程式碼程式碼如下:
CString g_szPropName = "Your Prop Name "; //自己定義一個屬性名
HANDLE g_hValue = (HANDLE)1; //自己定義一個屬性值
BOOL CALLBACK EnumWndProc(HWND hwnd,LPARAM lParam)
{
HANDLE h = GetProp(hwnd,g_szPropName);
if( h == g_hValue)
{
*(HWND*)lParam = hwnd;
return false;
}
return true;
}
3、在主視窗的 OnInitDialog()中新增屬性 //設定視窗屬性
SetProp(m_hWnd,g_szPropName,g_hValue);
再次啟動時,先檢查當前存在的所有視窗,如果有標題相同的,則把先前執行的視窗當成當前視窗
我的程式如下:
複製程式碼程式碼如下:
HWND hWnd_Exist;
hWnd_Exist=::GetDesktopWindow();
hWnd_Exist=::GetWindow(hWnd_Exist,GW_CHILD);
for(;;)
{
if(hWnd_Exist==NULL)
{
break;
}
char s[256];
memset(s,0,256);
::SendMessage(hWnd_Exist,WM_GETTEXT,255,(LONG)s);
if(strstr(s, "****** ")!=NULL)
break;
hWnd_Exist=::GetWindow(hWnd_Exist,GW_HWNDNEXT);
}
if(hWnd_Exist != NULL)
{
::ShowWindow(hWnd_Exist,SW_SHOWNORMAL);
::SetForegroundWindow(hWnd_Exist);
exit(0);
}
宣告一個全域性 CMutex 變數:
--------------------------------------------------------------------------------
CMutex mutexApp(FALSE, _T( "VPOS2000Server ")); //用此互斥量阻止多個例項
在你的 CWinApp 類的過載函式: InitInstance 中加入如下程式碼:
複製程式碼程式碼如下:
if (!mutexApp.Lock(1))
return FALSE;
::CreateMutex(NULL, TRUE, m_pszExeName);
if(ERROR_ALREADY_EXISTS == GetLastError())
{
CWnd* pPrevHwnd = CWnd::GetDesktopWindow()-> GetWindow(GW_CHILD);
while(pPrevHwnd)
{
if(::GetProp(pPrevHwnd-> GetSafeHwnd(), m_pszExeName))
{
if(pPrevHwnd-> IsIconic())
{
pPrevHwnd-> ShowWindow(SW_RESTORE);
}
pPrevHwnd-> SetForegroundWindow();
pPrevHwnd-> GetLastActivePopup()-> SetForegroundWindow();
return FALSE;
}
pPrevHwnd = pPrevHwnd-> GetWindow(GW_HWNDNEXT);
}
TRACE( "Could not fond frevious instance main window ! ");
return FALSE;
}
建立一個全域性的互斥量,每次啟動時檢查是否存在。
複製程式碼程式碼如下:
BOOL CRTDBApp::OnlyOneInstance()
{
if(::CreateMutex(NULL, TRUE, "onlyone ") == NULL )
{
TRACE0( "CreateMutex error. ");
return FALSE;
};
if( ::GetLastError() == ERROR_ALREADY_EXISTS) {
CWnd* pPrevWnd = CWnd::FindWindow(NULL, "onlyonehwnd ");
if(pPrevWnd)
{
if( pPrevWnd-> IsIconic())
pPrevWnd-> ShowWindow(SW_RESTORE);
pPrevWnd-> SetForegroundWindow();
pPrevWnd-> GetLastActivePopup()-> SetForegroundWindow();
return FALSE;
}
};
return TRUE;
}