HI,各位;
请问如何编写程序识别同一程序已运行?
比如我打开了一个软件:a.exe
下次我不小心又去打开它,这个时候程序先判断a.exe是否在运行,如何运行了,则不能再打开第二个a.exe了。有谁知道如何去实现它呀?最好有现成的代码!!先谢了!

解决方案 »

  1.   


     
      
    你好,  Darkay_Lee()  你那有这样的程序吗?能否提供给我参考呀?
      

  2.   

    我见过,好象用  APP.**** 吧 具体是什么我记不的了。不好意思啊
    if app.***** (省略)  then
    ....
    else
    ...
    end if
      

  3.   

    你要是做成功了 给我发一份
    mail:[email protected]
      

  4.   

    If App.PrevInstance = True Then
      End     '表明已运行
    End If
      

  5.   

    给你个模块:'*************************************************************************
    '**模 块 名:Module1
    '**说    明:判断程序是否运行,如运行切换到前台
    '**创 建 人:寒江雪
    '**日    期:2006-05-27 22:50:28
    '**修 改 人:
    '**日    期:
    '**描    述:在工程属性里设置从这个模块启动,即sub main。
    '**版    本:V1.0.0
    '*************************************************************************Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
    Public Declare Function OpenIcon Lib "user32" (ByVal hwnd As Long) As Long
    Public Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As LongPrivate Sub Main()
        Dim h  '声明句柄变量
        h = FindWindow(vbNullString, "form1") '取得窗体句柄
        If h <> 0 Then  '判断窗体是否存在
            OpenIcon h  '将最小化的窗体还原
            SetForegroundWindow h    '将窗体切换到前台
            End
        Else
            Load Form1  '若窗体不存在则加载窗体
            Form1.Show  '显示窗体
        End If
    End Sub
      

  6.   

    sub main()If App.PrevInstance = True Then
    msgbox "loaded!"
    else
    msgbox "not loaded!"
    End Ifend subApp.PrevInstance就是看之前有没有程序的副本被运行过
      

  7.   

    h = FindWindow(vbNullString, "form1") '取得窗体句柄
    请问这句中的“form1”是当前运行的窗体名称吗?还是可执行文件?我用的MDI窗体啥不好用嫩?
      

  8.   

    sub main()
    If App.PrevInstance = True Then
       msgbox app.title & ".exe is running"
       form1.windowstate=0
    else
      Load form1  
      form1.show
    End If
    end sub
      

  9.   

    说两句,有一部分同志,说的有问题,用APP,指的是本程序,楼主说的是A.EXE,一定是自己写的吗?如果是外部程序呢?简单的办法就是识别进程名,而不是识别什么窗口。
    ProcessFirst获取进程名
    ProcessNext获取下一个进程名
    用上面函数列出全部系统进程。如果已经存在你要运行的进程名,那么就关闭后一个。用ExitProcess就可以了。
    如果你无法终止后一个进程,那么需要提升你的应用程序的权限(不是优先级),可以用AdjustTokenPrivileges函数
      

  10.   

    如果a.exe是自己写的这个程序,直接用vb的App.PrevInstance来判断是否运行过一次最简单,不用互斥量之类的API。如果是别人写的程序,楼上的兄弟的办法可行
      

  11.   

    to zcsor()为什么不可以识别窗口名,如果说窗口名可能一样的话,进程名也可以一样,具体问题具体考虑嘛。不过保险的方法是进程名识别+进程路径识别。附:如何得到已知进程的路径Private Declare Function OpenProcess Lib "kernel32.dll" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
        
      Private Declare Function EnumProcessModules Lib "psapi.dll" (ByVal hProcess As Long, ByRef lphModule As Long, ByVal cb As Long, ByRef cbNeeded As Long) As Long
        
      Private Declare Function GetModuleFileNameExA Lib "psapi.dll" (ByVal hProcess As Long, ByVal hModule As Long, ByVal ModuleName As String, ByVal nSize As Long) As Long
        
      Private Declare Function CloseHandle Lib "kernel32.dll" (ByVal hObject As Long) As Long
        
      '根据进程号获取进程路径函数,原创:
      Function GetProcessPathByProcessID(ByVal PID As Long) As String
              On Error GoTo Z
              Dim cbNeeded     As Long
              Dim szBuf(1 To 250)         As Long
              Dim Ret     As Long
              Dim szPathName     As String
              Dim nSize     As Long
              Dim hProcess     As Long
              hProcess = OpenProcess(&H400 Or &H10, 0, PID)
              If hProcess <> 0 Then
                      Ret = EnumProcessModules(hProcess, szBuf(1), 250, cbNeeded)
                      If Ret <> 0 Then
                              szPathName = Space(260)
                              nSize = 500
                              Ret = GetModuleFileNameExA(hProcess, szBuf(1), szPathName, nSize)
                              GetProcessPathByProcessID = Left(szPathName, Ret)
                      End If
              End If
              Ret = CloseHandle(hProcess)
              If GetProcessPathByProcessID = "" Then
                    GetProcessPathByProcessID = "SYSTEM"
              End If
              Exit Function
    Z:
      End Function
        
      '我的系统VB进程ID为2256
      '下面的结果显示了VB进程的路径为:D:\Microsoft   Visual   Studio\VB98\VB6.EXE
        
      Private Sub Command1_Click()
              MsgBox GetProcessPathByProcessID(2256)
      End Sub
      

  12.   

    附:获得指定进程的PID'Search   Process   Functions
    Private Const MAX_PATH = 260
    Private Type PROCESSENTRY32
            dwSize   As Long
            cntUsage   As Long
            th32ProcessID   As Long
            th32DefaultHeapID   As Long
            th32ModuleID   As Long
            cntThreads   As Long
            th32ParentProcessID   As Long
            pcPriClassBase   As Long
            dwFlags   As Long
            szExeFile   As String * MAX_PATH
    End TypePrivate Declare Function CreateToolhelp32Snapshot Lib "kernel32" (ByVal dwFlags As Long, ByVal th32ProcessID As Long) As Long
    Private Declare Function Process32First Lib "kernel32" (ByVal hSnapshot As Long, lppe As Any) As Long
    Private Declare Function Process32Next Lib "kernel32" (ByVal hSnapshot As Long, lppe As Any) As LongPrivate Const TH32CS_SNAPHEAPLIST = &H1
    Private Const TH32CS_SNAPPROCESS = &H2
    Private Const TH32CS_SNAPTHREAD = &H4
    Private Const TH32CS_SNAPMODULE = &H8
    Private Const TH32CS_SNAPALL = (TH32CS_SNAPHEAPLIST + TH32CS_SNAPPROCESS + TH32CS_SNAPTHREAD + TH32CS_SNAPMODULE)
    Private Const TH32CS_INHERIT = &H80000000Private Sub Command1_Click()
        '查找进程
        Dim hSnapshot     As Long, P       As PROCESSENTRY32
        Dim exitCode     As Long
        Dim myProcess     As Long    P.dwSize = Len(P)
        hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, ByVal 0)
        If hSnapshot Then
            lRet = Process32First(hSnapshot, P)
            Do While lRet
                If InStr(P.szExeFile, "calc.exe") <> 0 Then
                    MsgBox P.th32ProcessID
                End If
                lRet = Process32Next(hSnapshot, P)
            Loop
        End If
    End Sub
      

  13.   

    如果用以下这个方法的话有一个问题
    要是本文件改名了   那么再次打开也是算没有打开过的呀
    sub main()If App.PrevInstance = True Then
    msgbox "loaded!"
    else
    msgbox "not loaded!"
    End Ifend sub
      

  14.   

    哎呀,那你们到底想怎么样麻!难道还要逐字节校验程序内容才肯确定我看这个问题麻烦了。不过感谢一下verywzm(寒江雪)同志,最近写一个类似任务管理器的东西,虽然最后用的代码不是你提供的获取进程路径的代码(我用的是查询模块一起出来了呵呵),但是也学了一些东西。有个问题想获得帮助,主题是:关于进程调用者名称的问题,SID? 
    求教!