2

したがって、次のように、Windowsでアプリケーションの単一インスタンスを適用できます。

[STAThread]
class method Program.Main(args: array of string);
begin
  var mutex := new Mutex(true, "{8F6F0AC4-B9A1-45fd-A8CF-72F04E6BDE8F}");
  if mutex.WaitOne(Timespan.Zero, true) then
  begin
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.ThreadException += OnThreadException;
    lMainForm := new MainForm;
    lMainForm.ShowInTaskbar := true;
    lMainForm.Visible := false;

    Application.Run(lMainForm);
  end
  else
    MessageBox.Show("Another copy running!!!");
end;

ただし、Linuxでモノラルで同じアプリケーションを実行すると、このコードはまったく機能しません。複数のコピーを実行できます。のようにターミナルでアプリケーションを起動しているという事実と関係があるのか​​どうかはわかりませんmono MyPro.exe。これが問題である場合、コマンドラインを実行する前にいくつかの値を渡す必要がありますか?

前もって感謝します、

4

3 に答える 3

3

おそらく、MONO_ENABLE_SHM環境変数を使用して共有ハンドルを有効にする必要があります。

MONO_ENABLE_SHM=1 mono MyPro.exe
于 2012-11-06T15:18:48.017 に答える
3

Adrian Faciuがアプローチを機能させるために言及したように、共有メモリをモノラルで有効にする必要がありますが、これは最善のアプローチではありません(理由は、今は正確に思い出せない場合でも、そもそもデフォルトで無効になっている理由があります)。 。

私は過去に2つのソリューションを使用しました:

  • ファイルベースのロック。既知のファイルを作成し、そのファイルにpidを書き込みます。アプリの起動時に、ファイルが存在するかどうかを確認し、存在する場合はpidを読み取り、そのpidで実行中のプロセスがあるかどうかを確認します(クラッシュから回復できるようにするため)。そして、終了時にファイルを削除します(最初にファイルを作成したインスタンスで)。欠点は、複数のインスタンスがほぼ同時に起動された場合、起動時に競合状態が発生することです。これはファイルロックで改善できますが、Linuxで適切なファイルロックを実行するにはP / Invokesを使用する必要がある場合があります(マネージAPIが期待どおりに機能するかどうかは完全にはわかりません)。

  • 靴下ベースのロック。既知のポートを開きます。上記に対する利点は、クリーンアップを行う必要がなく、競合状態がないことです。欠点は、固定/既知のポートが必要であり、他のプログラムがその正確なポートを同時に使用する可能性があることです。

于 2012-11-06T22:35:27.580 に答える
1

エイドリアンのソリューションはme(tm)で機能します。ワイルドな推測:両方の呼び出しでMONO_ENABLE_SHMが必要でしたか?

于 2012-11-06T16:57:42.217 に答える