共有ドライブに実行可能な ac# アプリケーションがあります。これにより、共有ドライブにアクセスできるユーザー (3) が実行可能ファイルを開くことができます。現在、実行可能ファイルを同時に実行できる人は 1 人までにする必要があります。私は周りを見回しましたが、解決策はミューテックスを使用することのようですが、よくわかりません。この問題に対する他の解決策/回避策はありますか?
6 に答える
非常に小さな制御ファイル、任意の形式のファイル、txt または XML をこのファイル フラグに追加して作成できます。
いずれかのインスタンスが開始され、フラグが true の場合はアプリケーションを終了し、それ以外の場合はフラグを true に設定します
そして、フラグをtrueに設定したアプリケーションの終了時に、フラグをfalseに戻します
ただし、フラグをロックしたアプリケーションが正常にオフになっている場合、これによりアプリケーションがロックされます。
したがって、最善の方法は、Mutex を使用するか、アプリケーションが接続する共通の場所に小さなサーバー アプリケーションを作成し、ファイルを使用するのと同じ方法でフラグを設定することです。このようにして、アプリケーションが通常とは異なる方法でシャットダウンした場合でも、サーバーはそれを検出でき、フラグの状態を解放して他のインスタンスを開始できるようにします。
編集:
ファイルを使用してフラグを制御し、アプリケーションが正常にシャットダウンしたときに発行します。
TimeStamp
これは、フラグと一緒に使用して修正できます。特定の時間よりも古い場合、つまり、誰もアプリケーションを使用していないため、アプリケーションの使用が許可されています。これには、アプリケーションの実行中にこれを一定期間ごとTimeStamp
に更新することが含まれます。 TimeStamp
、ハートビートのように
オペレーティング システムやネットワーク ファイル システムがこれをサポートしている場合は、ネットワーク ファイル サーバー上に空のファイルを作成し (まだ存在しない場合)、アプリケーションが起動するたびに排他的な書き込みアクセスを要求できます。
アプリケーションに排他的な書き込みアクセスが許可されていない場合、そのアプリケーションは既にネットワーク上の別の場所で実行されている可能性があります。(ここには、誤検知のリスクがあります。おそらく、誰かが好奇心からファイルをエディターで開いただけか、誰かがファイルのアクセス許可を変更した可能性があります。)
アプリケーションが終了すると、ファイル ハンドルを閉じる必要があります。これにより、ファイルの排他ロックが解放されます。
アプリケーションが異常終了した場合でも、OS はプロセスをクリーンアップしてファイル ハンドルを解放し、アプリケーションの別のインスタンスがファイル ロックを要求できるようにします。
(繰り返しますが、これはすべてのオペレーティング システムとネットワーク ファイル サーバー プロトコルで機能するとは限りません。これは、Windows ネットワークと Samba ファイル サーバーで機能するはずです。)
編集:一般的な要求により、この回答は質問者がミューテックスについて言及したことへの回答であることを指摘します。そのため、マシンごとのユーザー数を制限したいと考えていると思います。代わりに、ネットワークの総使用量を制限したい場合、これは適切な方法ではありません。
これが私が現在使用しているものです:
// Mutex object used to determine if there are multiple instances of this program running.
// Note that this is a reference to a .Net Mutex object, not the Windows mutex itself.
private static Mutex _onlyOneInstanceMutex;
/// <summary>
/// Method to test that there is not another instance of the program already running on this
/// machine, or at least in this Terminal Services session or Windows Vista / Windows 7
/// concurrent sessions session. If there is, a message box-style localized error message is
/// displayed and the value false is returned. This implies that this method should only be
/// used in WinForms programs.
///
/// This implementation uses a .Net Mutex object in public storage to prevent it from being
/// garbage-collected. The name of the associated Windows mutex is simply the program name as
/// provided by the caller. Neither the .Net Mutex object nor the Windows mutex are ever
/// explicitly released; they remain in existence, perhaps in an "abandoned" state, until the
/// process that created them terminates.
/// </summary>
/// <returns>false if another instance running, otherwise true</returns>
[SuppressMessage("Microsoft.Reliability", "CA2004:RemoveCallsToGCKeepAlive",
Justification = "Not sure if this is correct or not.")]
public static bool TestOnlyOneInstance(string programName)
{
// Funny construct to prevent the Mutex from being garbage collected
GC.KeepAlive(_onlyOneInstanceMutex);
// Test if we are the first instance, and if so create the Windows mutex, making it
// impossible for subsequent instances to successfully create their mutex
bool firstInstance;
_onlyOneInstanceMutex = new Mutex(false, programName, out firstInstance);
if (firstInstance)
return true;
// Display a (possibly localized) error message, then return
string errorMessage = MLocalizer.GetString("Error1",
"Another instance of this program is already running on this machine.") +
"\n" + MLocalizer.GetString("Error2",
"You cannot run two instances at the same time.") +
"\n" + MLocalizer.GetString("Error3", "Please use the other instance.");
MessageBox.Show(errorMessage, programName, MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
名前付きミューテックスを使用します。それが通常のやり方です。プログラムから名前付きミューテックスを作成します (名前が一意であることを確認してください)。コンストラクターは、パラメーターを使用して新しいミューテックスが作成されたか、既存のミューテックスが開かれたかを通知しout bool createdNew
ます。このフラグが false の場合、プログラムの 1 つのインスタンスが既に実行されています。
Mutex を使用したくない場合は、マシン上のすべてのプロセスをチェックするアプリケーション コードを記述し、同じプロセスが既に見つかっている場合は、アプリケーションを終了することができます。
System.Diagnostic.Process.GetProcesses(); // get a array of processes
ただし、プロセスを名前だけで比較するため、このソリューションには独自のマイナスがあります...
わかりました。追加情報が提供されたので、もう一度試してみます。
これが実行可能かどうかはわかりませんが、サーバー上に「一度に 1 つのロック ファイル」のようなものとして使用されるファイルを用意しない理由はありません。プログラムの開始時に、書き込み用にこのファイルを開きます。動作する場合は、排他ロックを配置する必要があります。動作しない場合は、別のプログラムが現在書き込み用にファイルを開いていることを示しており、「申し訳ありませんが、プログラムは現在別のマシンで実行されています」と言います。それが機能する場合は、プログラムが実行されている限り、ファイルを書き込み用に開いたままにします。おそらく、ファイルを明示的に閉じる必要はありません。これは、プログラムが終了するかクラッシュしたときに自動的に行われるはずです。