0

現時点では、「Single Instance」フラグを使用せずにシングルトン アプリケーションを構築しようとしています。これは、アプリケーションのメカニズムの一部が実際に複数のインスタンス (セルフ アップデーターなど) を必要とするためです。そのため、アプリケーションのインスタンスが 1 つだけであることを保証する独自の方法を構築する必要があります。

私はこれを作成することの約半分に達しました。

  • 実行中のインスタンスの数を検出します
  • 他のインスタンスのメイン ウィンドウを表示する方法(ここで行き詰まっています)

問題は、ほとんどの場合、アプリケーションがバックグラウンドで非表示になり、タスクバーにアイテムが表示されないことです。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ネットコード

両方の呼び出しが同時に行われると、これが機能しない可能性があることを示す 1 つの参照を見ました。おそらく、2回の電話で修正できます。ロードの早い段階 - その後。

お役に立てれば

于 2013-02-06T04:59:18.613 に答える