0

我正在重新措辞这个问题,因为我现在了解更多了。本来,我所拥有的太模糊了。我发现我正在被称为“代码访问安全”的东西路由。这对每个阅读本文的人来说都是老生常谈,我敢肯定,但对我来说不是。

该应用程序非常大,所以简而言之,我有两个程序集。一个是在整个程序中使用各种“工具”的实用程序程序集。另一个是调用这些工具以发挥作用。

在实用程序程序集中,有许多 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(请参见此处)。例如:

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;
}

最令人沮丧的是,这些程序集被两个不同的程序使用。一种是使用 Visual Studio 隔离 Shell 的 GUI。另一个只是一个命令行程序。当 GUI 运行时,上面的代码被调用并按预期执行。然而,在命令行工具中,它们会失败(如此 Setup API 函数的 MSDN 参考中所述),并提供一些有关发生情况的数据。此时,我只能恢复返回的部分数据。这是从运行时返回的:“stem.Security.PartialTrustVisibilityLevel, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089”。

我知道这与代码访问安全性有关,但我完全不确定如何解决。使用到目前为止我发现的一些建议,我尝试了程序集的这个属性(我把它放在代码的命名空间块之前):[程序集:AllowPartiallyTrustedCallers]

但这导致了其他编译​​问题。

拜托,任何事情都会最有帮助和非常感激。

安迪

4

1 回答 1

0

不幸的是,问题还没有解决。但是,正如我首先想到的那样,该问题似乎与代码访问安全性无关。我被抛出了一个红鲱鱼。我使用 Visual Studio 中的内存窗口逐步完成了代码,并注意到这些字符串在调用 Setup API 函数来填充它们之前就在内存中。有时,我也会得到不同内容的不同内存块,我通常只是以我粘贴的内容结束。

这个问题实际上似乎与 64 位和 32 位环境有关(至少,这是我目前的理论)。

但是,这个问题并不是真正的问题,所以我正在“回答”它以关闭它。

于 2012-03-09T14:39:12.643 回答