怎样判断程序正在运行,怎样关闭它。

怎样判断程序正在运行,怎样关闭它。,第1张

关闭正在运行的程序 你可以使用API函数FindWindow和PostMessage去寻找指定的窗口,并关闭它。 下面的例子教给你怎样找到并关掉一个悄烂尘Caption为“Caluclator”的程序。 Dim winHwnd As Long Dim RetVal As Long winHwnd = FindWindow(vbNullString, "Calculator ") Debug.Print winHwnd If winHwnd 0 Then RetVal = PostMessage(winHwnd, WM_CLOSE, 0&, 0&) If RetVal = 0 Then MsgBox "置入消息错误! " End If Else MsgBox "Calculator没有打开! " End If 为了让以上的代码工作,你必须在模块文件中什么以下API函数: Declare Function FindWindow Lib "user32 " Alias _ "FindWindowA " (ByVal lpClassName As String, _ ByVal lpWindowName As String) As Long Declare Function PostMessage Lib "user32 " Alias _ "PostMessageA " (ByVal hwnd As Long, ByVal wMsg As Long, _ ByVal wParam As Long, lParam As Any) As Long Public Const WM_CLOSE = &H10 判断一个32位程序是否结束 Microsoft 提供了少量的函数,如:WaitForSingleObject和 WaitForMultipleObjects 来完成该功能。尽管如此,这些函数并不是时时都有效。举例来说,如果你调用WaitForSingleObject函数监测Internet Explorer的运行,同时你又选择了“帮历族助”菜单中的“教程”项,结果将会是系统死锁,你不得不终止WaitForSingleObject函数的运行。造成这种结果的 原因是你点选了“教程”后,会返回给Internet Explorer一个地址,告诉浏览器转到下一个网址。这种情况通常发生在一个程序是由调用它的父程序中的一个过程或对象所启动,反过来却要等待父程序的结束。 本文的目的就是要解决这个问题。 Declare Declare Function OpenProcess Lib "kernel32 " (ByVal dwDesiredaccess&, ByVal bInherithandle&, ByVal dwProcessid&) As Long Declare Function GetExitCodeProcess Lib "kernel32 " (ByVal hProcess As Long, lpexitcode As Long) As Long ' Required Constants Const STILL_ACTIVE = &H103 Const PROCESS_QUERY_INFORMATION = &H400 Code Sub ShellWait(cCommandLine As String) Dim hShell As Long Dim hProc As Long Dim lExit As Long hShell = Shell(cCommandLine, vbNormalFocus) hProc = OpenProcess(PROCESS_QUERY_INFORMATION, False, hShell) Do GetExitCodeProcess hProc, lExit DoEvents Loop While lExit = STILL_ACTIVE End Sub 调用 ShellWait,启禅控制权将不会交给一个过程,直到调用该过程的程序结束 查看GetExitCodeProcess的用法 我还要关闭一个MessageBox,有是与否两个选项。我要发一个“是”的消息如何做。FindWindow VB声明 Declare Function FindWindow Lib "user32 " Alias "FindWindowA " (ByVal lpClassName As String, ByVal lpWindowName As String) As Long 说明 寻找窗口列表中第一个符合指定条件的顶级窗口(在vb里使用:FindWindow最常见的一个用途是获得ThunderRTMain类的隐藏窗口的句柄;该类是所有运行中vb执行程序的一部分。获得句柄后,可用api函数GetWindowText取得这个窗口的名称;该名也是应用程序的标题) 返回值 Long,找到窗口的句柄。如未找到相符窗口,则返回零。会设置GetLastError 参数表 参数 类型及说明 lpClassName String,指向包含了窗口类名的空中止(C语言)字串的指针;或设为零,表示接收任何类 lpWindowName String,指向包含了窗口文本(或标签)的空中止(C语言)字串的指针;或设为零,表示接收任何窗口标题 注解 很少要求同时按类与窗口名搜索。为向自己不准备参数传递一个零,最简便的办法是传递vbNullString常数 示例 Dim hw&, cnt&Dim rttitle As String * 256 hw&= FindWindow( "ThunderRT5Main ", vbNullString) ' ThunderRTMain under VB4 cnt = GetWindowText(hw&, rttitle, 255) MsgBox Left$(rttitle, cnt), 0, "RTMain title " FindWindowEx VB声明 Declare Function FindWindowEx Lib "user32 " Alias "FindWindowExA " (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long 说明 在窗口列表中寻找与指定条件相符的第一个子窗口 返回值 Long,找到的窗口的句柄。如未找到相符窗口,则返回零。零表示忽略 结束消息框 Private Const WM_CLOSE = &H10 Private Declare Function FindWindow Lib "user32 " Alias "FindWindowA " (ByVal lpClassName As String, ByVal lpWindowName As String) As Long Private Declare Function SendMessage Lib "user32 " Alias "SendMessageA " (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long Private Declare Function EnableWindow Lib "user32 " (ByVal hwnd As Long, ByVal fEnable As Long) As Long Private Declare Function GetParent Lib "user32 " (ByVal hwnd As Long) As Long Private Sub Command1_Click() Dim hwnd1 As Long Dim hwnd2 As Long ' hwnd1 = FindWindow(vbNullString, "Form2 ") hwnd2 = FindWindow(vbNullString, "Iloveyou ") 'Msgbox hwnd1 = GetParent(hwnd2) 'The Parent SendMessage hwnd2, WM_CLOSE, 0&, 0&EnableWindow hwnd1, 1 'Active the Parent End Sub --------------------------------------- Const WM_CLOSE = &H10 Private Declare Function FindWindow Lib "user32 " Alias "FindWindowA " (ByVal lpClassName As String, ByVal lpWindowName As String) As Long Private Declare Function SendMessage Lib "user32 " Alias "SendMessageA " (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long Private Sub command_click() Dim hwnd As Long Msgbox "xx ",, "aa " 'd出msgbox hwnd = FindWindow(vbNullString, "aa ") 'Msgbox的标题为aa SendMessage hwnd, WM_CLOSE, 0&, 0&'将它关闭 End Sub

windows是一个消息机制,

以桌面为父窗口来查找第一个主窗口

hWndPrevious = GetWindow(GetDesktopWindow(),GW_CHILD)

LPTSTR m_pszExeName

while (IsWindow(hWndPrevious))

{

int i=GetWindowTextLength(hWndPrevious)

GetWindowText(hWndPrevious,szHello,i)//获取窗口标题//这里我的窗口中只有下面几个字是不变的

if (strstr(szHello,"当前用户数:")){

sprintf( szHello1, "Hwnd:%X Title:%s",hWndPrevious,szHello)

TextOut(hdc, rt.left, rt.top, szHello1,strlen(szHello1))

break//匹配,这时hWndPrevious就是所要找的窗口的句柄

}

hWndPrevious = GetWindow(hWndPrevious,GW_HWNDNEXT)

}

获取了信息就可以调用

向运行程序的主窗口发送WM_CLOSE消息。 HWND hwnd = // 获得主窗口

PostMessage(hwnd, WM_CLOSE, 0, 0)

发送此消息后,通常应该等待直到进程确实终止: HANDLE hp = OpenProcess(SYNCHRONIZE|PROCESS_TERMINATE,FALSE,pid)

WaitForSingleObject(hp, 5000) // 等待5秒

当进程终止时,它发出状态信号,并且 WaitForSingleObject 返回WAIT_OBJECT_0。如果返回别的值,进程要么挂起了,要么仍然在进行处理。在这种情况下,杀死这个进程的唯一方法是用功能更强大的TerminateProcess: if (WaitForSingleObject(hp, 5000) != WAIT_OBJECT_0)

TerminateProcess(hp,0)

如果想干得漂亮一点,可以在关闭之前向主窗口发送一个WM_QUERYENDSESSION消息。当用户结束会话(log out)或者有人调用ExitWindows时,应用程序会收到这个消息。然后准备即将来临的死亡。此时一般都会d出一个确认对话框,告诉世人:“我要完蛋了,如果要保存修改的东西,现在是最佳时机,想保存吗?”有三种选择(Yes/No/Cancel)。此外,WM_QUERYENDSESSION甚至可以拒绝死亡(按下"Cancel键"),如果是这样,生命将会延续。代码应该这样写: DWORD bOKToKill = FALSE

SendMessageTimeout(hwnd, WM_QUERYENDSESSION, 0, 0,

SMTO_ABORTIFHUNG|SMTO_NOTIMEOUTIFNOTHUNG, 100, &bOKToKill)

if (bOKToKill) {

// 发送WM_CLOSE 并等待

}

如果想要关闭的进程被挂起。使用SendMessageTimeout就非常重要,戚吵而不是用SendMessage。SMTO_NOTIMEOUTIFNOTHUNG是一个只有Windows 2000 和Windows XP才有的标志高世侍。其意义是“如果线程没有挂起,不要超时返兄。”换句话说就是:如果线程正在进行正常处理,那么永远等待,以便用户能看到对话框并决定做什么。当用户最终做出决定后,SendMessageTimeout将带着相应的bOKToKill值返回。所有这些的前提是其它的应用程序运行正常并且WM_QUERYENDSESSION也得到正常处理。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12294175.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-24
下一篇 2023-05-24

发表评论

登录后才能评论

评论列表(0条)

保存