我 p/invokingInternetSecurityManager.GetZoneMappings()是為了從我的 Intranet 區域獲取安全站點串列,并且Next()回傳IEnumString物件上的方法總是報告獲取了零個站點,即使有。
這是我的代碼,基于這個答案:
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Runtime.InteropServices
Imports System.Runtime.InteropServices.ComTypes
Public Class Test
Private Shared ReadOnly CLSID_InternetSecurityManager As New Guid("7b8a2d94-0ac9-11d1-896c-00c04fb6bfc4")
Private ReadOnly InternetSecurityManager As IInternetSecurityManager
Private ReadOnly SecurityManager As Object
Private Const URLZONE_LOCAL_MACHINE As UInteger = &H0
Private Const URLZONE_INTRANET As UInteger = URLZONE_LOCAL_MACHINE 1
Private Const URLZONE_TRUSTED As UInteger = URLZONE_INTRANET 1
Private Const URLZONE_INTERNET As UInteger = URLZONE_TRUSTED 1
Private Const URLZONE_UNTRUSTED As UInteger = URLZONE_INTERNET 1
Public Sub New
Dim oType As Type
oType = Type.GetTypeFromCLSID(CLSID_InternetSecurityManager)
Me.SecurityManager = Activator.CreateInstance(oType)
Me.InternetSecurityManager = Me.SecurityManager
Me.GetSites()
End Sub
Private Function GetSites() As List(Of String)
Dim nItemsFetched As ULong
Dim oEnumString As IEnumString
Dim oSites As List(Of String)
Dim aItems As String()
oEnumString = Nothing
Me.InternetSecurityManager.GetZoneMappings(URLZONE_INTRANET, oEnumString, 0)
oSites = New List(Of String)
aItems = New String(0) {}
Do
oEnumString.Next(1, aItems, nItemsFetched)
If aItems.First Is Nothing Then
Exit Do
Else
oSites.Add(aItems.First)
End If
Loop
Return oSites
End Function
End Class
它運行并且確實正確地列舉了串列,但我想通過適當地回應的值來清理它nItemsFetched(而不是目前相當繁瑣的檢查Nothing)。
似乎托管代碼示例GetZoneMappings()非常稀缺。很多簽名,但沒有使用。我找不到任何東西(事實上,對于我所有的搜索,這可能是唯一的一個)。不過,經過一番認真的挖掘,我確實設法將拇指放在EnumString上面鏈接的示例上。
這是我的IInternetSecurityManager界面,從p/invoke.net收集:
Imports System
Imports System.Runtime.InteropServices
Imports System.Runtime.InteropServices.ComTypes
<ComImport, Guid("79EAC9EE-BAF9-11CE-8C82-00AA004BA90B"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)>
Public Interface IInternetSecurityManager
<PreserveSig>
Function SetSecuritySite(
<[In]> pSite As IntPtr) As Integer
<PreserveSig>
Function GetSecuritySite(
<Out> pSite As IntPtr) As Integer
<PreserveSig>
Function MapUrlToZone(
<[In], MarshalAs(UnmanagedType.LPWStr)> pwszUrl As String, <Out> ByRef pdwZone As UInteger, dwFlags As UInteger) As Integer
<PreserveSig>
Function GetSecurityId(
<MarshalAs(UnmanagedType.LPWStr)> pwszUrl As String,
<MarshalAs(UnmanagedType.LPArray)> pbSecurityId As Byte(), ByRef pcbSecurityId As UInteger, dwReserved As UInteger) As Integer
<PreserveSig>
Function ProcessUrlAction(
<[In], MarshalAs(UnmanagedType.LPWStr)> pwszUrl As String, dwAction As UInteger, <Out> ByRef pPolicy As Byte, cbPolicy As UInteger, pContext As Byte, cbContext As UInteger, dwFlags As UInteger, dwReserved As UInteger) As Integer
<PreserveSig>
Function QueryCustomPolicy(
<[In], MarshalAs(UnmanagedType.LPWStr)> pwszUrl As String, ByRef guidKey As Guid, ByRef ppPolicy As Byte, ByRef pcbPolicy As UInteger, ByRef pContext As Byte, cbContext As UInteger, dwReserved As UInteger) As Integer
<PreserveSig>
Function SetZoneMapping(dwZone As UInteger, <[In], MarshalAs(UnmanagedType.LPWStr)> lpszPattern As String, dwFlags As UInteger) As Integer
<PreserveSig>
Function GetZoneMappings(dwZone As UInteger, <Out> ByRef ppenumString As IEnumString, dwFlags As UInteger) As Integer
End Interface
我嘗試IEnumString根據這篇文章構建一個界面,但我只是遇到了問題。至少本機呼叫完成并回傳資料。我只想知道資料什么時候停止。
我怎樣才能EnumString.Next()正確回傳它獲取的專案數?
uj5u.com熱心網友回復:
Next()回傳一個 HRESULT 值,所以 0 是S_OK(成功),這意味著它回傳rgelt.
所以,
- 您必須在呼叫之前分配
aItems(至少)1個元素的陣列; - 可選地,您可以將非空指標傳遞給
pceltFetched. 如果傳遞 null,則無法確定讀取了多少項; - 如果讀取了某些內容,則呼叫應回傳
S_OK(0),S_FALSE(1) 如果未讀取所有請求(在錯誤情況下可能還有其他內容),這在celt= 1 的情況下是相同的“這是列舉中的最后一項”。
所以,你的代碼可以這樣寫:
Do
Dim ret = oEnumString.Next(1, aItems, IntPtr.Zero)
If ret <> 0 Then Exit Do
oSites.Add(aItems.First)
Loop
或者如果你想使用這個pceltFetched引數,就像這樣。這很少需要,只有當celt> 1 (當回傳值只是說不是所有內容都被讀取)時,列舉源也不總是支持,所以每個人總是使用celt= 1 ...
Dim fetchedPtr As IntPtr
fetchedPtr = Marshal.AllocHGlobal(Marshal.SizeOf(Of Integer)()) ' or AllocCoTaskMem
Dim fetched As Integer
Do
oEnumString.Next(1, aItems, fetchedPtr)
fetched = Marshal.ReadInt32(fetchedPtr)
If fetched <> 1 Then Exit Do
oSites.Add(aItems.First)
Loop
Marshal.FreeHGlobal(fetchedPtr)
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/503727.html
