【问题标题】:Simulate .Net single instance application without using the single instance flag在不使用单实例标志的情况下模拟 .Net 单实例应用程序
【发布时间】:2013-02-06 04:07:25
【问题描述】:

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

我已经完成了大约一半,我已经到了

  • 检测有多少实例正在运行
  • 一种显示其他实例主窗口的方法(这是我卡住的地方)

问题是应用程序大部分时间在后台运行,隐藏,任务栏中没有项目。调用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

【问题讨论】:

    标签: windows vb.net


    【解决方案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
    

    【讨论】:

    • 检测代码看起来不错!但问题是我的检测工作正常,但它的“如果应用程序已经运行则显示窗口”部分被破坏(“单实例应用程序”难题的第二部分)。但你的回答确实给了我一个可以尝试的想法。
    • 最好创建一个互斥锁而不是笨重的锁文件或使用进程列表来查看您的应用是否已经在运行。
    • @Chris,已经在使用进程列表方法,但我会尝试结合这个方法,并且在锁定文件中包含主窗口处理程序,除此之外,我不知道如何发送该信息(我很想以某种方式直接从程序中获取它,而不是处理锁定文件/临时文件/等)
    【解决方案2】:

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

    这里有几个链接(如果我可以发布的话)。

    Vb Helper

    C code but can be translated

    Vb Net Code

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

    希望对你有帮助

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-04-10
      • 2017-07-05
      • 2017-04-24
      • 1970-01-01
      • 1970-01-01
      • 2023-03-25
      • 2012-04-29
      相关资源
      最近更新 更多