Important: Due to changes to Dell’s website, the script below no longer works. An updated script is available on this page.
This is a VBScript that I wrote a few months ago as an example of how to retrieve warranty information from the Dell website. The script writes warranty information to subkeys under HKLM\Software\DellWarrantyInfo in the registry.
Dell doesn’t provide a web service for querying warranty information (that I know of), so I had to scrape the HTML. That means this script may stop working properly if Dell makes changes to the layout of their warranty information page. I wish Dell provided a more reliable method for retrieving warranty information.
Update 1/3/2011: Thanks to Patrick for letting me know that dell added a new column to the warranty information table. I updated the script to reflect this.
Continue reading 'Dell Warranty Information Script'»
Alright, here’s the scenario:
- You’ve upgraded your web server to Windows 2008 and you have a bunch of Windows Vista and Windows 7 clients connecting to an ASP .NET application on that web server. The application uses My.Request.UserHostAddress to check the IP address of the client. For whatever reason, your application only expects an IPv4 address to be returned
- Both the server and the client have IPv6 functionality enabled (by default) but are only configured with IPv4 addresses.
- Since neither the client nor the server have an IPv6 address set, you would expect My.Request.UserHostAddress to return an IPv4 address. Instead, it returns an IPv6 address that starts with 2002 prefix.
How in the heck did this happen!? Well, it turns out that this behavior is by design. When Microsoft added IPv6 support beginning with Windows Vista, they added support for using IPv6 over an IPv4 network, for compatibility and transitioning purposes. By default, a Windows Vista or Windows 7 computer that only has an IPv4 address assigned to it will try to communicate over IPv6 by using a special IPv6 address called a 6to4 address. All 6to4 addresses start with the 2002 prefix. The good news is a 6to4 address is derived from the octets of an IPv4 address, so we can convert 6to4 addresses to their IPv4 equivalent. This Technet page goes into further detail about the 6to4 addressing scheme.
Here’s the code I wrote to convert 6to4 IPv6 addresses back to their IPv4 equivalent:
ipAddress = System.Net.IPAddress.Parse(My.Request.UserHostAddress)
If ipAddress.AddressFamily = Net.Sockets.AddressFamily.InterNetworkV6 Then '
Dim tmpBytes() As Byte = ipAddress.GetAddressBytes
If tmpBytes(0) = 32 And tmpBytes(1) = 2 Then 'Check it's a 6to4 address (it begins with "2002")
ipAddress = System.Net.IPAddress.Parse(Convert.ToString(tmpBytes(2)) & "." & Convert.ToString(tmpBytes(3)) & "." & Convert.ToString(tmpBytes(4)) & "." & Convert.ToString(tmpBytes(5)))
Note that this code will only be applicable to 6to4 IPv6 addresses. Normal IPv6 addresses will be ignored because they can’t be converted to an IPv4 equivalent. This means that your code will eventually need to handle IPv6 addresses if clients that connect to the application are ever assigned IPv6 addresses.
Sometimes I write code that I think I need but never end up using. This was the case with the parseCommandLineString() function that I wrote in Visual Basic .NET. I needed a function that would take a command line string that included arguments and parse it in the same way that Environment.ParseCommandLineArgs() does. Why? Because System.Diagnostics.ProcessStartInfo uses two properties that separate the executable file name from the arguments. Why Microsoft left this functionality out of the framework is beyond me. Anyway, there is a method build into the Windows API that can parse arguments from a command line string: CommandLineToArgv(). Unfortunately, calling it in VB .NET requires Marshalling and I couldn’t find a good example online. Here’s my code:
Private Declare Function CommandLineToArgv Lib "shell32.dll" Alias "CommandLineToArgvW" (ByVal lpCmdLine As String, ByRef pNumArgs As Integer) As Long
''' Summary: Parse the command line string so that it can be used with System.Diagnostics.Process. I chose to use the Windows API here to ensure that the command line parsing is consistent with how Windows handles it.
''' Parameter command: The string that should be parsed
''' Returns: An array of command line arguments similar to what Environment.GetCommandLineArgs() produces.
''' It sure would be nice if the framework had a method for doing this. It becomes a drawback of using System.Diagnostics.Process, which requires arguments to be separated from the executable.
Private Function parseCommandLineString(ByVal command As String) As String()
Dim numargs As Integer
Dim t As Integer
Dim ptrCommand As IntPtr = Marshal.StringToHGlobalUni(command) 'Marshal the string to a pointer
Dim ptrSplitArgs As IntPtr = CommandLineToArgv(ptrCommand, numargs) 'Pass the pointer to CommandLineToArgv for parsing, retrieve the pointer of the result.
If ptrSplitArgs = IntPtr.Zero Then Throw New System.ComponentModel.Win32Exception 'Is it a valid pointer? Throw an exception if it isn't.
Dim splitargs(numargs - 1) As String
For t = 0 To numargs - 1
splitargs(t) = Marshal.PtrToStringUni(Marshal.ReadIntPtr(ptrCommand, t * IntPtr.Size)).Trim 'Iterate through the arguments and add them to an array.