■101191 |
Re[4]: タスクトレイ常駐アプリにおいて多重起動を禁止しアクティブ化 |
□投稿者/ 魔界の仮面弁士 -(2023/01/17(Tue) 10:34:43)
| ■No101181 (魔界の仮面弁士) に追記 >> これを多重起動を検知した際に呼び出せるような方法はないですかね。 > 別プロセスのメソッドを呼び出したいという話なら、 > WCF もしくは .NET Remoting とか。
WCF で通信してみるサンプル。 参照設定で "System.ServiceModel" を加えておきます。
// ===== ISampleService.cs ===== // System.ServiceModel; [ServiceContract] public interface ISampleService { [OperationContract] void ShowAndActive(); }
// ===== Form1.cs (抜粋) ===== // using System; using System.Runtime.InteropServices; using System.Windows.Forms;
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] public partial class Form1 : Form, ISampleService { // 外部から呼び出したい処理 // 今回は Form1 自身に ISampleService を直接実装している void ISampleService.ShowAndActive() { this.Visible = true; if (this.WindowState == FormWindowState.Minimized) { const int SW_RESTORE = 9; ShowWindowAsync(this.Handle, SW_RESTORE); } this.Activate(); } [DllImport("user32")] private static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow); }
// ===== Program.cs ===== // using System; using System.ServiceModel; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms;
internal static class Program { private static readonly string NetTcpUrl = "net.tcp://localhost:8089"; private static Mutex mutex;
[STAThread] static void Main() { mutex = new Mutex(false, "Wankuma101173"); if (mutex.WaitOne(0, false)) { // まだ起動されていない時の処理
Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); var mainForm = new Form1();
var netTcpUrl = new Uri(NetTcpUrl); var contract = typeof(ISampleService); // ServiceContract 属性付きのインターフェイスを指定 var host = new ServiceHost(mainForm, netTcpUrl); host.AddServiceEndpoint(contract, new NetTcpBinding(), "/nettcp"); host.Open();
Application.Run(mainForm); } else { // 既に起動されていた時の処理 // フォームを表示する必要は無いので、Form1 は new しない CallNetTcpBinding(); } }
private static void CallNetTcpBinding() { var channel = default(IClientChannel); var binding = new NetTcpBinding(); var factory = new ChannelFactory<ISampleService>(binding, new EndpointAddress(NetTcpUrl + "/nettcp")); factory.Open(); try { var client = factory.CreateChannel(); channel = (IClientChannel)client; channel.Open();
client.ShowAndActive(); // 既存プロセスの ISampleService.ShowAndActive メソッドを呼び出す
channel.Close(); } finally { factory.Close(); } } }
---
なお、WCF は .NET Framework 向けのものであり、.NET/.NET Core ではサポートされていませんが、 代わりに CoreWCF を使うことができます。(CoreWCF は .NET Framework でも使用できます)
https://www.nuget.org/packages?q=CoreWCF https://github.com/CoreWCF/CoreWCF/blob/main/Documentation/Microsoft-Support.md https://github.com/CoreWCF/samples/tree/main/Scenarios/Getting-Started-with-CoreWCF |
|