📢 Webサイト閉鎖と移転のお知らせ
このWebサイトは2026年9月に閉鎖いたします。
新しい記事は移転先で追加しております。(旧サイトでは記事を追加しておりません)

102行目: 102行目:
D-Bus経由でSystemdと直接通信するため、より柔軟で、プログラム内から制御できるようになっている。<br>
D-Bus経由でSystemdと直接通信するため、より柔軟で、プログラム内から制御できるようになっている。<br>
<br>
<br>
ただし、さんぷるコードを実行するには、適切な権限が必要となる。<br>
ただし、サンプルコードを実行するには、適切な権限が必要となる。<br>
  <syntaxhighlight lang="c++">
  <syntaxhighlight lang="c++">
#include <iostream>
#include <string>
  #include <sdbus-c++/sdbus-c++.h>
  #include <sdbus-c++/sdbus-c++.h>
  #include <iostream>
  // #include <atomic>
// std::atomic<bool> g_shouldExit(false);
// UnitStateChangedシグナルハンドラ
// ただし、Systemdサービスはシグナルを送信しないため、今回は設定しない
// void onUnitStateChanged(sdbus::Signal signal)
// {
//    std::string unitName, newState, oldState;
//    signal >> unitName >> newState >> oldState;
//    std::cout << "Unit " << unitName << " changed state from " << oldState << " to " << newState << std::endl;
//    if (unitName == "smb.service" && (newState == "active" || newState == "failed")) {
//        g_shouldExit.store(true);
//    }
// }
// smb.serviceが正常に開始されているかどうかを確認する
bool checkServiceStatus(sdbus::IProxy &systemdProxy, sdbus::InterfaceName &interfaceName, const std::string &serviceName)
{
    try {
      // smb.serviceのユニットパスを取得する
      sdbus::MethodName methodName{"GetUnit"};
      auto method = systemdProxy.createMethodCall(interfaceName, methodName);
      method << serviceName;
      auto reply = systemdProxy.callMethod(method);
      sdbus::ObjectPath unitPath;
      reply >> unitPath;
      // 取得したsmb.serviceのユニットパスを使用して、smb.serviceの開始状態を取得
      auto unitProxy = sdbus::createProxy(systemdProxy.getConnection(), std::move(sdbus::ServiceName{"org.freedesktop.systemd1"}), unitPath);
      auto getProperty = unitProxy->createMethodCall(sdbus::InterfaceName{"org.freedesktop.DBus.Properties"}, sdbus::MethodName{"Get"});
      getProperty << "org.freedesktop.systemd1.Unit" << "ActiveState";
      auto propertyReply = unitProxy->callMethod(getProperty);
      sdbus::Variant variant;
      propertyReply >> variant;
      std::string state = variant.get<std::string>();
      return (state == "active");
    }
    catch (const sdbus::Error &e) {
      // sdbus::Errorをキャッチしてエラーメッセージを表示
      std::cerr << "Error checking service status: " << e.getName() << " - " << e.getMessage() << std::endl;
      return false;
    }
    catch (const std::exception &e) {
      // std::exceptionをキャッチして一般エラーを処理
      std::cerr << "Error: " << e.what() << std::endl;
      return false;
    }
}
   
   
  int main()
  int main(int argc, char *argv[])
  {
  {
    // システムバスへの接続を作成
    auto connection = sdbus::createSystemBusConnection();
    // Systemdサービスのマネージャーインターフェースへのプロキシオブジェクトを作成
    sdbus::ServiceName destination("org.freedesktop.systemd1");
    sdbus::ObjectPath  objectPath("/org/freedesktop/systemd1");
    auto systemdProxy = sdbus::createProxy(*connection, std::move(destination), std::move(objectPath));
    // D-Busインターフェース名を指定
    sdbus::InterfaceName interfaceName("org.freedesktop.systemd1.Manager");
    // UnitStateChangedシグナルのハンドラを登録
    // ただし、Systemdサービスはシグナルを送信しないため、今回は設定しない
    //sdbus::SignalName    signalName("UnitStateChanged");
    //systemdProxy->registerSignalHandler(interfaceName, signalName, &onUnitStateChanged);
     try {
     try {
        // D-Busへの接続を作成
      // "StartUnit"はSystemdサービスのメソッド名
        auto connection = sdbus::createSystemBusConnection();
      sdbus::MethodName methodName{"StartUnit"};
      auto method = systemdProxy->createMethodCall(interfaceName, methodName);
   
   
        // Systemdのマネージャーインターフェースへのプロキシオブジェクトを作成
      // "smb.service"は開始するSystemdサービス名
        auto proxy = sdbus::createProxy(*connection,
      // "replace"はSystemdサービスの起動モード
                                        "org.freedesktop.systemd1",
      method << "smb.service" << "replace";
                                        "/org/freedesktop/systemd1");
      auto reply = systemdProxy->callMethod(method);
   
   
        // StartUnitメソッドを呼び出してsmbサービスを開始
      sdbus::ObjectPath jobPath;
        // "StartUnit"はSystemdサービスのメソッド名
      reply >> jobPath;
        // "org.freedesktop.systemd1.Manager"はD-Busインターフェース名
      std::cout << "StartUnit job path: " << jobPath << std::endl;
        // "smb.service"は開始するSystemdサービス名
        // "replace"はSystemdサービスの起動モード
        proxy->callMethod("StartUnit")
              .onInterface("org.freedesktop.systemd1.Manager")
              .withArguments("smb.service", "replace")
              .storeResultsTo();
   
   
        std::cout << "smb service started successfully." << std::endl;
      std::string serviceName = "smb.service";
      if (checkServiceStatus(*systemdProxy, interfaceName, serviceName)) {
          std::cout << "Service " << serviceName << " state: " << "avtive" << std::endl;
      }
     }
     }
     catch (const sdbus::Error &e) {
     catch (const sdbus::Error &e) {
       // sdbus::Errorをキャッチしてエラーメッセージを表示
       // sdbus::Errorをキャッチしてエラーメッセージを表示
       std::cerr << "D-Bus error: " << e.what() << std::endl;
       std::cerr << "Error starting smb.service: " << e.getName() << " - " << e.getMessage() << std::endl;
       return -1;
       return -1;
     }
     }
145行目: 214行目:
  </syntaxhighlight>
  </syntaxhighlight>
<br>
<br>
==== 使用例 : ユーザ定義のD-Busサービスの実行 ====
==== 使用例 : ユーザ定義のD-Busサービスの実行 ====
===== D-Busサービス =====
===== D-Busサービス =====