我已将一些DHCP Win32 Api转换为C#,因此我可以使用Power
Shell:
$definition = @" using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; using System.Net; namespace Dhcpsapi { public enum DHCP_SEARCH_INFO_TYPE : int { DhcpClientIpAddress = 0,DhcpClientHardwareAddress = 1,DhcpClientName = 2 }; [StructLayout(LayoutKind.Sequential)] public struct DHCP_BINARY_DATA { public uint DataLength; public IntPtr Data; }; [StructLayout(LayoutKind.Sequential)] public struct DHCP_IP_ADDRESS { public UInt32 IPAddress; } [StructLayout(LayoutKind.Explicit,Size=8)] public struct SearchInfo { [FieldOffset(0)] public DHCP_IP_ADDRESS ClientIpAddress; [FieldOffset(0)] public DHCP_BINARY_DATA ClientHardwareAddress; [FieldOffset(0)] public IntPtr ClientName; //LPWSTR } [StructLayout(LayoutKind.Sequential)] public struct DHCP_SEARCH_INFO { public DHCP_SEARCH_INFO_TYPE SearchType; public SearchInfo SearchInfo; } [StructLayout(LayoutKind.Sequential)] public struct DATE_TIME { public UInt32 dwLowDateTime; public UInt32 dwHighDateTime; public DateTime ToDateTime() { if (dwHighDateTime == 0 && dwLowDateTime == 0) { return DateTime.MinValue; } if (dwHighDateTime == int.MaxValue && dwLowDateTime == UInt32.MaxValue) { return DateTime.MaxValue; } return DateTime.FromFileTime((((long)dwHighDateTime) << 32) | dwLowDateTime); } } [StructLayout(LayoutKind.Sequential,CharSet = CharSet.Auto)] public struct DHCP_HOST_INFO { public uint IpAddress; public string NetBiosName; public string HostName; } [StructLayout(LayoutKind.Sequential,CharSet = CharSet.Auto)] public struct DHCP_CLIENT_INFO { public uint ClientIpAddress; public uint SubnetMask; public DHCP_BINARY_DATA ClientHardwareAddress; [MarshalAs(UnmanagedType.LPWStr)] public string ClientName; [MarshalAs(UnmanagedType.LPWStr)] public string ClientComment; public DATE_TIME ClientLeaseExpires; public DHCP_HOST_INFO OwnerHost; } public static class PS { [DllImport("Dhcpsapi.dll")] public static extern uint DhcpGetClientInfo( [MarshalAs(UnmanagedType.LPWStr)] string ServerIpAddress,[MarshalAs(UnmanagedType.Struct)] ref DHCP_SEARCH_INFO SearchInfo,out IntPtr ClientInfo); [DllImport("dhcpsapi.dll",SetLastError=true)] public static extern void DhcpRpcFreeMemory(IntPtr BufferPointer); } } "@ Add-Type -TypeDefinition $definition -PassThru
现在我尝试在PowerShell中使用它:
$dsi = New-Object dhcpsapi.DHCP_SEARCH_INFO $dsi.SearchType = [Dhcpsapi.DHCP_SEARCH_INFO_TYPE]::DhcpClientIpAddress $ipa = [System.Net.IPAddress]::Parse("10.4.3.101") $ip = [UInt32][System.Net.IPAddress]::NetworkToHostOrder([int][System.BitConverter]::ToUInt32($ipa.GetAddressBytes(),0)) # $ip is now 168035173 $dsi.SearchInfo.ClientIpAddress.IPAddress = $ip #however $dsi.SearchInfo.ClientIpAddress.IPAddress is 0 $dsi.SearchInfo.ClientIpAddress.IPAddress
运行之后$dsi.SearchInfo.ClientIpAddress.IPAddress是0而不是168035173,正如我所料.为什么会发生这种情况(它可以按预期从C#开始工作)以及如何使其正常工作?
解决方法
SearchInfo是一个结构,所以当你这样做时:
#however $dsi.SearchInfo.ClientIpAddress.IPAddress is 0 $dsi.SearchInfo.ClientIpAddress.IPAddress
然后,您正在创建SearchInfo的副本,并且该副本上的值正在变异.对于每个结构,您需要改变结构,然后将其分配回来:
$clientIpAddress = $dsi.SearchInfo.ClientIpAddress $clientIpAddress.IPAddress = $ip $searchInfo = $dsi.SearchInfo $searchInfo.ClientIpAddress = $clientIpAddress $dsi.SearchInfo = $searchInfo