質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

Q&A

解決済

1回答

2164閲覧

Windowsのユーザ切替でメールスロットのやり取りを行えるか?

nobureon2

総合スコア21

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

0グッド

0クリップ

投稿2019/07/08 06:17

編集2019/07/09 08:47

確認したいこと

そもそもやろうとしていることが実現可能か助言いただきたいです。
また、不可能な場合、ほかの方法があれば教えていただきたいです。
ユーザ切替を利用することは確定事項となります。

実現したいこと

Windowsのユーザ切替を利用して、事前にログインしたユーザが起動したプロセスに対して、
別のログインしたユーザからメールスロットでメッセージを送信したいです。
具体的な手順は以下になっています。

1、ユーザAさんでログインし、プロセスAを起動
2、ユーザ切替で、ユーザBさんでログインし、プロセスBを起動
3、ユーザ切替で、ユーザAでログインし、メッセージ表示を確認

■プロセスAでやっていること
タイマーを発行して、10秒間隔でメールスロットの読み取りを行い、
メッセージがある場合、メッセージボックスに受信メッセージを表示する。

■プロセスBでやっていること
メッセージへの書き込み

現状の動作

プロセスBのCreateFile関数でハンドルが取得できません。
GetLastWin32Errorで0x00000005(アクセスが拒否されました。)が返却されます。

環境

Windows10 Pro
VisualStudio 2013
.net framework4.5.1

補足

単一ユーザではメッセージが受信できることは確認済み。
メールスロットの受信/送信は以下のソース。

C#

1 // メールスロットの受信 2 private string ReadMailSlot(string slot, uint bufSize) 3 { 4 string ret = string.Empty; 5 try 6 { 7 if (_handleMailslot.IsInvalid) 8 return ret; 9 10 uint maxMessageSize = 1; 11 uint nextSize = 0; 12 uint messageCount = 0; 13 uint readTimeout = 0; 14 15 GetMailslotInfo(_handleMailslot, ref maxMessageSize, ref nextSize, ref messageCount, ref readTimeout); 16 17 if (messageCount > 0 && nextSize != (uint)MailSlotStatus.MAILSLOT_NO_MESSAGE) 18 { 19 byte[] buf = new byte[bufSize]; 20 int len = _fs.Read(buf, 0, buf.Length); 21 22 // 適時、文字コードは送信元に合わせてください 23 ret = Encoding.Unicode.GetString(buf, 0, len); 24 } 25 } 26 catch (Exception ex) 27 { 28 // 何かエラーだって! 29 MessageBox.Show(ex.Message); 30 } 31 32 return ret; 33 }

C#

1 // メールスロットの送信 2 public void WriteMailSlot(string slot, string message) 3 { 4 5 try 6 { 7 //メールスロットを開く 8 SafeFileHandle fileHandle = CreateFile(slot, 9 DesiredAccess.GENERIC_READ | DesiredAccess.GENERIC_WRITE, 10 ShareMode.FILE_SHARE_READ | ShareMode.FILE_SHARE_WRITE, 11 0, 12 CreationDisposition.OPEN_EXISTING, 13 FlagsAndAttributes.FILE_ATTRIBUTE_NORMAL, 14 (IntPtr)0); 15 16 if( fileHandle.IsInvalid ) 17 { 18 int errCode = Marshal.GetLastWin32Error(); 19 MessageBox.Show("Win32エラー・コード:" + 20 String.Format("{0:X8}", errCode)); 21 } 22 23 24 // 指定の文字列を出力する 25 using (FileStream fs = new FileStream(fileHandle, FileAccess.Write)) 26 { 27 byte[] msg = Encoding.UTF8.GetBytes(message); 28 fs.Write(msg, 0, msg.Length); 29 } 30 } 31 catch (Exception ex) 32 { 33 System.Diagnostics.Debug.WriteLine(ex.Message); 34 System.Diagnostics.Debug.WriteLine(ex.StackTrace); 35 throw ex; 36 } 37 }

C#

1 // 下記URLを参考に修正 2 // https://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=16274&forum=7 3 4 public void WriteMailSlot(string slot, string message) 5 { 6 System.IntPtr hNmPipe = IntPtr.Zero; // 名前付きパイプハンドル 7 8 //セキュリティ記述子作成 9 SECURITY_DESCRIPTOR sd = new SECURITY_DESCRIPTOR(); 10 bool bTemp = InitializeSecurityDescriptor(ref sd, 1); 11 bool bTemp2 = SetSecurityDescriptorDacl(ref sd, 1, IntPtr.Zero, 0); 12 GCHandle sdHandle = GCHandle.Alloc(sd, GCHandleType.Pinned); 13 14 try 15 { 16 SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES(); 17 sa.nLength = Marshal.SizeOf(sa); 18 sa.lpSecurityDescriptor = sdHandle.AddrOfPinnedObject(); 19 sa.bInheritHandle = 0; 20 21 //メールスロットを開く 22 SafeFileHandle fileHandle = CreateFile(slot, 23 DesiredAccess.GENERIC_READ | DesiredAccess.GENERIC_WRITE, 24 ShareMode.FILE_SHARE_READ | ShareMode.FILE_SHARE_WRITE, 25 ref sa, 26 CreationDisposition.OPEN_EXISTING, 27 FlagsAndAttributes.FILE_ATTRIBUTE_NORMAL, 28 (IntPtr)0); 29 30 if (fileHandle.IsInvalid) 31 { 32 int errCode = Marshal.GetLastWin32Error(); 33 MessageBox.Show("Win32エラー・コード:" + 34 String.Format("{0:X8}", errCode)); 35 } 36 37 38 // 指定の文字列を出力する 39 using (FileStream fs = new FileStream(fileHandle, FileAccess.Write)) 40 { 41 byte[] msg = Encoding.UTF8.GetBytes(message); 42 fs.Write(msg, 0, msg.Length); 43 } 44 45 } 46 catch (Exception ex) 47 { 48 System.Diagnostics.Debug.WriteLine(ex.Message); 49 System.Diagnostics.Debug.WriteLine(ex.StackTrace); 50 throw ex; 51 } 52 finally 53 { 54 sdHandle.Free(); 55 } 56 } 57

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

単純にセキュリティディスクリプタが設定されていないだけではないでしょうか?

対象は異なりますが、C# で DACL を設定しているサンプルがあったので、これと同様に CreateFile の 4 番目のパラメータの SECURITY_ATTRIBUTES を指定してみてはどうでしょう? CreateMailSlot の最後のパラメータに指定してみましょう。
https://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=16274&forum=7

CreateNamedPipe に渡している ref sa ってやつですね。

投稿2019/07/08 15:21

編集2019/07/09 16:37
atata0319

総合スコア881

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nobureon2

2019/07/09 08:44

回答ありがとうございます。 参考で掲載いただたURLの内容をほぼコピーしてみましたが、別のエラーになりました。 修正したソースも掲載します。 0x000003F0 存在しないトークンを参照しようとしました。 セキュリティディスクリプタについてよくわかってないのですが、 この場合、メールスロットで生成した仮想ファイルにDACLが設定されていないということでしょうか?
atata0319

2019/07/09 16:38

すみません。思いっきり回答間違ってましたので、修正しました。
nobureon2

2019/07/10 00:42

回答ありがとうございます! おかげさまで、出来ました。 セキュリティディスクリプタについて理解出来ていないので、 理解したうえで活用させてもらいます! ありがとうございました!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問