はじめに
.NET でパイプを使用したプロセス間通信は NamedPipeServerStream
を使用します。また、Windows 上で権限レベルが異なるユーザー間(例えばサービス - 一般ユーザー間)でプロセス間通信をする場合は、追加パッケージ System.IO.Pipes.AccessControl
を導入し、SetAccessControl
を以下のように指定します。
例えば以下のように実装すると、すべてのユーザーからアクセス可能なパイプが作成できます。
// すべてのユーザーからアクセス可能とする PipeSecurity pipeSecurity = new PipeSecurity(); pipeSecurity.AddAccessRule( new PipeAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), PipeAccessRights.FullControl, AccessControlType.Allow)); var pipe = new NamedPipeServerStream("pip-ename", PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous); // ★以前はコンストラクターで引数を指定できていたが // .NETのマルチプラットフォーム化でオーバーロードが削除されたため // 拡張パッケージによる追加メソッドで指定する p.SetAccessControl(pipeSecurity);
が、しかし、この実装は VisualStudio を管理者権限で起動して実行しても必ずエラーが発生し正常に動作しません。
// 管理者権限で実行しても SetAccessControl の行でエラーが発生する System.UnauthorizedAccessException: 'Attempted to perform an unauthorized operation.'
このエラーの対象方法について紹介となります。
確認環境
- .NET8
- VisualStudio2022
- Windows11
解決方法
解決方法は簡単で、SetAccessControl
の代わりに NamedPipeServerStreamAcl.Create
メソッドを使用してインスタンスを作成します。
実装例は以下の通りです。
PipeSecurity pipeSecurity = new PipeSecurity(); pipeSecurity.AddAccessRule( new PipeAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), PipeAccessRights.FullControl, AccessControlType.Allow)); // 代わりに以下のようにインスタンスを作成する var p = NamedPipeServerStreamAcl .Create("asdf", PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous, 1024 * 10, 1024 * 10, pipeSecurity);
これでエラーが発生しなくなります。
以上です。