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