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

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

ただいまの
回答率

88.59%

MemoryMappedFileをWindowsアプリとWebアプリで共有したい

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 2,093

imudak

score 31

 困っていること

MemoryMappedFileをWindowsアプリとWebアプリで共有しようとしています。

それぞれ単独で動かしたときには良いのですが、アプリ→Webの順に実行しようとすると
MemoryMappedFile.CreateOrOpenのところで、UnauthorizedAccessExceptionになります。

逆順に実行すると問題ないので最悪起動順に気をつければいいのですが、なぜ後からWebを実行するとダメなのか
原因がよくわかりません。

 試した条件

  1. MyApp.exe: 
    ・.NET Framework 4.7.2
    ・MyDll.dll参照
    ・管理者権限で実行

  2. MyWeb: 
    ・Asp.NET Core 2.1
    ・.NET Framework 4.7.2
    ・MyDll.dll参照
    ・管理者権限で実行

  3. MyDll.dll: 
    ・.NET Framework 4.7.2
    ・MemoryMappedFile作成、開くクラスが存在

MyDll.dll: MyApp.exe, MyWeb共通で呼び出しているメソッド

public void CreateOrOpenSharedMemory(string name, int capacity) {
        var mmf = MemoryMappedFile.CreateOrOpen($@"Global\{name}", capacity);
        var stream = mmf.CreateViewStream();
}

 試した結果

 結果1) MyApp.exe -> MyWebの順で実行。

System.UnauthorizedAccessException: パスへのアクセスは拒否されました。
   場所 System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   場所 System.IO.MemoryMappedFiles.MemoryMappedFile.CreateOrOpenCore(SafeFileHandle fileHandle, String mapName, HandleInheritability inheritability, MemoryMappedFileSecurity memoryMappedFileSecurity, MemoryMappedFileAccess access, MemoryMappedFileOptions options, Int64 capacity)
   場所 System.IO.MemoryMappedFiles.MemoryMappedFile.CreateOrOpen(String mapName, Int64 capacity, MemoryMappedFileAccess access, MemoryMappedFileOptions options, MemoryMappedFileSecurity memoryMappedFileSecurity, HandleInheritability inheritability)
   場所 System.IO.MemoryMappedFiles.MemoryMappedFile.CreateOrOpen(String mapName, Int64 capacity)

 結果2) MyWeb -> MyApp.exeの順で実行

→問題なく起動、動作。

 追記

コメントいただいたので追記します。
まさに業務で使おうとしています…

  1. WindowsAppが元々あり、MemoryMappedFileを使ったdllがあります。
  2. このWindowsAppの一部機能をWebApp化する要望があります。
  3. この一部機能を実現するためにMemoryMappedFileを使ったdllを使う必要があります。

MemoryMappedFileを使ったdllはとある情報を保持しており、この情報はWindowsAppからも
WebAppからも更新され共有する必要があります。

 追記2' アクセス権追加

everyoneに権限を追加してみたところ、CreateOrOpen時の例外は回避されました。

MemoryMappedFileSecurity customSecurity = new MemoryMappedFileSecurity();
customSecurity.AddAccessRule(
    new System.Security.AccessControl.AccessRule<MemoryMappedFileRights>(
        "everyone", MemoryMappedFileRights.FullControl, 
        System.Security.AccessControl.AccessControlType.Allow));

//    m_MemoryMappedFile = MemoryMappedFile.CreateOrOpen(name, capacity);
m_MemoryMappedFile = MemoryMappedFile.CreateOrOpen(
    $@"Global\{name}", capacity,
    MemoryMappedFileAccess.ReadWrite,
    MemoryMappedFileOptions.None,
    customSecurity,
    System.IO.HandleInheritability.Inheritable);
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • SurferOnWww

    2018/10/25 11:37

    返答いただきありがとうございました。そういうことですと自分はアイデアは出せそうもないです。お役に立てずすみませんが、他の方の回答をお待ちください。

    キャンセル

  • imudak

    2018/10/25 11:38

    こちらこそありがとうございました。dllが素直にDBに入れててくれればもう少し簡単だったのですが…

    キャンセル

  • imudak

    2018/10/25 13:21

    参照しているdllが更新されていなかったため、追記2の結果を修正しました。

    キャンセル

回答 2

+2

みなさんありがとうございました。解決できました。

作成時に、IUSR,IIS_IUSRSにアクセス権を与えてればよいようです。
指定が面倒なら過剰ですが"everyone"でもよいようです。

MemoryMappedFileSecurity customSecurity = new MemoryMappedFileSecurity();

//customSecurity.AddAccessRule(
//    new System.Security.AccessControl.AccessRule<MemoryMappedFileRights>(
//        "everyone", MemoryMappedFileRights.FullControl,
//        System.Security.AccessControl.AccessControlType.Allow));
customSecurity.AddAccessRule(
    new System.Security.AccessControl.AccessRule<MemoryMappedFileRights>(
        "IIS_IUSRS", MemoryMappedFileRights.FullControl,
        System.Security.AccessControl.AccessControlType.Allow));
customSecurity.AddAccessRule(
    new System.Security.AccessControl.AccessRule<MemoryMappedFileRights>(
        "IUSR", MemoryMappedFileRights.FullControl,
        System.Security.AccessControl.AccessControlType.Allow));

//    m_MemoryMappedFile = MemoryMappedFile.CreateOrOpen(name, capacity);

m_MemoryMappedFile = MemoryMappedFile.CreateOrOpen(
    $@"Global\{name}", capacity,
    MemoryMappedFileAccess.ReadWrite,
    MemoryMappedFileOptions.None,
    customSecurity,
    System.IO.HandleInheritability.Inheritable)

ちなみに、読み書き時にMutexも使っていたので同様にアクセス権を付与します。

var mutex = new Mutex(false, $@"Global\{name}");

var security = new MutexSecurity();
security.AddAccessRule(
    new MutexAccessRule("IUSR", MutexRights.FullControl,
    AccessControlType.Allow));
security.AddAccessRule(
    new MutexAccessRule("IIS_IUSRS", MutexRights.FullControl,
    AccessControlType.Allow));

mutex.SetAccessControl(security);

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

checkベストアンサー

+1

System.UnauthorizedAccessExceptionの例外が発生している為、
MyApp.exe、MyWebのそれぞれを管理者権限で実行していたとしても、
MemoryMappedFile.CreateOrOpen()で作成されたMemoryMappedFileのアクセス権限が、
それぞれで違ったりしませんか?(MyWebの方がIIS_USERで弱いとか))

MemoryMappedFile.GetAccessControl()で権限を見ることが出来そうですが、
触ったことがない為、サンプルとか提示できません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/10/25 11:35

    GetAccessControl() Debugで見てみたのですが、いまいちよくわからずです…MemoryMappedFileSecurityを緩めに設定してCreateOrOpen()か、SetAccessControl()で渡してやれば良さそうなのですが、なにを渡せばゆるくなるのか調べているところです。

    キャンセル

  • 2018/10/25 14:19

    手がかりになりました。ありがとうございました。

    キャンセル

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

  • ただいまの回答率 88.59%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る