我正在重新措辞这个问题,因为我现在了解更多了。本来,我所拥有的太模糊了。我发现我正在被称为“代码访问安全”的东西路由。这对每个阅读本文的人来说都是老生常谈,我敢肯定,但对我来说不是。
该应用程序非常大,所以简而言之,我有两个程序集。一个是在整个程序中使用各种“工具”的实用程序程序集。另一个是调用这些工具以发挥作用。
在实用程序程序集中,有许多 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]
但这导致了其他编译问题。
拜托,任何事情都会最有帮助和非常感激。
安迪