C# 从Windows服务通过WPF应用程序中托管的命名管道使用WCF服务

C# 从Windows服务通过WPF应用程序中托管的命名管道使用WCF服务,c#,wpf,wcf,named-pipes,C#,Wpf,Wcf,Named Pipes,我在WPF应用程序中托管了一个WCF服务,该应用程序使用命名管道更新GUI。在Windows服务中,我使用此WCF服务来更新GUI 我使用以下代码在我的WPF应用程序中托管它: private ServiceHost serviceHost; public MainWindow() { InitializeComponent(); try { string address = "net.pipe://localhost/Path/ServiceName

我在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
}
string address=“net。pipe://localhost/Path/ServiceName";
NetNamedPipeBinding绑定=新的NetNamedPipeBinding(NetNamedPipeSecurityMode.None);
EndpointAddress ep=新的EndpointAddress(地址);
IComService通道=
ChannelFactory.CreateChannel(
装订
);
尝试
{
channel.SendUpdatedStatus(“测试”);
}
捕获(例外e)
{
//抛出:管道端点网络。pipe://localhost/... 在本地计算机上找不到
}
System.IO.PipeException:在网络上没有端点侦听。pipe://localhost/... 这可以接受这个信息


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

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

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

这最像是一个安全问题。默认情况下,运行windows服务的用户帐户是LocalService,它几乎没有权限,可能无法将命名管道连接到任何东西。试着用你自己的帐户启动这项服务,我想你会发现它是有效的。必须小心地为要运行的Windows服务查找适当的帐户,否则将打开一个安全漏洞。@AQuirky to除了这个问题之外,我已经使用启动WPF应用程序的相同帐户运行了它。没有成功。我编写了一个Windows服务和一个WPF客户端,正如您在这里所展示的那样,即使在默认的LocalService帐户下,它也可以正常工作。所以我觉得问题出在你实现服务的方式上。我做了最简单的工作:创建了服务循环,它是在OnStart中的一个新线程上创建的。建立连接后的服务循环以1秒延迟连续循环发送“测试”,一切正常。@非常感谢您的测试。明天我将尝试建立一个新的服务,从头开始。@AQuirky不幸的是我没有运气。您是否为您的服务创建了ProjectInstaller?你的设置是什么?你用的是什么.NET版本?你得给我点信任。我对你的第一个评论是,这可能是一个安全问题。不过你现在不能放弃!我的WPF应用程序在没有管理员的情况下可以正常通信,并且我的服务在LocalService帐户下运行。比它不起作用更糟糕的是,它起作用了,在你的安全上打开了一个大洞。非常感谢你的洞察力。在使用此设置之前,我必须仔细检查此策略对用户组是否安全。我理解。我正在与一位不愿更换烫发的客户打交道,因此我正在寻找其他选择。有一件事可能也行得通,我还没有试过……我想如果你将你的UI连接到你的服务(会话2到会话0),你可能不需要这个权限。如果要“推送”到UI,只需使用双工绑定,让UI连接到web服务并订阅回调。我还没有尝试过,所以我不确定这是否有效,但这可能是一个可行的解决方案。祝你好运