使用针对.NET Framework 4.x编译的应用程序,并在.NET Framework 4.6.2或更高版本上运行,可以通过不重新编译来解决该问题。有一个新的
App.config
开关,可以更改WCF命名管道的查找行为,以使用最佳匹配的基地址。
因此,要解决该问题,需要执行以下操作:
- 使用唯一的基地址和相对路径,例如
net.pipe://127.0.0.1/<MySpecificApplication>
(将<MySpecificApplication>替换为您的唯一相对路径)
- 在WCF客户端项目中添加一个
App.config
文件(用于桌面应用程序)或Web.config
文件(用于IIS和ASP.NET Core模块),并添加以下内容。如果该配置文件已经存在于项目中,请将XML元素添加到尚不存在的配置中。
- 对于不需要重新编译的现有桌面安装:复制该文件并将其重命名为
<name-of-the-wcf-client-exe-file>.exe.config
,然后将其复制到应用程序文件夹中exe <name-of-the-wcf-client-exe-file>.exe
旁边。
<configuration>
<appSettings>
<add key="wcf:useBestMatchNamedPipeUri" value="true" />
</appSettings>
</configuration>
我确认这个修复方案适用于针对.NET Framework 4.7.2编译的桌面应用程序,并在.NET Framework 4.8上运行时解决了问题。
详细解释:
WCF命名管道使用一个间接方式,通过
文件映射对象 / 段对象调用连接的基地址来查找要连接的命名管道。
默认查找策略首先尝试在
全局命名空间中查找对象(以管理员权限运行的服务和应用程序在此处创建其部分),然后在本地命名空间中查找对象(未以管理员身份运行的应用程序在此处创建其部分)。
在全局命名空间中,它从指定的基地址开始(例如
net.pipe://127.0.0.1/<MySpecificApplication>
),然后沿着路径层次结构向上走,直到达到根目录(例如
net.pipe://127.0.0.1/
)。只有在全局命名空间中未找到匹配项时,才会搜索并沿着层次结构遍历本地命名空间。
使用
wcf:useBestMatchNamedPipeUri=true
进行查找。
顺序保持不变(先全局命名空间,然后是本地命名空间,并从每个命名空间中最具体的基地址向根地址),但是查找不会在第一个匹配项处停止,而是寻找最佳匹配项(基地址的最长子字符串)。
来源:
-
.NET Framework 源代码 System.ServiceModel.Channels.PipeConnection.GetPipeName(Uri uri, IPipeTransportFactorySettings transportFactorySettings)
-
https://web.archive.org/web/20110920061444/http://blogs.charteris.com/blogs/chrisdi/archive/2010/10/20/locating-a-wcf-named-pipe-endpoint.aspx
NetNamedPipeBinding best match
WCF has a new app setting that can be set on client applications to ensure they always connect to the service listening on the URI that best matches the one that they request. With this app setting set to false
(the default), it is possible for clients using NetNamedPipeBinding to attempt to connect to a service listening on a URI that is a substring of the requested URI.
For example, a client tries to connect to a service listening at net.pipe://localhost/Service1
, but a different service on that machine running with administrator privilege is listening at net.pipe://localhost
. With this app setting set to false
, the client would attempt to connect to the wrong service. After setting the app setting to true
, the client will always connect to the best matching service.
Note
Clients using NetNamedPipeBinding find services based on the service's base address (if it exists) rather than the full endpoint address. To ensure this setting always works the service should use a unique base address.
To enable this change, add the following app setting to your client application's App.config or Web.config file:
XML
<configuration>
<appSettings>
<add key="wcf:useBestMatchNamedPipeUri" value="true" />
</appSettings>
</configuration>
来源:
https://learn.microsoft.com/zh-cn/dotnet/framework/whats-new/#windows-communication-foundation