2011-11-30 54 views
2

我不是那麼熟悉非託管代碼,但一直在我的C​​#應用​​程序中使用dnsapi.dll中的一些方法。有很多關於如何使用DnsQuery或DnsFlushResolverCache的示例,但DnsValidateServerStatus方法似乎是新的(需要Win 7或Server 2008 R2)。我想從我的C#應用​​程序中使用這種方法,但我似乎無法使Marshaling和結構正常工作。此方法的文檔可在以下網址找到: http://msdn.microsoft.com/en-us/library/windows/desktop/ee837436(v=VS.85).aspx如何P /調用dnsapi.dll方法:DnsValidateServerStatus

請幫忙!

+1

避免使這是一個'發送我的代碼'問題,張貼你得到。 –

+0

當你瞭解這一點時,考慮將解決方案發布到http://pinvoke.net。 – dthorpe

回答

0

這個Win32 API中的困難的部分是SOCKADDR結構。在PINVOKE.NET上有一個SOCKADDR結構的實現。以下示例基於此實現:

[DllImport("Dnsapi.dll")] 
private static extern int DnsValidateServerStatus(IntPtr sockaddr, string queryName, ref uint serverStatus); 

WinsockSockAddr addr = new WinsockSockAddr(IPAddress.Parse("127.0.0.1"), 0); 
uint serverStatus = 0; 
int status = DnsValidateServerStatus(addr.PinnedSockAddr, "fqdn server name", ref serverStatus); 

Console.Out.WriteLine(status); 
Console.Out.WriteLine(serverStatus); 

希望,這有幫助。

+0

這似乎大部分工作!當服務器不可用時,我得到每個API的DNS_VALSVR_ERROR_UNREACHABLE和DNS_VALSVR_ERROR_NO_RESPONSE。當服務器運行時,我得到DNS_VALSVR_ERROR_NO_AUTH,不知道爲什麼我沒有獲得成功的方法。也許我使用queryName錯誤? – user1073928

0

不知道它的工作原理:

[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, CharSet=System.Runtime.InteropServices.CharSet.Ansi)] 
public struct sockaddr { 

    /// u_short->unsigned short 
    public ushort sa_family; 

    /// char[14] 
    [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=14)] 
    public byte[] sa_data; 
} 



    /// Return Type: DWORD->unsigned int 
    ///server: PSOCKADDR->sockaddr* 
    ///queryName: PCWSTR->WCHAR* 
    ///serverStatus: PDWORD->DWORD* 
    [System.Runtime.InteropServices.DllImportAttribute("dnsapi.dll", EntryPoint="DnsValidateServerStatus")] 
public static extern uint DnsValidateServerStatus([System.Runtime.InteropServices.InAttribute()] ref sockaddr server, [System.Runtime.InteropServices.InAttribute()] [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPWStr)] string queryName, [System.Runtime.InteropServices.OutAttribute()] out uint serverStatus) ; 
} 
+0

這看起來類似於我一直在玩的東西。爲了測試PInvoke的,我會使用類似: 公共靜態無效測試() \t \t { \t \t \t的sockaddr地址=新的sockaddr(); \t \t \t addr.sa_family = 1; \t \t \t IPAddress ip = IPAddress.Parse(「10.70.72.20」); \t \t \t addr.sa_data = BitConverter.GetBytes(ip.Address); \t \t \t string query = string.Empty; \t \t \t uint status = 0; \t \t \t uint result = DnsValidateServerStatus(ref addr,query,out status); \t \t} 在這種情況下,由於IP的字節數組並不像結構中指定的14那麼大,所以我總是得到Marshaling異常。 – user1073928

+0

我從結構中刪除了SizeConst = 14,然後每次都會返回狀態爲4的pinvoke。 – user1073928

+0

嘗試使用http://msdn.microsoft.com/en-us/library/system.net.ipaddress.getaddressbytes.aspx獲取地址字節。 – user629926