次のコードは、アプリケーションのインスタンスを 1 つだけ実行できるようにする単純なシングルトンを実装しています。ただし、別のインスタンスが開始された場合は、そのインスタンスのコマンドライン引数を取得し、それを最初のインスタンスに渡してから、2 番目のインスタンスを終了できる必要があります。
アプリケーションの最初のインスタンスを取得しようとすると、問題が発生します。そのインスタンスのメイン フォームのハンドルを見つけたら、それをControl.FromHandle()
メソッドに渡しMainForm
ます。代わりに、戻り値は常にnull
です。(Control.FromChildHandle()
同じ結果が得られます。)
したがって、私の質問は単純です: 私は何を間違っていますか? そして、これは.NETでも可能ですか?
public class MainForm : Form
{
[DllImport("user32")]
extern static int ShowWindowAsync(IntPtr hWnd, int nCmdShow);
[DllImport("user32")]
extern static bool SetForegroundWindow(IntPtr hWnd);
private Mutex singletonMutex;
private void MainForm_Load(object sender, EventArgs e)
{
bool wasCreated;
singletonMutex = new Mutex(false, Application.ProductName + "Mutex", out wasCreated);
// returns false for every instance except the first
if (!wasCreated)
{
Process thisProcess = Process.GetCurrentProcess();
Process[] peerProcesses = Process.GetProcessesByName(thisProcess.ProcessName.Replace(".vshost", string.Empty));
foreach (Process currentProcess in peerProcesses)
{
if (currentProcess.Handle != thisProcess.Handle)
{
ShowWindowAsync(currentProcess.MainWindowHandle, 1); // SW_NORMAL
SetForegroundWindow(currentProcess.MainWindowHandle);
// always returns null !!!
MainForm runningForm = (MainForm) Control.FromHandle(currentProcess.MainWindowHandle);
if (runningForm != null)
{
runningForm.Arguments = this.Arguments;
runningForm.ProcessArguments();
}
break;
}
}
Application.Exit();
return;
}
}