0

もう少し理解できたので、この質問を言い換えています。もともと、私が持っていたものはあまりにも曖昧でした。「コードアクセスセキュリティ」と呼ばれるものによってルーティングされていることを発見しました。これは古いものです。これを読んでいるすべての人にとっては確かですが、私にとってはそうではありません。

アプリケーションは非常に大きいので、一言で言えば、2つのアセンブリがあります。1つは、プログラム全体で使用されるさまざまな「ツール」を備えたユーティリティアセンブリです。もう1つは、機能するためにこれらのツールを呼び出すことです。

ユーティリティアセンブリには、PInvokedである多くの関数がありますが、私に不満を与えるのは、SetupDiGetDeviceInterfaceDetail()です(ここを参照)。私の関数プロトタイプは次のようになります。

[DllImport("SetupApi.dll", SetLastError = true, CharSet = CharSet.Auto)]
[return : MarshalAs(UnmanagedType.Bool)]
public static extern bool SetupDiGetDeviceInterfaceDetail(
    SafeHandleZeroOrMinusOneIsInvalid deviceInfoSet,
    ref SP_DEVICE_INTERFACE_DATA deviceInterfaceData,
    IntPtr deviceInterfaceDetailData,
    uint deviceInterfaceDetailDataSize,
    IntPtr requiredSize,
    IntPtr deviceInfoData);

この関数を使用するアセンブリでは、SP_DEVICE_INTERFACE_DETAIL_DATA構造体にあるDevicePathを格納するために必要なスペースの量を理解するために、注釈で概説されている2つのステップのプロセスを使用しています(ここを参照)。例えば:

string GetDevicePath(SafeHandleSeroOrMinusOneIsInvalid hList, SP_DEVICE_INTERFACE_DATA infoSet)
{
    IntPtr pReqSize = Marshal.AllocHGlobal(4);
    Marshal.WriteInt32(pReqSize, 0);
    uint reqSize;

    // get the size needed
    PInvoke.SetupDiGetDeviceInterfaceDetail(hList,
                                            ref infoSet,
                                            IntPtr.Zero,
                                            0,
                                            pReqSize,
                                            IntPtr.Zero);

    reqSize = (uint)Marshal.ReadInt32(pReqSize, 0);

    IntPtr pDevInfoDetail = Marshal.AllocHGlobal((int)reqSize + 4); // +4 for cbSize

    // call again, this time getting the actual data wanted
    PInvoke.SetupDiGetDeviceInterfaceDetail(hList,
                                            ref infoSet,
                                            pDevInfoDetail,
                                            reqSize,
                                            IntPtr.Zero,
                                            IntPtr.Zero);

    string path;
    // work .NET magic to read from unmanaged memory the path string and assign it
    // to the above variable.  Deallocate both unmanaged memory blocks.

    return path;
}

最も苛立たしいことは、これらのアセンブリが2つの異なるプログラムによって使用されていることです。1つは、VisualStudioの分離シェルを使用するGUIです。もう1つは、単なるコマンドラインプログラムです。GUIが実行されているとき、上記のコードが呼び出され、期待どおりに実行されます。ただし、コマンドラインツールでは、何が起こったかに関するいくつかのデータで失敗します(このセットアップAPI関数のMSDNリファレンスで説明されています)。この時点では、返されたデータの一部しか回復できません。これがランタイムから返されるものです: "stem.Security.PartialTrustVisibilityLevel、mscorlib、Version = 4.0.0.0、Culture = neutral、PublicKeyToken=b77a5c561934e089"。

これがコードアクセスセキュリティと関係があることは知っていますが、修正方法がまったくわかりません。これまでに見つけたいくつかの提案を使用して、この属性をアセンブリに試しました(コードの名前空間ブロックの前に配置しました):[アセンブリ:AllowPartiallyTrustedCallers]

しかし、これは他のコンパイルの問題を引き起こしました。

どうか、何でも最も役に立ち、大いに感謝します。

アンディ

4

1 に答える 1

0

残念ながら、この問題はまだ修正されていません。しかし、私が最初に考えたように、この問題はコードアクセスセキュリティとは何の関係もないようです。私は赤いニシンを投げられていました。Visual Studioのメモリウィンドウを使用してコードをステップ実行し、セットアップAPI関数を呼び出してそれらを埋める前に、これらの文字列がメモリ内にあることに気付きました。たまに、内容の異なる別のメモリブロックを取得することもありましたが、通常は貼り付けた内容になってしまいました。

この問題は、実際には64ビット環境と32ビット環境に関係しているように見えます(少なくとも、現時点での私の理論です)。

ただし、この質問は実際の問題ではないため、「回答」して閉じます。

于 2012-03-09T14:39:12.643 に答える