是否有可能编写一个App.PrevInstance Replacement来提供实时信息



App.Previnstance返回TrueFalse的值,这取决于该实例启动时程序的前一个程序是否正在运行。

随后,如果前一个实例被终止,App.PrevInstance的值不会改变。

是否有可能编写一个函数,能够在任何时候确定是否先前实例存在吗?

我猜,为此,您将需要日期/时间进程开始可用。由于这些信息似乎无法从任务管理器中获得,我想知道windows是否存储了它?

您在App.PrevInstance 中看到的问题可能是因为您正在测试在调试器(即VB 6 IDE)下运行的应用程序。但我不完全确定。它可能只执行一次检查并缓存该值,这使得它可以随着环境状态的变化而变得"陈旧"。正如您已经注意到的,App.PrevInstance属性有很多限制。它的另一个常见问题是它的脆弱性。更改可执行文件的名称很容易使其失败。这并不总是理想的行为。

所以用另一种解决方案来代替它是个好主意。正如wqw在评论中所说,最好的解决方案是在应用程序启动时使用GUID作为互斥锁的名称创建一个互斥锁。第一次应该会成功,但随后会失败,因为互斥锁已经注册了(由应用程序的前一个实例)。该失败提示您应用程序的前一个实例正在运行。要在VB 6中做到这一点,您需要导入并调用一些Win32函数,如CreateMutexCloseHandleReleaseMutex。这里有一个如何在MSDN上使用互斥锁的示例,但是除非你已经非常熟悉Win32 API,否则它不会对你编写VB 6代码有很大帮助。在我的回答中,我已经链接到一个包含VB 6中必要代码的教程。

如果您对App.PrevInstance的行为感到满意,并且您只是希望每次调用它时它都执行检查(而不是使用过时的缓存值),那么您可以将其替换为对您自己的函数的调用,该函数本质上做同样的事情:遍历所有当前运行的进程,并查找与可执行文件名称匹配的函数。不幸的是,这并不一定比使用互斥锁的"更好"解决方案工作量少。您仍然需要导入一些Win32函数,包括EnumProcesses。在一篇旧的知识库文章中有这方面的说明——显然你想要关注"Windows NT"部分,而忽略"Windows 95/98"的东西。

我猜,为此,您将需要日期/时间进程开始可用。由于这些信息似乎无法从任务管理器中获得,我想知道windows是否存储了它?

你实际上并不需要这些信息。事实上,我不确定你想到的是什么方法需要它。进程何时启动并不重要,重要的是它当前是否正在运行。这完全是两码事。

然而,只是为了好玩,Windows 实际上存储了这些信息。任务管理器不会显示它,但进程资源管理器会显示。您可以通过调用GetProcessTimes函数或查询WMI(特别是Win32_Process类的CreationDate属性)以编程方式检索它。

感谢wqw的评论,我查找了CreateMutex,这正是我所需要的。

我找到了下面的代码

'Code by Adam Verwijs
Const ERROR_ALREADY_EXISTS = 183&
Private Declare Function CreateMutex Lib "kernel32" Alias "CreateMutexA" (lpMutexAttributes As Any, ByVal bInitialOwner As Long, ByVal lpName As String) As Long
Private Declare Function ReleaseMutex Lib "kernel32" (ByVal hMutex As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Sub Form_Load()
    Dim hMutex As Long
    'Try to create a new Mutex
    hMutex = CreateMutex(ByVal 0&, 1, App.Title)
    'Did the mutex already exist?
    If (Err.LastDllError = ERROR_ALREADY_EXISTS) Then
        'Clean up
        ReleaseMutex hMutex
        CloseHandle hMutex
        'More than one instance detected
        MsgBox "More than one instance"
        End
    Else
        'form load code
    End If
End Sub

EDIT显示相同的非零互斥锁返回:如果你用一个按钮创建一个新的vb6项目,粘贴下面的代码,使项目,然后运行多个实例,你会看到所有的都有相同的非零互斥锁,至少在我的计算机上(windows vista home basic)

   Option Explicit
Const ERROR_ALREADY_EXISTS = 183&
Private Declare Function CreateMutex Lib "kernel32" Alias "CreateMutexA" (lpMutexAttributes As Any, ByVal bInitialOwner As Long, ByVal lpName As String) As Long
Private Declare Function ReleaseMutex Lib "kernel32" (ByVal hMutex As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Sub Command1_Click()
 Dim hMutex As Long
    'Try to create a new Mutex
    hMutex = CreateMutex(ByVal 0&, 1, App.Title)
    MsgBox hMutex
    'Did the mutex already exist?
    If (Err.LastDllError = ERROR_ALREADY_EXISTS) Then
        'Clean up
        ReleaseMutex hMutex
        CloseHandle hMutex
        'More than one instance detected
        MsgBox "More than one instance"

    End If
End Sub

编辑2016-04-17请勿使用此代码!!我使用它没有注意到一个问题,直到最近,但现在发现,它不能跨多个用户登录在一台计算机上工作。

用wqw的答案代替

最新更新