通过 dbus-sharp 访问 NetworkManager 连接设置
Accessing NetworkManager Connection Settings through dbus-sharp
我是 运行 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
我只是想访问当前活动连接的设置,它应该作为 'Dict of {String, Dict of {String, Variant}}' 返回,因为我已经在 org.freedesktop.NetworkManager.Settings.Connection 界面的 d-feet 工具中检查过
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 的方法调用都没有问题。我在尝试修复另一个项目中的错误时也遇到了类似的问题,其中 dbus-sharp 在调用 GetSettings 时会抛出异常。这可能是 dbus-sharp 的问题吗?
查看源代码,dbus-sharp 似乎直接从声明方法的签名中推断出 return 类型。不幸的是,它不检查我是否正在使用父 class 或字典的接口,最终它尝试读取 DBus 结构,因为后备情况导致异常,因为 DBus 结构在字典使用时填充了 8 字节4 个字节
用 Dictionary 替换所有 IDictionary 类型工作正常并解决了我的问题。
我是 运行 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
我只是想访问当前活动连接的设置,它应该作为 'Dict of {String, Dict of {String, Variant}}' 返回,因为我已经在 org.freedesktop.NetworkManager.Settings.Connection 界面的 d-feet 工具中检查过
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 的方法调用都没有问题。我在尝试修复另一个项目中的错误时也遇到了类似的问题,其中 dbus-sharp 在调用 GetSettings 时会抛出异常。这可能是 dbus-sharp 的问题吗?
查看源代码,dbus-sharp 似乎直接从声明方法的签名中推断出 return 类型。不幸的是,它不检查我是否正在使用父 class 或字典的接口,最终它尝试读取 DBus 结构,因为后备情况导致异常,因为 DBus 结构在字典使用时填充了 8 字节4 个字节
用 Dictionary 替换所有 IDictionary 类型工作正常并解决了我的问题。