在不使用单实例标志的情况下模拟.Net单实例应用程序

时间:2013-02-06 04:07:26

标签: windows vb.net

目前我正在尝试在不使用“Single Instance”标志的情况下构建单例应用程序,这是由于应用程序的某些机制实际上需要多个实例(自更新程序等)。因此,我必须构建自己的方法来确保只有一个应用程序实例。

我已经到了创造这个的一半,我已经到了

的目的
  • 检测正在运行的实例数
  • 显示其他实例的方法主窗口(这是我被困的地方)

问题是应用程序大部分时间在后台运行,隐藏,任务栏中没有项目。当调用process.MainWindowHandle时,它总是返回0,因为该函数检测当前的“MainWindow”,它需要窗口为A)可见,B)在任务栏中显示。

是否存在此限制?

我能想到的一种方法,但没有实现的想法是在第一次看到应用程序时存储MainWindowHandle,但是我如何公开这个值呢?

当前代码:

            Dim running_processes As Process() = Process.GetProcessesByName("helpdesk")
            Dim current_process_id As Integer = Process.GetCurrentProcess().Id

            If (running_processes.Length = 1) Then
                'Run the app like normal
                bootstrap_loader.Show()


            Else
                For Each process As Process In running_processes
                    If process.Id = current_process_id Then Continue For

                    'MainWindowHandle returns 0 when window is not visible
                    'Sidenote: ShowWindow is from user32.dll :) 
                    ShowWindow(process.MainWindowHandle, SHOW_WINDOW.SW_NORMAL)

                    'Exit the application like a baws
                    'Environment.Exit(2)
                Next
            End If

2 个答案:

答案 0 :(得分:1)

在应用启动时,打开临时文件并保持打开状态。同样在启动时,测试是否可以删除临时文件。如果没有,则另一个实例正在运行,因此您的应用程序将关闭。

Imports System.IO

Public Class Form1
  Private mstrLockFilename As String
  Private mfstLock As FileStream

  Public Sub New()

    ' This call is required by the designer.
    InitializeComponent()

    ' Add any initialization after the InitializeComponent() call.
    mstrLockFilename = Application.StartupPath & "\lock.txt"
    Try
      mfstLock = New FileStream(mstrLockFilename, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None)
    Catch ex As Exception
      MsgBox("App is already running", MsgBoxStyle.Exclamation)
      End
    End Try
  End Sub

  Private Sub Form1_FormClosed(sender As Object, e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
    If mfstLock IsNot Nothing Then
      mfstLock.Close()
      mfstLock.Dispose()
      Try
        File.Delete(mstrLockFilename)
      Catch
      End Try
    End If
  End Sub
End Class

答案 1 :(得分:0)

在他们拥有Single Instance选项之前,您必须自己完成。基本上 - 您可以调用当前的应用程序名称 - 然后调用以该名称获取所有正在运行的应用程序。

以下是一些链接(如果我可以发布)。

Vb Helper

C code but can be translated

Vb Net Code

我看到一个引用表明这可能无法在两个呼叫同时进行。可以通过两次调用修复的Pehaps。在装载的早期 - 然后在之后。

希望这有帮助