Sco*_*ain 21 c# named-pipes .net-3.5
我正在尝试编写一个(提升权限)服务,该服务将与非特权winforms应用程序进行通信.我能够有两个控制台应用程序(一个没有升级)应答来回没问题,但我在服务和winforms应用程序时遇到问题.
管道的第一个实例完美无缺.然而,在我的客户端连接后,我尝试创建一个新实例,以便在第二个客户端连接时准备就绪,但NamedPipeServerStream的构造函数会引发异常
System.UnauthorizedAccessException was unhandled
Message=Access to the path is denied.
Source=System.Core
StackTrace:
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.Pipes.NamedPipeServerStream.Create(String fullPipeName, PipeDirection direction, Int32 maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, Int32 inBufferSize, Int32 outBufferSize, PipeAccessRights rights, SECURITY_ATTRIBUTES secAttrs)
at System.IO.Pipes.NamedPipeServerStream..ctor(String pipeName, PipeDirection direction, Int32 maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, Int32 inBufferSize, Int32 outBufferSize, PipeSecurity pipeSecurity, HandleInheritability inheritability, PipeAccessRights additionalAccessRights)
at System.IO.Pipes.NamedPipeServerStream..ctor(String pipeName, PipeDirection direction, Int32 maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, Int32 inBufferSize, Int32 outBufferSize, PipeSecurity pipeSecurity)
at PipeServer.Server.Client..ctor(String pipeName, List`1 container) in E:\Visual Studio 2010\Projects\Sandbox Service\PipeServer.cs:line 27
at PipeServer.Server.ListenForClients() in E:\Visual Studio 2010\Projects\Sandbox Service\PipeServer.cs:line 148
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
Run Code Online (Sandbox Code Playgroud)
删除示例,请参阅底部的示例以获得更简单的测试用例
第一次迭代工作正常.它是在客户端连接并client = new Client
第二次被调用时,它反过来调用Pipe = new NamedPipeServerStream
并抛出异常.
任何人都可以看到我犯的是什么错误吗?
更多信息,出于好奇,我回到了我的控制台应用程序.为了测试多个实例,我只是多次运行exe.当我把两个new NamedPipeServerStream
放在同一个可执行文件中时,我得到了同样的错误...那么为什么如果你有单独的exe作为服务器指向相同的命名管道地址但是禁止在同一个exe内部执行它,这是否可以?
static void Main()
{
PipeAccessRule pr = new PipeAccessRule("Users", PipeAccessRights.ReadWrite, System.Security.AccessControl.AccessControlType.Allow);
PipeSecurity ps = new PipeSecurity();
ps.AddAccessRule(pr);
using (NamedPipeServerStream pipeServer =
new NamedPipeServerStream("testpipe",PipeDirection.InOut,10,
PipeTransmissionMode.Message,
PipeOptions.WriteThrough,4028,4028,ps))
using (NamedPipeServerStream pipeServer2 = //v-- Throws the execption, but if you comment this out and run the EXE twice it works fine. creating a new instance of ps and pr does not change anything.
new NamedPipeServerStream("testpipe", PipeDirection.InOut, 10,
PipeTransmissionMode.Message,
PipeOptions.WriteThrough, 4028, 4028, ps))
{
Run Code Online (Sandbox Code Playgroud)
更多信息:
如果我没有设置PipeSecurity
它不会抛出异常,但是当我设置安全性时它会.如果我PipeSecurity
使用相同的设置传递两个实例相同或两个实例它仍然抛出异常并不重要.
Chr*_*son 31
有两件事可能导致同一管道上的第二个或后续NamedPipeServerStream的实例化失败:
服务进程应该设置管道安全性:
PipeSecurity ps = new PipeSecurity();
ps.AddAccessRule(new PipeAccessRule(myPipeUsersGroup, PipeAccessRights.ReadWrite, AccessControlType.Allow));
ps.AddAccessRule(new PipeAccessRule(myPipeServerIdentity, PipeAccessRights.FullControl, AccessControlType.Allow));
Run Code Online (Sandbox Code Playgroud)
哪里:
myPipeUsersGroup
是一个占位符,用于包含将连接到管道的所有预期客户端标识的组.根据您的要求/用例,这可能是特定的客户端标识,自定义组或内置组,例如"用户"或"管理员".myPipeServerIdentity
是服务标识的占位符.例如,可以将其设置为WindowsIdentity.GetCurrent().Owner
.当管道服务器托管在Windows服务中时,那么更好(但更难以实现)将是服务进程的登录SID标识 - 这将确保只有特定的服务进程才能创建管道的实例.如果要确保管道访问仅限于本地登录的用户,即为了防止通过网络进行远程访问,还可以将网络用户的拒绝ACE添加到管道安全ACL中.
Sco*_*ain 16
我想到了.
static void Main()
{
PipeSecurity ps = new PipeSecurity();
ps.AddAccessRule(new PipeAccessRule("Users", PipeAccessRights.ReadWrite | PipeAccessRights.CreateNewInstance, AccessControlType.Allow));
ps.AddAccessRule(new PipeAccessRule("CREATOR OWNER", PipeAccessRights.FullControl, AccessControlType.Allow));
ps.AddAccessRule(new PipeAccessRule("SYSTEM", PipeAccessRights.FullControl, AccessControlType.Allow));
ps.AddAccessRule(pa);
using (NamedPipeServerStream pipeServer =
new NamedPipeServerStream("testpipe",PipeDirection.InOut,10,
PipeTransmissionMode.Message, PipeOptions.WriteThrough, 1024,1024,ps))
using (NamedPipeServerStream pipeServer2 =
new NamedPipeServerStream("testpipe", PipeDirection.InOut, 10,
PipeTransmissionMode.Message, PipeOptions.WriteThrough,1024,1024,ps))
{
Run Code Online (Sandbox Code Playgroud)
通过添加权利,PipeAccessRights.CreateNewInstance
它现在可以正常工作.
我遇到了另一个障碍,但我解决了它,但想发布它,以防其他人通过谷歌发现这一点.通过提供您自己的管道安全对象,它将删除默认对象,因此如果您需要它,您需要重新添加系统组,以便在编写服务时它可以与管道通信.我将上面的代码更新为我用来获得提升的服务和非提升的winforms应用程序以相互交谈(创建者所有者可能是不必要的)
归档时间: |
|
查看次数: |
20299 次 |
最近记录: |