0

目前我正在尝试在不使用“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
4

2 回答 2

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
于 2013-02-06T05:12:27.870 回答
0

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

这里有一些链接(如果我可以发布它们)。

VB 助手

C 代码但可以翻译

VB网络代码

我看到一个参考表明这在两个呼叫同时发生的情况下可能不起作用。也许可以通过两个电话来解决。在加载的早期 - 然后稍后。

希望这可以帮助

于 2013-02-06T04:59:18.613 回答