SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

UWPアプリ開発の最前線

簡単になったUWP Bridge
~Windows 10 1803の新機能「タイムライン」をWPFアプリに実装してみる

UWPアプリ開発の最前線 第6回


  • X ポスト
  • このエントリーをはてなブックマークに追加

多重起動を防ぐためにプロセス間通信を実装する

 ここまでで、プロトコルアクティベーションで起動されたときに指定のURLを表示できるようになりましたが、依然としてアクティベーションされるたびに新しいプロセスが立ち上がってしまいます。

 多重起動に対処するために、プロセス間通信の仕組みを導入します。プロセス間通信のサーバーとクライアントを同じWPFアプリが兼ねるようにして、クライアント側からURLを投げ、サーバー側ではそれを受け取って表示するようにします。この仕組みができたら、2番目に起動されたプロセスはクライアントとなってサーバーに処理を渡し、自分は終了してしまうことで、多重起動を防げます。

 プロセス間通信の仕組みは、名前付きパイプを使ったWCF(Windows Communication Foundation)にしました。コードの全体は「IpcService.cs」ファイルを見てください。その概要は次のようになっています。

プロセス間通信のコードの概要
// System.ServiceModel アセンブリへの参照追加が必要

// サービスの定義
[ServiceContract]
public interface INavigationService
{
  [OperationContract]
  void Navigate(string url);
}

// サーバー側
public class IpcServer : INavigationService
{
  // サービスの実装(WCFを通じてクライアント側から呼び出される)
  public void Navigate(string url)
  {
    // ……省略……

    // URL の Web ページを表示
    if (!string.IsNullOrWhiteSpace(url))
      mainWindow.Navigate(url);
  }

  // サーバーを起動するメソッド
  public static void StartService()
  {
    // ……省略……
  }
}

// クライアント側
public class IpcClient
{
  // サーバーにリクエストを投げるメソッド(成功したらtrueを返す)
  public static bool RequestNavigation(string url)
  {
    // ……省略……

    // サービスを呼び出し
    navigationService.Navigate(url);
    return true;

    // ……省略……
  }
}

 アプリが起動されたら、まずIpcClient(クライアント側)のRequestNavigationメソッドを呼び出してみます。呼び出しが成功したら(=サーバーと交信できたら)、すでに他のプロセスが動いていたということですから、自分は終了します。呼び出しに失敗したときは、まだ他のプロセスが動いていないということですから、IpcServer(サーバー側)のStartServiceメソッドを呼び出して自分がサーバーになります。

多重起動を防止する

 上記のプロセス間通信の仕組みを使って、多重起動を防止します。起動時にサーバーにリクエストを投げてみて、成功したら自分は終了する、失敗したときは自分がサーバーになるというコードをMain関数に組み込みます(次のコード、Appクラス内)。

多重起動の防止を追加したMain関数
[STAThread]
public static void Main(string[] args)
{
  // プロトコルアクティベーションで起動されたときの、表示すべきURL
  string protocolActivationUrl = GetProtocolActivationUrl();

  // サーバーにリクエストを投げてみる
  if (IpcClient.RequestNavigation(protocolActivationUrl))
  {
    // サーバーとの通信に成功した == 多重起動である
    // 多重起動の場合は、アプリを終了する
    return;
  }

  App app = new App();
  app.Startup += OnStartup;
  app.InitializeComponent();
  app.Run();

  return; // 以下はローカル関数のみ

  string GetProtocolActivationUrl()
  {
    // ……省略……
  }

  void OnStartup(object sender, StartupEventArgs e)
  {
    // プロセス間通信のサーバーを起動する
    IpcServer.StartService();

    // MainWindowを表示する
    MainWindow mainWindow = new MainWindow();
    mainWindow.Show();
    if (protocolActivationUrl != null)
      // プロトコルアクティベーションのときは、そのURLを表示する
      mainWindow.Navigate(protocolActivationUrl);
  }
}

 これで、アプリが実行中に「タイムライン」からプロトコルアクティベーションを受けても、実行中のウインドウにそのWebページが表示されるようになります。

 なお、上のコードでは、IpcClient.RequestNavigationメソッド呼び出しとIpcServer.StartServiceメソッド呼び出しの間に別のサーバーが起動してしまうという、本当に運の悪いことが起きる可能性がゼロではありません。その場合は複数のプロセスが起動してしまうことになりますが、今回は気にしないことにしました。そこも気になる方は、MutexなりSemaphoreなりを使ったプロセス間の排他処理を加えてください(ロックの取得に失敗したら、サーバーが動いているはずなので、リクエストを投げて自身を終了させる)。

まとめ

 Widnows 10 1803の新機能「タイムライン」をWPFアプリで利用するために、デスクトップブリッジを使いました。インストール時に独自の処理を必要としないアプリなら、ものすごく簡単に「UWPアプリ化」できることがお分かりいただけたかと思います。なお、「タイムライン」に登録する方法やその表示をカスタマイズする方法については前回で詳しく解説しましたので、そちらをご覧ください。

UWPアプリに興味が湧いてきた人へ

 Windowsデスクトップ用アプリの開発はWindows Formsなら経験があるけど、ちょっとUWPアプリ開発も気になってきたという方へ。ぴったりの電子書籍を書きました!

UWP アプリ開発 101 第2版: Windows Forms 開発者のための C# / XAML による UWP アプリ開発入門』 (BluewaterSoft 2017/7/1)
Kindle版UWPアプリ版があります。
・どちらも無料で最初の方を読めるので、とりあえず試し読みをしてみてください。

 また、Microsoft公式のチュートリアルやたくさんのサンプルコードなどもあります。UWPアプリの開発環境を整えてUWPアプリのプロジェクトを作れるようになったら、これらのドキュメントやサンプルも参考にしてみてください。

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
UWPアプリ開発の最前線連載記事一覧

もっと読む

この記事の著者

biac(ばいあっく)

HONDA R&Dで自動車の設計をやっていた機械屋さんが、技術の進化スピードに魅かれてプログラマーに。以来30年ほど、より良いコードをどうやったら作れるか、模索の人生。わんくま同盟の勉強会(名古屋)で、よく喋ってたりする。2014/10~2019/6 Microsoft MVP (Windows Devel...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/10810 2019/11/10 21:18

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング