连接到示例 DBus 守护程序的 C# 程序总是得到“访问被拒绝:DBus.BusObject”

Posted

技术标签:

【中文标题】连接到示例 DBus 守护程序的 C# 程序总是得到“访问被拒绝:DBus.BusObject”【英文标题】:C# program connecting to example DBus daemon always gets 'Access is denied: DBus.BusObject' 【发布时间】:2012-11-25 19:25:18 【问题描述】:

对于我们当前的项目,我们使用的是 DBus (1.6.n)。 它主要是在共享内存模式下从 C++ 访问的,而且效果非常好。

我现在正尝试从 C# 程序访问相同的 DBus。

为了先尝试一下,我下载了我能找到的最新版本的 dbus-sharp,并启动了下载中包含的守护程序,看看我是否可以从我的测试 C# 应用程序连接到它。

每当我建立连接时,守护程序控制台都会显示我正在与之通信,但是一旦我尝试访问连接上的任何方法,我就会收到错误;

'访问被拒绝:DBus.BusObject'

这是我尝试过的代码;

        DBus.Bus dBus = null;
        try
        
            //input address comes from the UI and ends up as "tcp:host=localhost,port=12345";
            //dBus = new Bus(InputAddress.Text + inputAddressExtension.Text);
            //string s = dBus.GetId();
            //dBus.Close();

            //DBus.Bus bus = DBus.Bus.System;
            //DBus.Bus bus = Bus.Open(InputAddress.Text + inputAddressExtension.Text);
            //DBus.Bus bus = DBus.Bus.Session;
            //DBus.Bus bus = DBus.Bus.Starter;

            var conn = Connection.Open(InputAddress.Text + inputAddressExtension.Text);
            var bus = conn.GetObject<Introspectable>(@"org.freedesktop.DBus.Introspectable", new ObjectPath("/org/freedesktop/DBus/Introspectable"));

            bus.Introspect();

        
        finally
        
            if(dBus != null)
                dBus.Close();
        

注释的代码最终也会产生同样的错误。

我已经使用调试器,它总是会在 TypeImplementer.cs 中找到以下代码;

公共类型GetImplementation(类型declType) 输入 retT;

        lock (getImplLock)
            if (map.TryGetValue (declType, out retT))
                return retT;

        string proxyName = declType.FullName + "Proxy";

        Type parentType;

        if (declType.IsInterface)
            parentType = typeof (BusObject);
        else
            parentType = declType;

        TypeBuilder typeB = modB.DefineType (proxyName, TypeAttributes.Class | TypeAttributes.Public, parentType);

        if (declType.IsInterface)
            Implement (typeB, declType);

        foreach (Type iface in declType.GetInterfaces ())
            Implement (typeB, iface);

        retT = typeB.CreateType (); <======== Fails here ==========

        lock (getImplLock)
            map[declType] = retT;

        return retT;
    

我没有找到任何关于从 C# 访问 DBus 的有用示例或文档,而且最近似乎很少有关于这方面的条目,所以也许没有其他人在尝试这个。

我在与测试程序相同的文件夹中运行守护程序。 当我在 Windows 上运行时,守护进程正在侦听 tcp 设置;

string addr = "tcp:host=localhost,port=12345";

由于这是下载中包含的示例,我认为它会很简单,但可惜还没有运气。

还有其他人来过这里并知道下一个难题吗?

任何想法都将不胜感激。

【问题讨论】:

更新 - 我已尝试根据 'documentation'! 在与 exe 同名且扩展名为 .conf 的配置文件中添加各种设置。守护进程似乎没有注意到任何这些设置,因为我可以输入任何我喜欢的内容,并且守护进程的运行与以前完全相同。 【参考方案1】:

在没有收到任何评论或回复的情况下,我将使用我在提出问题后找到的信息来回答问题。

DBus 似乎没有有用的 C# 接口。 (通过有用,我的意思是一个有效的!) 我能找到的唯一信息或示例都不是最新的,而且似乎没有付出任何努力来提供工作界面。

我决定使用编写为 Windows 服务的 C++ 实现来与 DBus 交互,我的 C# 程序将通过该服务向 DBus 发送消息。这似乎工作正常,因此可以满足业务需求。

我很失望不能让 C# 到 DBus 工作,但是有很多服务总线实现可以在 Windows 上运行,所以将来我会考虑实现这些而不是 DBus。

如果有人提出了一个可行的、记录在案的解决方案来从 Windows 上的 C# 访问 DBus,我仍然有兴趣看到它。

【讨论】:

【参考方案2】:

当我创建新的测试项目并将 dbus cs 源文件添加到它的主项目程序集中时,我遇到了同样的错误。那是在动态创建的程序集中动态创建 IBusProxy 类型的时候。

asmB = AppDomain.CurrentDomain.DefineDynamicAssembly (new AssemblyName ("NDesk.DBus.Proxies"), canSave ? AssemblyBuilderAccess.RunAndSave : AssemblyBuilderAccess.Run);
modB = asmB.DefineDynamicModule ("NDesk.DBus.Proxies");
......
retT = typeB.CreateType ();

我认为这是因为当前运行的程序集对创建的程序集不友好。就在我添加到项目编译的 NDesk.DBus.dll 时,这个错误消失了。

【讨论】:

以上是关于连接到示例 DBus 守护程序的 C# 程序总是得到“访问被拒绝:DBus.BusObject”的主要内容,如果未能解决你的问题,请参考以下文章

RaspberryPi 蓝牙文件应用程序总是要求在 iOS 上配对

无法从 ubuntu 中的服务连接到会话 dbus

Monit 守护程序 - 连接到 monit 守护程序时出错

通过 TCP 连接到 DBus 服务

无法连接到 Mac OS X 上的 Docker 守护程序

无法连接到 Docker 守护程序。 docker 守护进程是不是在此主机上运行?