Я переписываю этот вопрос, так как теперь я понимаю немного больше. Изначально то, что у меня было, было слишком расплывчатым. Я обнаружил, что меня маршрутизирует нечто, называемое «Безопасность доступа к коду». Я уверен, что это знакомая всем, но не мне.
Приложение очень большое, поэтому в двух словах у меня две сборки. Одним из них является сборка утилит с различными «инструментами», используемыми в программе. Другой призывает эти инструменты, чтобы функционировать.
В сборке утилит есть много функций, которые вызываются 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);
В сборке, которая использует эту функцию, я использую двухэтапный процесс, описанный в комментариях, чтобы понять, сколько места мне нужно для хранения DevicePath, который находится в структуре SP_DEVICE_INTERFACE_DETAIL_DATA ( см здесь ). Например:
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. Другой просто программа командной строки. Когда GUI работает, приведенный выше код вызывается и выполняется, как и ожидалось. Однако в средстве командной строки они терпят неудачу (как описано в справочнике MSDN для этой функции API настройки) с некоторыми данными о том, что произошло. На данный момент я могу восстановить только часть возвращенных данных. Вот что возвращается из среды выполнения: «stem.Security.PartialTrustVisibilityLevel, mscorlib, версия = 4.0.0.0, Culture = нейтральный, PublicKeyToken = b77a5c561934e089».
Я знаю, что это как-то связано с Code Access Security, но я совсем не уверен, как это исправить. Используя некоторые предложения, которые я нашел до сих пор, я попробовал этот атрибут в сборке (я поместил его перед блоком пространства имен):
[сборка: AllowPartiallyTrustedCallers]
Но это вызвало другие проблемы компиляции.
Пожалуйста, все, что будет наиболее полезно и высоко ценится.
Andy