2012-03-08 55 views
0

我正在重新說明這個問題,因爲我現在對它有了更多的瞭解。原來,我的含義太模糊。我發現我被稱爲「代碼訪問安全性」。對於每個人來說,這是一句老生常談,但我確信,但對我而言並非如此。代碼訪問安全性正在阻止PInvoking安裝API調用

該應用程序非常大,所以簡而言之,我有兩個程序集。一個是在整個程序中使用各種「工具」的實用程序集合。另一個是要求這些工具才能正常工作。

在實用程序集合中,有許多函數是PInvoked,但是讓我感到悲傷的是:SetupDiGetDeviceInterfaceDetail()(see here)。我的函數原型是這樣的:

[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結構中(see here)。例如:

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 Isolated Shell的GUI。另一個只是一個命令行程序。當GUI運行時,上面的代碼被調用並按預期執行。但是,在命令行工具中,它們會失敗(如在此Setup API函數的MSDN參考資料中所述),並提供有關發生了什麼的一些數據。在這一點上,我只能恢復一部分返回的數據。這是從運行時返回的內容:「stem.Security.PartialTrustVisibilityLevel,mscorlib,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089」。

我知道這與代碼訪問安全性有關,但我完全不知道如何解決。使用我迄今發現的一些建議,我已經試過這個屬性到程序集(我把它放在名稱空間代碼塊之前): [assembly:AllowPartiallyTrustedCallers]

但是,這導致了其他編譯​​問題。

請,任何東西將是最有幫助和極大的讚賞。

Andy

+0

您能否提供完整的異常詳細信息,如其ToString()方法返回的那樣? – 2012-03-08 19:35:22

+0

@Nicole據我所知,沒有異常正在產生。 Visual Studio不打破任何未處理的異常,並且我的代碼未包含在try/catch塊中。我的唯一跡象是安裝程序API函數返回錯誤代碼1784(無效的用戶緩衝區),並將設備的詳細信息暴露給路徑成員。不幸的是,當我增加緩衝區的大小來捕獲它時,我只能得到無意義的數據。 – 2012-03-08 19:43:57

+0

您在哪裏找到對PartialTrustVisibilityLevel的引用? – 2012-03-08 20:05:29

回答

0

不幸的是,問題還沒有解決。但是,這個問題似乎與我第一次想到的Code Access Security無關。我被扔了一隻紅鯡魚。我使用Visual Studio中的內存窗口逐步完成代碼,發現在調用Setup API函數填充它們之前,這些字符串在內存中。偶爾,我也會得到不同內容的不同塊,我通常只會粘貼我粘貼的內容。

這個問題實際上似乎與64位和32位環境有關(至少這是我的理論)。

但是,這個問題不是真正的問題,所以我「回答」它關閉它。

+0

你必須接受你自己的答案。當然也不會關閉問題。 – 2012-03-09 15:24:52

相關問題