通过dbus-sharp访问NetworkManager连接设置

本文关键字:连接 设置 NetworkManager 访问 dbus-sharp 通过 | 更新日期: 2023-09-27 18:19:03

我正在运行Arch Linux和以下版本的mcs:

>mcs --version
Mono C# compiler version 4.0.4.0

和以下版本的dbus-sharp

>pacman -Ss dbus-sharp
extra/dbus-sharp 0.8.1-1 [installed] C# implementation of D-Bus
extra/dbus-sharp-glib 0.6.0-1 [installed] C# GLib implementation of D-Bus

这是我的测试程序,基于这里找到的示例代码:https://gist.github.com/Ummon/4317268

我只是想访问当前活动连接的设置,它应该作为'字典{String,字典{String, Variant}}'返回,因为我已经在d-feet工具中检查了org.freedesktop.NetworkManager.Settings.Connection接口

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using DBus;
namespace NetworkManagerDictTest {
    public class MyTest {
        [Interface("org.freedesktop.NetworkManager.Settings.Connection")]
        public interface IConnection {
            IDictionary<string, IDictionary<string, object>> GetSettings();
        }
        readonly static string BUS_NAME = "org.freedesktop.NetworkManager";
        public static void Main(string[] argv) {
            org.freedesktop.DBus.Properties NetworkManagerProps = Bus.System.GetObject<org.freedesktop.DBus.Properties>(BUS_NAME, new ObjectPath("/org/freedesktop/NetworkManager"));
            ObjectPath[] activeConnections = NetworkManagerProps.Get(BUS_NAME, "ActiveConnections") as ObjectPath[];
            if (activeConnections.Length > 0) {
                org.freedesktop.DBus.Properties ActiveConnectionProperties = Bus.System.GetObject<org.freedesktop.DBus.Properties>(BUS_NAME, activeConnections[0]);
                ObjectPath ActiveConnectionPath = ActiveConnectionProperties.Get("org.freedesktop.NetworkManager.Connection.Active", "Connection") as ObjectPath;
                Console.WriteLine("Using connection path: " + ActiveConnectionPath);
                IConnection connection = Bus.System.GetObject<IConnection>(BUS_NAME, ActiveConnectionPath);
                Console.WriteLine("Connection Object ok");
                IDictionary<string, IDictionary<string, object>> settings = connection.GetSettings();
                Console.WriteLine(settings);
            }
        }
    }
}

编译没有错误和警告:

mcs Test.cs -r:/usr/lib/mono/dbus-sharp-2.0/dbus-sharp.dll -r:/usr/lib/mono/dbus-sharp-glib-2.0/dbus-sharp-glib.dll
然而,我的程序在执行过程中崩溃,输出如下:
>mono Test.exe
Using connection path: /org/freedesktop/NetworkManager/Settings/0
Connection Object ok
Unhandled Exception:
DBus.Protocol.MessageReader+PaddingException: Read non-zero byte at position 28 while expecting padding. Value given: 200
  at DBus.Protocol.MessageReader.ReadPad (Int32 alignment) [0x00000] in <filename unknown>:0 
  at DBus.Protocol.MessageReader.ReadStruct (System.Type type) [0x00000] in <filename unknown>:0 
  at DBus.Protocol.MessageReader.ReadValue (System.Type type) [0x00000] in <filename unknown>:0 
  at DBus.Protocol.MessageReader.ReadDictionary[String,IDictionary`2] () [0x00000] in <filename unknown>:0 
  at NetworkManagerDictTest.MyTest+IConnectionProxy.GetSettings () [0x00000] in <filename unknown>:0 
  at NetworkManagerDictTest.MyTest.Main (System.String[] argv) [0x00000] in <filename unknown>:0 
[ERROR] FATAL UNHANDLED EXCEPTION: DBus.Protocol.MessageReader+PaddingException: Read non-zero byte at position 28 while expecting padding. Value given: 200
  at DBus.Protocol.MessageReader.ReadPad (Int32 alignment) [0x00000] in <filename unknown>:0 
  at DBus.Protocol.MessageReader.ReadStruct (System.Type type) [0x00000] in <filename unknown>:0 
  at DBus.Protocol.MessageReader.ReadValue (System.Type type) [0x00000] in <filename unknown>:0 
  at DBus.Protocol.MessageReader.ReadDictionary[String,IDictionary`2] () [0x00000] in <filename unknown>:0 
  at NetworkManagerDictTest.MyTest+IConnectionProxy.GetSettings () [0x00000] in <filename unknown>:0 
  at NetworkManagerDictTest.MyTest.Main (System.String[] argv) [0x00000] in <filename unknown>:0 

我能做些什么来解决这个问题?当我与DBus工作时,我犯了一个错误吗?似乎所有对GetSettings的方法调用都没有问题。在试图修复另一个项目中的bug时,我也遇到了类似的问题,在该项目中,调用GetSettings时会抛出异常。这是否会成为滥用的问题呢?

通过dbus-sharp访问NetworkManager连接设置

看一看源代码,似乎bus-sharp直接从声明的方法的签名推断返回类型。不幸的是,它没有检查我是否使用父类或字典的接口,最终它试图读取一个DBus结构,因为一个回退的情况下,导致异常的DBus结构是8字节填充,而字典使用4字节

用Dictionary替换所有的Dictionary类型很好地解决了我的问题。