📢 Webサイト閉鎖と移転のお知らせ
このWebサイトは2026年9月に閉鎖いたします。
新しい記事は移転先で追加しております。(旧サイトでは記事を追加しておりません)
ページの作成:「== 概要 == dbus-sharp (ndesk-dbusプロジェクトのフォーク) は、Monoと.NET 2.0をターゲットとするC#の実装である。<br> <br> Tmds.DBusは、dbus-sharpのプロトコル実装の上に構築されており、.NET 4.5で導入された非同期プログラミングモデルに基づく APIを提供している。<br> このライブラリは .NET Standard 2.0をターゲットとしており、.NET Framework 4.6.1以降、.NET Core / .NET 6…」 |
|||
| (同じ利用者による、間の11版が非表示) | |||
| 1行目: | 1行目: | ||
== 概要 == | == 概要 == | ||
D-Busはメッセージバスシステムであり、ソフトウェアが互いに通信するためのシンプルな方法である。<br> | |||
プロセス間通信に加えて、プロセスのライフサイクルを調整するのに役立つ。<br> | |||
シングルインスタンスのソフトウェアやデーモンをコード化して、そのサービスが必要な時にオンデマンドでソフトウェアやデーモンを起動することにより、シンプルで信頼性の高いものになる。<br> | |||
<br> | <br> | ||
Tmds.DBusは、dbus-sharpのプロトコル実装の上に構築されており、.NET 4.5で導入された非同期プログラミングモデルに基づく APIを提供している。<br> | Tmds.DBusは、dbus-sharpのプロトコル実装の上に構築されており、.NET 4.5で導入された非同期プログラミングモデルに基づく APIを提供している。<br> | ||
このライブラリは .NET Standard 2.0をターゲットとしており、.NET Framework 4.6.1以降、.NET Core / .NET 6以降で実行できる。<br> | このライブラリは .NET Standard 2.0をターゲットとしており、.NET Framework 4.6.1以降、.NET Core / .NET 6以降で実行できる。<br> | ||
<br> | |||
dbus-sharp (ndesk-dbusプロジェクトのフォーク) は、Monoと.NET 2.0をターゲットとするC#の実装である。<br> | |||
<br><br> | <br><br> | ||
== Tmds DBusライブラリのインストール == | == Tmds.DBus.Protocol == | ||
Tmds.DBus.Protocolパッケージは、D-Busプロトコルの低レベルAPIを提供する。<br> | |||
高レベルのTmds.DBusライブラリとは異なり、プロトコルライブラリはネイティブAOTコンパイルで使用できる。<br> | |||
<br> | |||
Tmds.DBus.SourceGeneratorは、プロトコルライブラリをターゲットとしたソースジェネレータを提供する。<br> | |||
<br><br> | |||
== Tmds.DBusライブラリのインストール == | |||
Tmds.DBusライブラリをNuGetからインストールする。<br> | Tmds.DBusライブラリをNuGetからインストールする。<br> | ||
また、Tmds.DBusライブラリは[https://github.com/tmds/Tmds.DBus Github]で公開されている。<br> | また、Tmds.DBusライブラリは[https://github.com/tmds/Tmds.DBus Github]で公開されている。<br> | ||
| 13行目: | 24行目: | ||
*# メイン画面下部にNuGetペインが開くので、<u>Tmds.DBus</u>と入力して検索する。 | *# メイン画面下部にNuGetペインが開くので、<u>Tmds.DBus</u>と入力して検索する。 | ||
*# メイン画面右下から、プロジェクト名の右にある[+]ボタンを押下する。 | *# メイン画面右下から、プロジェクト名の右にある[+]ボタンを押下する。 | ||
* | *# Tmds.DBusライブラリがインストールされる。 | ||
<br> | <br> | ||
次に、<code>dotnet</code>コマンドを実行して、Tmds.DBus.Toolをインストールする。<br> | 次に、<code>dotnet</code>コマンドを実行して、Tmds.DBus.Toolをインストールする。<br> | ||
これにより、各D-BusサービスからC#のインターフェースを自動生成することができる。<br> | |||
<br> | |||
<u>NuGetからインストールする場合、インストールに失敗することに注意する。</u><br> | <u>NuGetからインストールする場合、インストールに失敗することに注意する。</u><br> | ||
dotnet tool install -g Tmds.DBus.Tool | dotnet tool install -g Tmds.DBus.Tool | ||
| 22行目: | 35行目: | ||
== D-Busサービスのインターフェースの生成 == | == D-Busサービスのインターフェースの生成 == | ||
<code>dotnet dbus list</code>コマンドを実行して、任意のD-Busサービス名を調べる。<br> | <code>dotnet dbus list</code>コマンドを実行して、任意のD-Busサービス名を調べる。<br> | ||
# システムバスの場合 | |||
dotnet dbus list services --bus system | grep -iE "<D-Busサービス名 (名前の一部でも可能)>" | dotnet dbus list services --bus system | grep -iE "<D-Busサービス名 (名前の一部でも可能)>" | ||
# セッションバスの場合 | |||
dotnet dbus list services --bus session | grep -iE "<D-Busサービス名 (名前の一部でも可能)>" | |||
<br> | <br> | ||
D-Busサービス名を使用して、D-Busオブジェクト名を調べる。<br> | D-Busサービス名を使用して、D-Busオブジェクト名を調べる。<br> | ||
# システムバスの場合 | |||
dotnet dbus list objects --bus system --service <D-Busサービス名> | head -2 | dotnet dbus list objects --bus system --service <D-Busサービス名> | head -2 | ||
<br> | |||
# セッションバスの場合 | |||
dotnet dbus list objects --bus session --service <D-Busサービス名> | head -2 | |||
<br> | |||
以下の例では、org.freedesktop.login1.Managerサービスがシステムバス上にあり、<br> | |||
org.freedesktop.login1.Managerサービスを実装した/org/freedesktop/login1オブジェクトにエントリポイントオブジェクトがあることを示している。<br> | |||
# 実行例: | # 実行例: | ||
dotnet dbus list objects --bus system --service org.freedesktop.login1 | head -2 | dotnet dbus list objects --bus system --service org.freedesktop.login1 | head -2 | ||
| 33行目: | 56行目: | ||
/org/freedesktop/LogControl1 : org.freedesktop.LogControl1 | /org/freedesktop/LogControl1 : org.freedesktop.LogControl1 | ||
/org/freedesktop/login1 : org.freedesktop.login1.Manager | /org/freedesktop/login1 : org.freedesktop.login1.Manager | ||
<br> | <br> | ||
最後に、<code>dotnet dbus codegen</code>コマンドを実行して、D-Busサービス向けのC#インターフェイスを生成する。<br> | 最後に、<code>dotnet dbus codegen</code>コマンドを実行して、D-Busサービス向けのC#インターフェイスを生成する。<br> | ||
# システムバスの場合 | |||
dotnet dbus codegen --bus system --service <D-Busサービス名> | 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 | dotnet dbus codegen --bus system --service org.freedesktop.login1 | ||
<br> | <br> | ||
C#インターフェイスが記述されているファイルは、現在のカレントディレクトリに<u><D-Busサービス名のサフィックス>.DBus.cs</u>ファイルとして生成される。<br> | |||
<br> | <br> | ||
自動生成されたC#ファイルには、D-Busサービスのインターフェースが記述されている。<br> | 自動生成されたC#ファイルには、D-Busサービスのインターフェースが記述されている。<br> | ||
| 49行目: | 73行目: | ||
<br><br> | <br><br> | ||
== | == D-Busの呼び出し (クライアント側) == | ||
以下の例では、Linuxにおいてセッションをログオフしている。<br> | |||
<br> | |||
システムバスまたはセッションバスに接続する<code>Connection.System</code>は<code>Static</code>であることに注意する。<br> | |||
<code>Connection.System</code>および<code>Connection.Session</code>は、それぞれシステムバスおよびセッションバスへの接続を提供する。<br> | |||
これらのメンバは、アプリケーション全体で同じ<code>Connection</code>クラスを共有する便利な方法を提供している。<br> | |||
<br> | |||
各バスへの接続は、最初の使用時に自動的に確立される。<br> | |||
ただし、ステートフル操作 (<code>Connection.RegisterServiceAsync</code>等) は許可されていない。<br> | |||
<br> | |||
<u>※注意</u><br> | |||
<u>実行アプリケーションは特定のD-Busサービスを要求する時、該当するD-Busサービスがまだ起動していない場合において、<code>Connection</code>クラスの<code>ActivateServiceAsync</code>メソッドを実行することにより、</u><br> | |||
<u>指定したD-Busサービス名に対してD-Busデーモンにリクエストを送信して、該当サービスの起動を試みる。</u><br> | |||
<u>これは、D-Busサービスの遅延起動(必要になるまでサービスが起動されない)を可能にするためのものである。</u><br> | |||
<br> | |||
<u>D-Busサービスがオンデマンドで実行されるように設計されている場合に特に有用である。</u><br> | |||
したがって<u>、D-Busサービスは使用される必要がある時にのみ起動されるため、リソースの節約に役立つ。</u><br> | |||
<br> | |||
<syntaxhighlight lang="c#"> | |||
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")); | |||
// D-Busサービスのヘルパーファイルが起動していない場合、ヘルパーファイルを起動する | |||
// 常に起動しているD-Busサービスにおいては不要である | |||
//await connection.ActivateServiceAsync("<D-Busサービス名>"); | |||
// セッションのリストを取得 | |||
var sessions = await loginManager.ListSessionsAsync(); | |||
// セッションをログオフする | |||
foreach (var session in sessions) | |||
{ | |||
await loginManager.TerminateSessionAsync(session.Item1); | |||
} | |||
Console.WriteLine("ログオフが完了しました。"); | |||
} | |||
catch (Exception ex) | |||
{ | |||
Console.WriteLine($"エラー: {ex.Message}"); | |||
} | |||
} | |||
} | |||
</syntaxhighlight> | |||
<br><br> | |||
== D-Busヘルパーファイル == | |||
==== D-Busヘルパーファイルのサンプルコード ==== | |||
D-Busヘルパーファイルは、以下に示すような順で処理を記述する。<br> | |||
# D-Busシステムバス、または、D-Busセッションバスに接続する。 | |||
#: <code>Connection</code>クラスの<code>ConnectAsync</code>メソッド | |||
# D-Busオブジェクトを登録する。 | |||
#: <code>Connection</code>クラスの<code>RegisterObjectAsync</code>メソッド、または、<code>RegisterObjectsAsync</code>メソッド | |||
# D-Busサービスを登録する。 | |||
#: <code>Connection</code>クラスの<code>RegisterServiceAsync</code>メソッド | |||
# D-Busサービスが呼び出されてヘルパーファイルが実行されるまで待機する。<br>また、一定時間内に呼び出しが無い場合は、D-Busサービスを終了することを推奨する。 | |||
#: 一定時間のみ待機する場合 (例: 30[Sec]) | |||
#: <code>await Task.Delay(1000 * 30)</code> | |||
#: <br> | |||
#: PCをシャットダウンするまで待機する場合 | |||
#: <code>while (true) { await Task.Delay(int.MaxValue) }</code> | |||
<br> | |||
以下の例で使用しているD-Busヘルパーファイルのインターフェースは、以下に示すような構造をしている。<br> | |||
<syntaxhighlight lang="xml"> | |||
<node> | |||
<interface name="com.example.MyInterface"> | |||
<method name="SayHello"> | |||
</method> | |||
<method name="Add"> | |||
<arg type="i" name="x" direction="in"/> | |||
<arg type="i" name="y" direction="in"/> | |||
<arg type="i" name="sum" direction="out"/> | |||
</method> | |||
</interface> | |||
</node> | |||
</syntaxhighlight> | |||
<br> | |||
<syntaxhighlight lang="c#"> | |||
using Tmds.DBus; | |||
namespace DBusHelper; | |||
// D-Busインターフェースの定義 | |||
[DBusInterface("com.example.MyInterface")] // D-Busインターフェース名を指定する 例: com.example.MyInterface | |||
public interface IMyInterface : IDBusObject | |||
{ | |||
Task SayHelloAsync(); | |||
Task<int> AddAsync(int x, int y); | |||
} | |||
// D-Busサービスの定義 | |||
public class MyObject : IMyInterface | |||
{ | |||
// D-Busオブジェクト名 | |||
public ObjectPath ObjectPath { get; } = new ObjectPath("/com/example/MyObject"); | |||
// 各D-Busインターフェースの詳細な定義 | |||
public async Task SayHelloAsync() | |||
{ | |||
await Task.Run(() => Console.WriteLine("Hello from D-Bus server!")); | |||
} | |||
public async Task<int> AddAsync(int x, int y) | |||
{ | |||
return await Task.Run(() => x + y); | |||
} | |||
public Task<IDisposable> WatchPropertiesAsync(Action<PropertyChanges> onChanged) | |||
{ | |||
return Task.FromResult<IDisposable>(null!); | |||
} | |||
public Task<PropertyChanges> GetAllAsync() | |||
{ | |||
return Task.FromResult(new PropertyChanges()); | |||
} | |||
} | |||
class Program | |||
{ | |||
static async Task Main(string[] _) | |||
{ | |||
// D-Busシステムバスを使用 | |||
// D-Busセッションバスを使用する場合は、Address.Sessionを使用すること | |||
var connection = new Connection(Address.System); | |||
await connection.ConnectAsync(); | |||
try | |||
{ | |||
// D-Busオブジェクトを登録 | |||
var myObject = new MyObject(); | |||
await connection.RegisterObjectAsync(myObject); | |||
// D-Busサービスを登録 | |||
const string helperServiceName = "com.example.MyObject"; | |||
await connection.RegisterServiceAsync(helperServiceName); | |||
Console.WriteLine("D-Bus server is start."); | |||
// D-Busヘルパーファイルの起動時間を指定 例: 30[Sec] | |||
await Task.Delay(1000 * 30); | |||
Console.WriteLine("Terminates the D-Bus server."); | |||
} | |||
catch (Exception e) | |||
{ | |||
Console.WriteLine($"{e.Message}"); | |||
} | |||
finally | |||
{ | |||
// 登録したD-BusサービスおよびD-Busオブジェクトを削除 | |||
connection.Dispose(); | |||
} | |||
} | |||
} | |||
</syntaxhighlight> | |||
<br> | |||
==== D-Busセッションバスを使用する場合 ==== | |||
セッションバス向けD-Busサービスファイルを作成する。<br> | |||
sudo vi /usr/share/dbus-1/services/<任意の名前>.service | |||
<br> | |||
<syntaxhighlight lang="ini"> | |||
# /usr/share/dbus-1/services/<任意の名前>.serviceファイル | |||
[D-BUS Service] | |||
Name=<D-Busサービス名> | |||
Exec=<D-Busヘルパーファイルのパス> | |||
</syntaxhighlight> | |||
<br> | |||
==== D-Busシステムバスを使用する場合 ==== | |||
まず、システムバス向けD-Busサービスファイルを作成する。<br> | |||
sudo vi /usr/share/dbus-1/system-services/<任意の名前>.service | |||
<br> | |||
<syntaxhighlight lang="ini"> | |||
# /usr/share/dbus-1/system-services/<任意の名前>.serviceファイル | |||
[D-BUS Service] | |||
Name=<D-Busサービス名> | |||
Exec=<D-Busヘルパーファイルのパス> | |||
User=root | |||
</syntaxhighlight> | |||
<br> | |||
次に、PolicyKit (PolKit) の動作するために必要なセキュリティポリシーを設定する。<br> | |||
sudo vi /usr/share/dbus-1/system.d/<任意の名前>.conf | |||
<br> | |||
<syntaxhighlight lang="xml"> | |||
# /usr/share/dbus-1/system.d/<任意の名前>.confファイル | |||
<policy user="root"> | |||
<allow own="<D-Busサービス名>"/> | |||
</policy> | |||
<policy context="default"> | |||
<allow send_destination="<D-Busサービス名>"/> | |||
</policy> | |||
</syntaxhighlight> | |||
<br><br> | <br><br> | ||