Arnout's Eclectica

But I digress…

Making HttpWebRequest work while having Fiddler decrypt SSL

Just a quick reminder to myself, so that I can forget about it...

Fiddler can act as a man-in-the-middle and decrypt SSL traffic, but then System.Net.Security rightfully complains about an invalid remote certificate ("The remote certificate is invalid according to the validation procedure."). This results in a System.Net.WebException "The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.".

To prevent this from happening:

ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

Just be sure to not include this in production code :-)

Registration-free COM

31 March 2007 0:40 — COM,Development,Windows

A while ago, I had the following problem:

  • The build system needed to run a unit test of some code that depended on some COM object.
  • That COM object was not installed on the build system (it wasn't a part of the system we were developing).
  • Installing that COM object would mean having to install a large system with all kinds of dependencies — not exactly something I wanted to do on the build machine...

Fortunately, the interaction with the particular COM object was very basic. I made a fake implementation of it, just returning hard-coded responses for the few calls I needed. With the fake COM object in place, the unit tests passed.

I added some logic to the build file that checks whether a particular ProgID existed in the registry. If not, the build script registers the fake object, runs the specific tests, and then unregisters it again.
If the ProgID is found in the registry, however, just the tests are executed. This allows the build to be also run on a developer's machine containing the back-end system (and not mess up its COM registration). Works great.

Fast-forward to yesterday.

Triggered by a discussion with a co-worker about the fact that the unit tests aren't nicely isolated from the back-end system this way, I suddenly remembered reading about registration-free COM on Junfeng Zhang's blog.

Registration-free COM

As the name implies, registration-free COM makes it possible to use COM objects without registering them. An application gets all activation information (typelib, ProgID-to-CLSID mapping, threading model and the like) from a manifest file, instead of reading it from the registry. This allows multiple applications to use different versions of a COM object, with the same ProgID and/or CLSID.

That's a much nicer solution for my original problem — I no longer have to dynamically register and unregister my fake implementation, and I can use the fake implementation on systems containing the real one as well.

A sample manifest file

The manifest file I'm using looks like this:

<?xml version='1.0' encoding='utf-8'?>
<assembly manifestVersion='1.0' xmlns='urn:schemas-microsoft-com:asm.v1'>
  <assemblyIdentity type='win32' name='RegFreeCOM-sample.exe' version='1.0.0.0' />
  <file name='FakeTCMXML.dll'>
    <comClass clsid='{69c2082a-61b1-4a83-a947-88420fac54fa}'
              threadingModel='Apartment'
              progid='TCMXML.XMLResponder' />
  </file>
</assembly>

I've saved this as RegistrationFreeCOM.exe.manifest in the same directory as my test application RegistrationFreeCOM.exe, and also copied my fake implementation FakeTCMXML.dll into that directory. The test application will activate TCMXML.XMLResponder from FakeTCMXML.dll, regardless of whether that ProgID already occurs in the registry, and without affecting that registration.

Creating a manifest file

For many scenarios, the sample manifest file is sufficient: just update the 'name', 'clsid' and 'progid' attributes. You can find the value for 'clsid' in the IDL for your component, or by using OleView.
You can also have Visual Studio 2005 create a manifest file for you: create a throw-away project, reference your COM dll, view the properties of that reference, and toggle the 'Isolated' flag to 'True'. When you build the project, the manifest file will be generated.

Copying message box text to the clipboard

9 May 2006 22:22 — Tips & Tricks,Windows

Screen dump of standard Windows message box containing the text "Did you know that CTRL-C copies this text to the clipboard?"

(This post triggered by receiving a lovely screen dump of a message box. A message box covering almost the complete screen, and containing lots of serialized XML. XML containing lots of entitified HTML...)

Displaying VMWare Server status on the desktop

2 May 2006 21:55 — VMWare,Windows

In another post, I provided a VB script that outputs the status of the guests running on a VMWare Server. With a tiny modification that script can be used within Sysinternals' BGInfo, to display this information on the host's desktop:

Screenshot showing information about VMWare guests on the desktop

In order to do this, change the line "WScript.Echo s" to "Echo s". In BGInfo, create a VBScript Custom field, by clicking "Custom...", "New...", selecting "VB Script file" and entering a field name and the path to your script.

Using VmCOM to display the status of VMWare Server guests

29 April 2006 15:17 — VMWare,Windows

VmCOM is a COM-based API that allows you to control VMWare Server from your own software. As an example, the following script displays the status of each registered guest:

Option Explicit
Dim cp, server, vmCollection, vmName, vm, s

Const vmErr_VMBusy = &H80040215
Const vmExecutionState_On = 1
Const vmExecutionState_Off = 2
Const vmExecutionState_Suspended = 3
Const vmExecutionState_Stuck = 4

Set cp = CreateObject("VmCOM.VmConnectParams")
Set server = CreateObject("VmCOM.VmServerCtl")

server.Connect cp
Set vmCollection = server.RegisteredVmNames

For Each vmName in vmCollection
   Set vm = CreateObject("VmCOM.VmCtl")
   On error resume next
   vm.Connect cp, vmName
   If Err.Number = vmErr_VMBUSY Then
      s = Basename(vmName) & ":      BUSY"
   ElseIf Err.Number <> 0 Then
      s = Basename(vmName) & ":     ERROR"
   Else
      On Error Goto 0
      s = vm.Config("displayName") & ": " & State2Str(vm)
   End if
   WScript.Echo s
next


Function State2Str(ByVal vm)
  Select Case vm.ExecutionState
      Case vmExecutionState_On
         State2Str = "       ON"
      Case vmExecutionState_Off
         State2Str = "      OFF"
      Case vmExecutionState_Suspended
         State2Str = "SUSPENDED"
      Case vmExecutionState_Stuck
         State2Str = "    STUCK"
      Case else
         State2Str = "  UNKNOWN"
   End Select
End Function


Function Basename(ByVal path)
   Dim pos
   pos = InstrRev(path, "\")
   If pos > 0 Then
      Basename = Mid(path, pos + 1)
   Else
      Basename = path
   End If
End Function

Copyright © 2006-2009 Arnout Grootveld — Powered by WordPress — Hosted at pair Networks