【问题标题】:Consume WCF Service over named pipe hosted in WPF app from Windows Service通过 Windows 服务的 WPF 应用程序中托管的命名管道使用 WCF 服务
【发布时间】:2018-05-17 07:17:18
【问题描述】:

我在 WPF 应用程序中托管 WCF 服务,该应用程序使用命名管道更新 GUI。在 Windows 服务中,我使用此 WCF 服务来更新 GUI。

我使用以下代码将它托管在我的 WPF 应用程序中:

private ServiceHost serviceHost;

public MainWindow()
{
    InitializeComponent();

    try
    {
        string address = "net.pipe://localhost/Path/ServiceName";
        serviceHost = new ServiceHost(typeof(ComGUIService));
        NetNamedPipeBinding binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None);
        serviceHost.AddServiceEndpoint(typeof(IComService), binding, address);
        serviceHost.Open();

    }
    catch (Exception ex)
    {
        // TODO: Logging & Handling
    }
}

并在我的 Windows 服务中使用它:

string address = "net.pipe://localhost/Path/ServiceName";

NetNamedPipeBinding binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None);
EndpointAddress ep = new EndpointAddress(address);

IComService channel =
    ChannelFactory<IComService>.CreateChannel(
        binding, ep
    );

try
{
    channel.SendUpdatedStatus("test");
}
catch (Exception e)
{
    // Throws: The pipe endpoint net.pipe://localhost/... could not be found on your local machine
}

System.IO.PipeException:在 net.pipe://localhost/... 上没有可以接受消息的端点监听

奇怪的是,完全相同的代码在控制台应用程序中执行并且与 WPF 应用程序的通信成功时工作。 Windows 服务和桌面应用程序之间通过命名管道进行的通信有什么特别之处吗?这甚至可能吗?

【问题讨论】:

  • 这很像一个安全问题。默认情况下,运行 Windows 服务的用户帐户是 LocalService,它几乎没有权限并且可能无法将命名管道连接到任何东西。尝试在您自己的帐户下启动该服务,我想您会看到它有效。必须小心地为 Windows 服务找到合适的帐户来运行,否则您将打开一个安全漏洞。
  • @AQuirky 除了这个问题,我已经使用启动 WPF 应用程序的同一帐户运行它。没有成功。
  • 好的。我完全按照您在此处显示的那样编写了一个 Windows 服务和一个 WPF 客户端,即使在默认的 LocalService 帐户下也可以正常工作。所以我觉得问题出在你实现服务的方式上。我做了绝对最低限度的工作:在 OnStart 的新线程上创建的服务循环。建立连接后的服务循环连续循环,延迟1秒发送“测试”,一切正常。
  • @AQuirky 非常感谢您的测试。明天我将尝试设置一个新服务并从头开始。
  • @AQuirky 不幸的是我没有运气。您是否为您的服务创建了 ProjectInstaller?你的设置是什么?您使用的是哪个 .NET 版本?

标签: c# wpf wcf named-pipes


【解决方案1】:

我设法让它工作。我唯一要做的就是以管理权限运行 WPF 应用程序。为什么这些应用程序之间的通信仅在 WPF 应用程序以管理员身份运行时才有效仍然是一个谜。

【讨论】:

  • 嗯,你得给我一点信任。我对您的第一条评论是这可能是一个安全问题。不过现在不能放弃!我的 WPF 应用程序在没有管理员的情况下可以正常通信,并且我的服务在 LocalService 帐户下运行。比它不工作更糟糕的是它工作并给你的安全打开了一个大漏洞。
【解决方案2】:

我遇到了同样的问题。问题是您的服务在作为服务运行时在会话 0 中运行,而您的应用程序在会话 2 中运行。当将服务作为控制台运行时,您会看到它在工作,因为两个应用程序都在同一个会话 2 下运行(不需要额外的权限)。命名管道必须在共享内存空间中创建,服务才能真正看到命名管道,当它们运行不同的会话时,您会看到这个问题突然出现。解决方案是简单地允许必要的用户/组“创建本地对象”权限。进入组策略编辑器。 Windows 设置 -> 安全设置 -> 本地策略 -> 用户权限分配 -> 创建全局对象(将用户组添加到此权限,你应该很高兴!)。祝你好运!

【讨论】:

  • 非常感谢您的洞察力。在我可以使用此设置之前,我必须仔细检查此策略对用户组是否安全。
  • 我明白了。我正在与一位不愿更改烫发的客户打交道,因此我正在寻找其他选择。一件事也可能有效,我没有尝试过....我认为如果您将 UI 连接到您的服务(会话 2 到会话 0),您可能不需要此权限。如果您想“推送”到您的 UI,只需使用双工绑定并让您的 UI 连接到 Web 服务并订阅回调。我还没有尝试过,所以我不确定这是否可行,但这可能是一个可行的解决方案。祝你好运!
猜你喜欢
  • 2011-10-05
  • 2017-01-20
  • 1970-01-01
  • 2010-11-04
  • 1970-01-01
  • 1970-01-01
  • 2012-03-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多