A Microsoft platform for building and publishing apps for Windows devices.
I've recently looked into this issue and have some new findings.
Your scenario is that the desktop app creates the pipe, and the UWP app connects to it. The key is to configure the proper permissions for the UWP app when the desktop app creates the pipe.
On the UWP side, your original code is fine:
pipeClient = new NamedPipeClientStream(".", "testpipe", PipeDirection.InOut, PipeOptions.Asynchronous);
pipeClient.Connect(5000);
As long as you use the correct package family name, the SID returned by DeriveAppContainerSidFromAppContainerName should be correct. If you got an incorrect SID, it was likely because you passed the wrong package family name.
For example, Baka632.UwpPipe.NetNative_xrr5xv0r1z0t2 is the package family name; Baka632.UwpPipe.NetNative_1.0.1.0_x64__xrr5xv0r1z0t2 is the package full name; and Baka632.UwpPipe.NetNative is the package name. Only the package family name (here Baka632.UwpPipe.NetNative_xrr5xv0r1z0t2) yields the correct SID – none of the others work.
It might also be a P/Invoke marshaling issue. I used CsWin32 to generate the P/Invoke code, which makes it easier to obtain the SID:
if (!string.IsNullOrWhiteSpace(packageFamilyName)
&& PInvoke.DeriveAppContainerSidFromAppContainerName(packageFamilyName, out PSID psid).Succeeded)
{
SecurityIdentifier appSid;
unsafe
{
appSid = new((nint)psid.Value);
PInvoke.FreeSid(psid); // The PSID must be freed; this does not affect the already created SecurityIdentifier.
}
return packageSid;
}
The desktop app's pipe creation code is as follows. Unlike your version, you don't need to add WorldSid – just the current user's SID is sufficient. You also don't need broad permissions; read/write access is enough.
PipeSecurity access = new();
SecurityIdentifier appSid; // The UWP app's SID obtained earlier.
SecurityIdentifier currentUserSid = WindowsIdentity.GetCurrent().Owner ?? throw new InvalidOperationException("Unable to get the current user's SID.");
PipeAccessRights rights = PipeAccessRights.Read | PipeAccessRights.Write;
access.AddAccessRule(new PipeAccessRule(appSid, rights, AccessControlType.Allow));
access.AddAccessRule(new PipeAccessRule(currentUserSid, rights, AccessControlType.Allow));
NamedPipeServerStream pipeStream = NamedPipeServerStreamAcl.Create(
"testpipe", PipeDirection.InOut, NamedPipeServerStream.MaxAllowedServerInstances, PipeTransmissionMode.Byte,
PipeOptions.Asynchronous, 512, 512,
access, HandleInheritability.None);
Additionally, I've written a detailed demo project for UWP pipe communication, which you can refer to: Baka632/UWP-Pipe.
Now, regarding the System.Security.Principal.Windows package:
The latest version (5.0.0) conflicts with UWP dependencies, causing the compiler to reference the wrong assembly version, which leads to application crashes. (In fact, the compiler also shows a MSB3277 warning after installing this package as a reminder.)
If your UWP client only connects to a pipe created by a desktop app, you don't need any extra package – you can simply uninstall it.
If you cannot uninstall it, downgrade to version 4.7.0.
You also mentioned the NamedPipeServerStream.NetFrameworkVersion package. If your UWP app needs to reference it, use version 1.0.10, because its latest version also references System.Security.Principal.Windows 5.0.0.