Windows 服务中使用 App.Config 的 WCF 命名管道

2024-03-25

我烦了。好的,这是错误。

net.pipe://localhost/MyIpcAppToService 上没有侦听端点可以接受该消息。这通常是由不正确的地址或 SOAP 操作引起的。有关更多详细信息,请参阅 InnerException(如果存在)。

我终于让 App.Config 文件正常工作了,至少没有抱怨。

当前应用程序配置

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <!-- When deploying the service library project, the content of the config file must be added to the host's 
  app.config file. System.Configuration does not support config files for libraries. -->
    <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/>
    </startup>
    <system.serviceModel>
        <services>
            <service behaviorConfiguration="MyServiceBehavior" name="MyService.Communication.IpcAppToService">
                <endpoint address="net.pipe://localhost/MyIpcAppToService" binding="wsDualHttpBinding" bindingConfiguration="MyAppToServiceEndpointBinding" contract="MyIpc.IIpcAppToService"/>
                <endpoint address="mex" binding="mexHttpBinding" name="mex" contract="IMetadataExchange"/>
                <host>
                    <baseAddresses>
                        <add baseAddress="http://localhost:8733/MyService/"/>
                    </baseAddresses>
                </host>
            </service>
  </services>
        <behaviors>
            <serviceBehaviors>
                <behavior name="MyServiceBehavior">
                    <!-- To avoid disclosing metadata information, set the values below to false before deployment -->
                    <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
                    <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment  to avoid disclosing exception information -->
                    <serviceDebug includeExceptionDetailInFaults="true"/>
                    <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
                </behavior>
            </serviceBehaviors>
        </behaviors>
        <protocolMapping>
            <add scheme="http" binding="wsHttpBinding" bindingConfiguration="MyAppToServiceEndpointBinding" />
        </protocolMapping>
        <bindings>
            <wsDualHttpBinding>
                <!-- https://learn.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/wcf/wshttpbinding -->
                <binding name="MyAppToServiceEndpointBinding"
                                 transactionFlow="true"
                                 sendTimeout="00:01:00"
                                 maxReceivedMessageSize="2147483647"
                                 messageEncoding="Mtom">
                </binding>
            </wsDualHttpBinding>
        </bindings>
        <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true">
            <baseAddressPrefixFilters>
                <add prefix="http://localhost:8733"/>
            </baseAddressPrefixFilters>
        </serviceHostingEnvironment>
    </system.serviceModel>
    <appSettings>
        <add key="countoffiles" value="7"/>
        <add key="logfilelocation" value="abc.txt"/>
    </appSettings>
</configuration>

我曾经有过:

<endpoint address="http://localhost:8733/MyIpcAppToService" ...

并在 Windows 服务中OnStart() event:

(从本问题帖子开始,以下代码现已被注释掉,因为App.config文件应该启动named.pipe。)

public Boolean CreatePipeServer()
{
    string eventText = $"My Service: CommAppToService::CreatePipeServer(IPC App to Service){Environment.NewLine}";
    try
    {
        if (null != this.ServiceParent.HostIpcAppToService)
            this.ServiceParent.HostIpcAppToService = null;

        string pipeBaseAddress = @"net.pipe://localhost/MyIpcAppToService";
        this.ServiceParent.HostIpcAppToService = new ServiceHost(typeof(IpcAppToService), new Uri(pipeBaseAddress));
        NetNamedPipeBinding pipeBinding = new NetNamedPipeBinding()
        {
            //ReceiveTimeout = new TimeSpan(0, 0, 0, 0, Constants.My_TimeoutMsSendReceive),
            //SendTimeout = new TimeSpan(0, 0, 0, 0, Constants.My_TimeoutMsSendReceive),
        };
        this.ServiceParent.HostIpcAppToService.AddServiceEndpoint(typeof(IIpcAppToService), pipeBinding, "MyIpcAppToService");
        this.ServiceParent.HostIpcAppToService.UnknownMessageReceived += HostIpcAppServer_UnknownMessageReceived;
        this.ServiceParent.HostIpcAppToService.Faulted += HostIpcAppServer_Faulted;
        this.ServiceParent.HostIpcAppToService.Closing += HostIpcAppServer_Closing;
        this.ServiceParent.HostIpcAppToService.Closed += HostIpcAppServer_Closed;

        this.IpcAppToService = new IpcAppToService();
        this.IpcAppToService.ApplyDispatchBehavior(this.ServiceParent.HostIpcAppToService);
        this.IpcAppToService.Validate(this.ServiceParent.HostIpcAppToService);
        this.ServiceParent.HostIpcAppToService.Open();

        return true;
    }

我读到该服务将自动启动放置在App.Config文件,确实是MyExeName.exe.config文件。我不断查看代码,发现它几乎相同,所以我替换了http:// with net.pipe://.

可悲的是,旧代码、新代码、中间代码,什么都没有。我不断收到同样的错误。

我使用以下命令从桌面应用程序连接到该服务。

public static Boolean ConnectToService()
{
    try
    {
        var callback = new IpcCallbackAppToService();
        var context = new InstanceContext(callback);
        var pipeFactory = new DuplexChannelFactory<IIpcAppToService>(context, new NetNamedPipeBinding(), new EndpointAddress("net.pipe://localhost/MyIpcAppToService"));
        Program.HostIpcAppToService = pipeFactory.CreateChannel();
        Program.HostIpcAppToService.Connect();
        CommAppToService.IsPipeAppToService = true;

        return true;
    }

    catch (Exception ex)
    {
        // Log the exception.
        Errors.LogException(ex);
    }

    return false;
}

不管它的价值如何,这里是:

界面

[ServiceContract(SessionMode = SessionMode.Allowed, CallbackContract = typeof(IIpcCallbackAppToService))]
public interface IIpcAppToService
{
    [OperationContract(IsOneWay = false)]
    [FaultContractAttribute(typeof(IpcAppToServiceFault))]
    UInt16 GetServiceId();

    ...
}

Service:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class IpcAppToService : IIpcAppToService, IErrorHandler
{
    public static IIpcCallbackAppToService Callback { get; set; } = null;

    public void OpenCallback()
    {
        IpcAppToService.Callback = OperationContext.Current.GetCallbackChannel<IIpcCallbackAppToService>();
    }

    public void CloseCallback()
    {
        IpcAppToService.Callback = null;
    }

    public void SendMessage(string message)
    {
        //MessageBox.Show(message);
    }

    public UInt16 GetServiceId()
    {
        return Constants.My_Id_AppToService;
    }

    ...
}

内部异常从我的桌面 WinForms 应用程序 (注意,除了这个之外,没有更多的内部异常。):

“在本地计算机上找不到管道端点 'net.pipe://localhost/MyIpcAppToService'。”

为什么我总是看到此错误?

第一个答案后更新

我想要采取的方向与答案相反,但相同,即服务从App.configclient使用 C# 代码。

可悲的是,我仍然遇到同样的错误。

修改服务器端 App.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <!-- When deploying the service library project, the content of the config file must be added to the host's 
  app.config file. System.Configuration does not support config files for libraries. -->
    <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/>
    </startup>
    <system.serviceModel>
        <services>
            <service behaviorConfiguration="BehaviorMyService" name="MyService.Communication.IpcAppToService">
                <endpoint address="net.pipe://localhost/MyIpcAppToService"
                                    binding="netNamedPipeBinding"
                                    bindingConfiguration="EndpointBindingMyAppToService"
                                    contract="MyIpc.IIpcAppToService"
                                    />
                <endpoint address="mex" binding="mexHttpBinding" name="mex" contract="IMetadataExchange"/>
                <host>
                    <baseAddresses>
                        <add baseAddress="http://localhost:8733/MyService/"/>
                    </baseAddresses>
                </host>
            </service>
        </services>
        <behaviors>
            <serviceBehaviors>
                <behavior name="BehaviorMyService">
                    <!-- To avoid disclosing metadata information, set the values below to false before deployment -->
                    <serviceMetadata httpGetEnabled="true"
                                                     httpsGetEnabled="true"
                                                     />
                    <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment  to avoid disclosing exception information -->
                    <serviceDebug includeExceptionDetailInFaults="true"/>
                    <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
                </behavior>
            </serviceBehaviors>
        </behaviors>
        <bindings>
            <netNamedPipeBinding>
                <!-- https://learn.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/wcf/wshttpbinding -->
                <binding name="EndpointBindingMyAppToService"
                                 closeTimeout="00:01:00"  
                                 openTimeout="00:01:00"   
                                 receiveTimeout="00:10:00"   
                                 sendTimeout="00:01:00"  
                                 transactionFlow="false"   
                                 transferMode="Buffered"   
                                 transactionProtocol="OleTransactions"  
                                 hostNameComparisonMode="StrongWildcard"   
                                 maxBufferPoolSize="524288"  
                                 maxBufferSize="65536"   
                                 maxConnections="10"   
                                 maxReceivedMessageSize="2147483647"
                                 >
                    <security mode="None">
                        <transport protectionLevel="None" />
                    </security>
                </binding>
            </netNamedPipeBinding>
        </bindings>
        <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true">
            <baseAddressPrefixFilters>
                <add prefix="http://localhost:8733"/>
            </baseAddressPrefixFilters>
        </serviceHostingEnvironment>
    </system.serviceModel>
    <appSettings>
        <add key="countoffiles" value="7"/>
        <add key="logfilelocation" value="abc.txt"/>
    </appSettings>
</configuration>

修改后的客户端 C# 代码:

var callback = new IpcCallbackAppToService();
InstanceContext context = new InstanceContext(callback);
NetNamedPipeBinding binding = new NetNamedPipeBinding();
binding.Security.Mode = NetNamedPipeSecurityMode.None;
EndpointAddress endpointAddress = new EndpointAddress("net.pipe://localhost/MyIpcAppToService");
var pipeFactory = new DuplexChannelFactory<IIpcAppToService>(context, binding, endpointAddress);
Program.HostIpcAppToService = pipeFactory.CreateChannel();
Program.HostIpcAppToService.Connect();
CommAppToService.IsPipeAppToService = true;

该服务不会引发我可以检测到的异常,因为 EventViewer 是干净的,只有 OnStart() 成功完成消息。我知道系统处理App.config文件,就像之前我遇到错误时一样,Windows Event Viewer会一直抱怨,但不会了。

以下是我使用的一些 Microsoft 文档:

网络命名管道绑定 https://learn.microsoft.com/en-us/dotnet/framework/wcf/samples/netnamedpipebinding

网络命名管道绑定 2 https://learn.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/wcf/netnamedpipebinding

我确实尝试过IO Ninja https://ioninja.com/,但指定\\.\pipe\MyIpcToService for File Stream, Pipe Listener, and Pipe Monitor,但是即使当我尝试使用 WinForms 桌面应用程序进行连接时,那里也没有显示任何内容,然后抛出 no pipeline Listenerfound 异常。

可能是什么问题?


<endpoint address="net.pipe://localhost/MyIpcAppToService" binding="wsDualHttpBinding" bindingConfiguration="MyAppToServiceEndpointBinding" contract="MyIpc.IIpcAppToService"/>

确保服务地址与绑定类型采用相同的形式(传输协议)。

  • TCP(net.tcp://localhost:8000/myservice) NetTcpBinding
  • IPC(net.pipe://localhost/mypipe) NetNamedPipeBinding
  • Http/Https(http://localhost:8000/myservice http://localhost:8000/myservice)
    Wshttp绑定、Wsdualhttp绑定、基本http绑定

  • WebSocket(ws://localhost:3434) Nethttp绑定

  • MSMQ(net.msmq://localhost/private/myservice) NetMsmqBinding

我们应该使用 NetnamedPipeBinding 作为服务地址。请参考我的例子。


Updated
I have a wcf service using NetNamedPipeBinding hosted in IIS, wish it is useful to you.
Server(wcf service application)
    [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        string GetData(int value);
}
    public class Service1 : IService1
    {
        public string GetData(int value)
        {
            return string.Format("You entered: {0}", value);
        }
}

Web.config(服务器端)

<system.serviceModel>
    <services>
      <service behaviorConfiguration="BehaviorMyService" name="WcfService1.Service1">
        <endpoint address="MyIpcAppToService"
                            binding="netNamedPipeBinding"
                            bindingConfiguration="EndpointBindingMyAppToService"
                            contract="WcfService1.IService1"
                                    />
        <endpoint address="mex" binding="mexHttpBinding" name="mex" contract="IMetadataExchange"/>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="BehaviorMyService">
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
          <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <netNamedPipeBinding>
        <binding name="EndpointBindingMyAppToService"
                         closeTimeout="00:01:00"
                         openTimeout="00:01:00"
                         receiveTimeout="00:10:00"
                         sendTimeout="00:01:00"
                         transactionFlow="false"
                         transferMode="Buffered"
                         transactionProtocol="OleTransactions"
                         hostNameComparisonMode="StrongWildcard"
                         maxBufferPoolSize="524288"
                         maxConnections="10"
                         maxReceivedMessageSize="2147483647"
                                 >
          <security mode="None">
            <transport protectionLevel="None" />
          </security>
        </binding>
      </netNamedPipeBinding>
    </bindings>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true">
    </serviceHostingEnvironment>
  </system.serviceModel>

Enable WCF new feature.
enter image description here
enter image description here
IIS site(enable net.pipe)
enter image description here
enter image description here
Client(console application)

  ServiceReference1.Service1Client client = new ServiceReference1.Service1Client();
    var result = client.GetData(34);
    Console.WriteLine(result);

客户端app.config(自动生成)
我使用http地址(服务元数据GET地址http://localhost:8733/Service1.svc?wsdl http://localhost:8733/Service1.svc?wsdl) 来生成配置。

  <system.serviceModel>
        <bindings>
            <netNamedPipeBinding>
                <binding name="NetNamedPipeBinding_IService1">
                    <security mode="None" />
                </binding>
            </netNamedPipeBinding>
        </bindings>
        <client>
            <endpoint address="net.pipe://mynetpipe/Service1.svc/MyIpcAppToService"
                binding="netNamedPipeBinding" bindingConfiguration="NetNamedPipeBinding_IService1"
                contract="ServiceReference1.IService1" name="NetNamedPipeBinding_IService1" />
        </client>
    </system.serviceModel>

如果有什么需要我帮忙的,请随时告诉我。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Windows 服务中使用 App.Config 的 WCF 命名管道 的相关文章

随机推荐

  • Firebase InstanceId 无法解析标识符 swift4

    我最近更新了我的 SWIFT 应用程序 pod 文件 并且由于 firebase 版本现已更新到 5 2 现在在获取设备实例 ID 时出现以下错误 let tokenId InstanceID instanceID token error
  • 如何将一个数组的值放入另一个数组中?

    String input txtInput getText char charArray input toCharArray char flipArray null System out println charArray length f
  • 内连接三个表

    我有三个表 我希望通过它们之间的公共列进行内部连接 假设我的桌子是 TableA TableB TableC 我想加入A B 但随后也B C这一切都源于这个共同的领域 我将其称为共同的 我已经像这样连接了两个表 dbo tableA AS
  • Pandas 与正则表达式“.”不一致点元字符?

    考虑 df Cost Store 1 22 5 Store 1 Store 2 要将这些点转换为 nan 我可以使用 df replace np nan regex True Cost Store 1 22 5 Store 1 NaN St
  • 如何让Eclipse使用JDK8来编译项目?

    我正在尝试新的 jdk8 这里提供什么http jdk8 java net lambda http jdk8 java net lambda 我可以从命令行编译并运行我的项目 我还可以将这个新的 JDK 添加到Installed JREs在
  • 获取 ngComponentOutlet 的引用

    我正在使用 ngComponentOutlet 动态创建一个组件 听上去像 import Component NgModule from angular core import BrowserModule from angular plat
  • 实际上如何使用 C 库?

    我确信这个问题已经被问过很多次了 但我无法弄清楚 耐心听我说 因此 当您下载库时 您会得到一堆 c 和 h 文件 以及许多其他内容 现在假设您想使用这个库编写一个程序 我将所有 h 文件复制到我的项目目录中 它只是无法编译 太好了 然后我将
  • 如何在 Python 中将 '%' 替换为 '\x'

    我的目标是将base64编码的 EB 字符串转换为 xEB 然而 一尝试 我发现这很难 并且通过 string replace 和 re sub 都无法实现 我的代码失败如下 target EB AF B8 EB 9F AC EC 8A A
  • 如何使用同一个 R 包的多个版本?

    为了能够比较包的两个版本 我需要能够选择加载哪个版本的包 R 的包系统默认设置为覆盖现有包 以便您始终拥有最新版本 我该如何覆盖这种行为 到目前为止我的想法是 我可以获取包源 编辑描述以给出不同的名称 并实际上构建两个不同的包 不过 我宁愿
  • 谁能告诉我 python 中的 pika 和 kombu 消息传递库有什么区别?

    我想在我的应用程序中使用消息传递库与rabbitmq交互 谁能解释一下 pika 和 kombu 库之间的区别吗 Kombu 和 pika 是两个不同的 Python 库 它们从根本上服务于相同的目的 向消息代理发布消息和使用消息代理发送消
  • 检查谷歌地图应用程序是否安装在react-native iOS中

    我尝试使用 npm 模块react native check app install但我无法实现 结果总是错误的 还尝试过react native installed apps获取手机中安装的应用程序列表 但这始终返回空列表 您确定声明了
  • Laravel 所有输入字段均为必填

    我有大约 50 个输入字段 它们都是必需的 有没有简单的方法来检查它们是否都已设置 所以我不必手动将每个字段放入我的模型中 验证规则为 必需 我知道这已经晚了 但我编写了一个简单的函数来为自己解决这个问题 foreach request g
  • 以网格格式绘制脉冲响应函数

    我已经从 R 中的 VAR 模型运行了以下脉冲响应函数 debtarg 1 lt irf var est debt arg response pfdebt arg impulse sp n ahead 40 ortho TRUE boot
  • Java Web 开发的学习路线?

    我继承了一个大型Java Web项目 我必须对其进行一些修改 在基础知识方面我是一个相当称职的Java程序员 但我以前从未做过任何JSP编程或EJB编程 我记得大约 5 年前在大学里做过一些 servlet 编程 但我假设从那时起一切都发生
  • 访问控件值的最有效方法是什么?

    在我必须访问控件的值的两个选择中 哪个是最有效的 getComponent ControlName getValue or dataSource getItemValue FieldName 我发现有时getComponent似乎没有返回当
  • 使用 Python 查找 Mac UUID/序列号

    基本上 我计划将计算机的 UUID 序列号与它运行的密钥绑定起来 在 Windows 上 我发现获取 UUID 很容易 但我很难为 Mac 获取任何东西 有什么解决办法吗 MacOS 有一个内置程序用于访问此信息 您可以使用以下命令获取它
  • 调整工作表演示文稿 SwiftUI 的大小

    我正在尝试以小尺寸呈现模型视图 有什么办法可以调整大小吗 Button Present self presentingModal true padding sheet isPresented presentingModal content
  • 将图像从 api url 加载到 Angular 5 组件中

    我有一个 html 结构如下的组件 img src img 并在打字稿中 constructor private loginService LoginService this img null this loadImage loadImag
  • 如何解决此问题:应用程序启用 YouTube 视频的后台播放

    我制作了一个播放 YouTube 视频的phonegap 应用程序 谷歌已将其从 Play 商店下架 因为 该应用程序可以在后台播放 YouTube 视频 我不知道这意味着什么 有人可以帮我解决这个问题 以便视频不会在后台播放吗 Thank
  • Windows 服务中使用 App.Config 的 WCF 命名管道

    我烦了 好的 这是错误 net pipe localhost MyIpcAppToService 上没有侦听端点可以接受该消息 这通常是由不正确的地址或 SOAP 操作引起的 有关更多详细信息 请参阅 InnerException 如果存在