C Sharpの応用 - D-Bus

提供:MochiuWiki : SUSE, EC, PCB
2024年2月12日 (月) 06:42時点におけるWiki (トーク | 投稿記録)による版 (→‎サンプルコード)
ナビゲーションに移動 検索に移動

概要

D-Busはメッセージバスシステムであり、ソフトウェアが互いに通信するためのシンプルな方法である。
プロセス間通信に加えて、プロセスのライフサイクルを調整するのに役立つ。
シングルインスタンスのソフトウェアやデーモンをコード化して、そのサービスが必要な時にオンデマンドでソフトウェアやデーモンを起動することにより、シンプルで信頼性の高いものになる。

Tmds.DBusは、dbus-sharpのプロトコル実装の上に構築されており、.NET 4.5で導入された非同期プログラミングモデルに基づく APIを提供している。
このライブラリは .NET Standard 2.0をターゲットとしており、.NET Framework 4.6.1以降、.NET Core / .NET 6以降で実行できる。

dbus-sharp (ndesk-dbusプロジェクトのフォーク) は、Monoと.NET 2.0をターゲットとするC#の実装である。


Tmds.DBus.Protocol

Tmds.DBus.Protocolパッケージは、D-Busプロトコルの低レベルAPIを提供する。
高レベルのTmds.DBusライブラリとは異なり、プロトコルライブラリはネイティブAOTコンパイルで使用できる。

Tmds.DBus.SourceGeneratorは、プロトコルライブラリをターゲットとしたソースジェネレータを提供する。


Tmds.DBusライブラリのインストール

Tmds.DBusライブラリをNuGetからインストールする。
また、Tmds.DBusライブラリはGithubで公開されている。

  • Riderの場合
    1. [ツール]メニューバー - [NuGet] - [<プロジェクト名> の NuGet パッケージを管理]を選択する。
    2. メイン画面下部にNuGetペインが開くので、Tmds.DBusと入力して検索する。
    3. メイン画面右下から、プロジェクト名の右にある[+]ボタンを押下する。
    4. Tmds.DBusライブラリがインストールされる。


次に、dotnetコマンドを実行して、Tmds.DBus.Toolをインストールする。
これにより、各D-BusサービスからC#のインターフェースを自動生成することができる。

NuGetからインストールする場合、インストールに失敗することに注意する。

dotnet tool install -g Tmds.DBus.Tool



D-Busサービスのインターフェースの生成

dotnet dbus listコマンドを実行して、任意のD-Busサービス名を調べる。

# システムバスの場合
dotnet dbus list services --bus system | grep -iE "<D-Busサービス名 (名前の一部でも可能)>"

# セッションバスの場合
dotnet dbus list services --bus session | grep -iE "<D-Busサービス名 (名前の一部でも可能)>"


D-Busサービス名を使用して、D-Busオブジェクト名を調べる。

# システムバスの場合
dotnet dbus list objects --bus system --service <D-Busサービス名> | head -2

# セッションバスの場合
dotnet dbus list objects --bus session --service <D-Busサービス名> | head -2


以下の例では、org.freedesktop.login1.Managerサービスがシステムバス上にあり、
org.freedesktop.login1.Managerサービスを実装した/org/freedesktop/login1オブジェクトにエントリポイントオブジェクトがあることを示している。

# 実行例:
dotnet dbus list objects --bus system --service org.freedesktop.login1 | head -2

# 出力例:
/org/freedesktop/LogControl1 : org.freedesktop.LogControl1
/org/freedesktop/login1 : org.freedesktop.login1.Manager


最後に、dotnet dbus codegenコマンドを実行して、D-Busサービス向けのC#インターフェイスを生成する。

# システムバスの場合
dotnet dbus codegen --bus system --service <D-Busサービス名>

# セッションバスの場合
dotnet dbus codegen --bus session --service <D-Busサービス名>

# 実行例:
dotnet dbus codegen --bus system --service org.freedesktop.login1


C#インターフェイスが記述されているファイルは、現在のカレントディレクトリに<D-Busサービス名のサフィックス>.DBus.csファイルとして生成される。

自動生成されたC#ファイルには、D-Busサービスのインターフェースが記述されている。
このD-Busサービスのインターフェースを使用して、プロキシオブジェクトのインスタンスを生成する。


サンプルコード

以下の例では、Linuxにおいてセッションをログオフしている。

システムバスまたはセッションバスに接続するConnection.SystemStaticであることに注意する。
Connection.SystemおよびConnection.Sessionは、それぞれシステムバスおよびセッションバスへの接続を提供する。
これらのメンバは、アプリケーション全体で同じConnectionクラスを共有する便利な方法を提供している。

各バスへの接続は、最初の使用時に自動的に確立される。
ただし、ステートフル操作 (Connection.RegisterServiceAsync等) は許可されていない。

 using Tmds.DBus;
 using login1.DBus;  // org.freedesktop.login1サービスをもとに自動生成されたC#インターフェース
 
 namespace DBusSample;
 
 internal static class Program
 {
    private static async Task Main(string[] args)
    {
       try
       {
          // D-Busのシステムバスに接続
          var connection = Connection.System;
 
          // ログインマネージャーオブジェクトを取得
          // connection.CreateProxy<<自動生成されたインターフェース名>>("<D-Busサービス名>", new ObjectPath("<D-Busオブジェクト名"));
          var loginManager = connection.CreateProxy<IManager>("org.freedesktop.login1", new ObjectPath("/org/freedesktop/login1"));
 
          // セッションのリストを取得
          var sessions = await loginManager.ListSessionsAsync();
 
          // セッションをログオフする
          foreach (var session in sessions)
          {
             await loginManager.TerminateSessionAsync(session.Item1);
          }
 
          Console.WriteLine("ログオフが完了しました。");
 
        }
        catch (Exception ex)
        {
           Console.WriteLine($"エラー: {ex.Message}");
        }
    }
 }