Refreshing a SOAP WSDL import file with Delphi

I’m consuming a web service from a Delphi desktop app and both the web service and the desktop app are being developed at the same time.   Because the WSDL generated by the web service can change, I need to refresh the service interface code that the Delphi code uses to access the web service.  It corresponds to the web references class that a .NET app would use to consume a web service.

You typically create the web service interface code by bringing up the WSDL Import Wizard from the File->New->Other menu in Delphi.  You get a dialog that prompts you for the location of the WSDL file or URL.  From the WSDL, it generates a unit with interfaces defined for the classes and objects exposed by the web service.  It creates the file with the name of the service, plus “.pas”.

It works pretty well, but if you need to refresh that file due to changes in the web service, you don’t need to use that wizard to update the file.  There is a command line tool that will generate a new output file from a specificied WSDL.  This tool is named WSDLImp.exe, and is located in the bin folder of your Delphi installation.

The typical syntax is

WSDLImp.exe -P http://localhost/somefolder/someservice.asmx?WSDL

That will generate a file named someservice.pas.  If you want to specify a different name for the file, you can use the “-=” command line parameter like this”

WSDLImp.exe -P -= http://localhost/somefolder/someservice.asmx?WSDL=myservice.pas

That will create the file myservice.pas.  Very handy if you want to use a different name than the default.  Now when you update the service interface, you can just run WSDLImp to reimport the web service interface.

Using the test form from remote connections for .NET web services

I’m working on a web service using C# and targeting the .NET 2.0 Framework.  Nothing terribly fancy, but it has some code to log the caller’s IP address (via HttpContext.Current.Request.UserHostAddress).  While testing the code, I like using the test form functionality that .NET provides with web services.  By design, it only works locally.  If you try to use the test form from a remote machine, you’ll get the error:

The test form is only available for requests from the local machine

That’s fine, when you expose a web service you don’t want to make it too easy for people to start poking at your web service methods with a pointy stick.  Still, I wanted to test it from another machine and it saves time being able to enter in different values without having to code up a test framework.  Plus, I wanted to make sure that my code was reliably picking up the caller’s IP address.

After just a tiny bit of searching in the series of tubes, I found how to easily enable the web service test form for remote connections.  Juan Ignacio Gelos posted what you need to add to the web service web.config file to enable the test form.

<configuration>
<system.web>
<webServices>
<protocols>
<add name="HttpGet"/>
<add name="HttpPost"/>
protocols>
webServices>
system.web>
configuration>

You are still limited to run methods that have simple data types as input, but it’s very handy for testing.  Since this setting lives in web.config, it’s easy to remove it when I run a build.  I’m using FinalBuilder on a dedicated build box and it’s easy to clean up .config files so that developer settings get scrubbed before the files get packages into an installer.

Using Delphi in a team

I was just reading Marshall Fryman’s post about getting Delphi set up in a uniform way in a team or group setting.  He’s looking for a tool to manage the 3rd party components and compiler patches so that everyone on the team has the same setting.

What we ended up doing was documenting the install process for each component and compiler patch in our internal development wiki.  I prefer this method rather than an automated process like what Marshall described.  The wiki has a page that documents each step and provides helpful notes and also includes extra information when needed.  When we change or update a component, we just update that article in the wiki and then notify the developers what would be affected by the change.  We used MediaWiki, but any decent wiki package would do.

This isn’t limited to Delphi, we do the same for our .NET development environments.  When we rebuild a PC or add a new team member, it’s a straight forward process to get the IDE setup to our team standard.  It also allows us to customize the how we want the components to be installed.  For example, we make sure that each component set has the compiled units separate from the source code.  By just having the compiled files on the search path, doing full builds will not need to spend extra time compiling the third party code.  Most 3rd party packages already do that, but not all of them.  That saves a bit of time.  We also enforce a no warning and no hint rule on our own code.  Doing a full build with 3rd party code in the mix will toss out all sorts of warning/hint messages that we don’t need to see.

We also have a dedicated build PC.  The IDE settings on that machine provide the baseline for the wiki article and ensures that a QA-ready build will be compiled with the right settings and the right components.  When one of our developers needs to verify that his settings are correct, they can remote in to the build machine and compare the settings.  We let our developers deviate from our team standard, but not the build machine.  It’s our “Gold Standard“.

Marshall suggested that CodeGear should define an API the provides a mechanism for 3rd party vendors to install their components to a shared repository.  The IDE would then pull the components from the repository to the locally installed IDE.  That sounds intriguing, but I just don’t see everyone getting on board with this one.  Writing an installer to add Delphi components isn’t rocket science, but it can be a little tricky.  Adding a new API to that process adds a non-trivial amount of work to the component vendor. 

A lot of what goes under the hood of a component installer is determined at run time for the installer, based on the settings of the IDE that it is installing into.  The DevExpress installer is pretty intricate.  They use a single executable to install their any and all of their Delphi VCL components.  It handles all of the currently supported compilers and the packages that get installed are determined at runtime, based on your registration code.  In addition to installing or repairing the Delphi components, it will also remove the older versions of those components.  It has some fairly tricky logic, but it works very well.

To include support for a component repository API, a bunch of issues is created for the component vendor.  Most component vendors provide their license is by the user.  The API would need a mechanism to store individual licenses and install counts for group license.  The component vendors would have to come up with a standard mechanism for handling registration or license codes.  DevExpress validates their registration codes online against a user account and email address.  This new API would have to handle that.  I just don’t see that happening.  There would issues with components that are add-ons to other components.  You would need to implement the logic for the API to address version conflicts between the component vendors.

The idea of using a repository to manage 3rd party components sounds intriguing, but I just don’t see the component vendors getting on board.  There would be a lot of work adapting installers to the new API and I just don’t see the ROI in it.  For the most part, this would be a feature used infrequently.  It’s not like you are installing your Delphi components every day or even every month.  I used to write the QuickReport installers and while the Delphi versions were pretty easy to install, the C++Builder (this goes back 8 years) were just a nightmare to get right.  The last thing you want to do is to make that process anymore complex than it already is.

We started using the wiki approach when we migrated to Delphi 2007.  The first person sailing into the void (usually me) would write the installation instructions as each step was performed on his box.  The next step would be to update the build machine using the Wiki instructions.  This allows us to perform a sanity check on the wiki instructions and make any corrections as needed.  That made the process for the rest of the team pretty much a trouble-free experience.  We do the same thing with our Visual Studio environments. 

The wiki method also lets us document which service packs or hot fixes are required for each IDE.  It also list optional components or packages that, while not required, provide for a better experience with IDE.  Stuff like the DelphiSpeedUp IDE plugin or the GExperts tools are handy, but not required.

Get ready to say good bye to Google Page Creator

When I get some spare time, I plan on revamping the layout of this blog.  Right now, it’s an ugly mess of hacks placed in Blogger templates.  I want to make use of external CSS and Javascript files, but Blogger doesn’t allow you to upload those types of files.  Since of the design goals for this blog is to run it for free, I wanted to have a way of hosting CSS and Javascript files without having to use a paid hosting account.

I read a cool blog article writen by Lars Gersmann on how to add WordPress style calendar pages to Blogger based blogs to jazz up the blog post timestamp.  Lars provided the links the .css and .js files, hosted on his Google Page Creator account.  That looked vaguely familiar, I have a Google Page Creator account gathering virtual dust out in the cloud.  I logged in my Google Pages account and saw an announcement that Google was pulling the plug on Google Page Creator.  if you don’t have a Google Page Creator account now and go to the site, Google Page Creator, you’ll see one of the messages.

On August 4th, Google posted an announcement that they would be shutting down Google Page Creator later this year in favor of Google Sites.  Both sites let you create simple web sites very easily, but Google Sites, will not let you host your own .css or .js files.  Sometime later this year, Google will be shutting down Google Page Creator and I’m assuming that any site left there will be purged.  Google Page Creator was part of Labs.Google.com, which basically means it was a beta project with no guarantee that it would be around as a permanent fixture.

Why doesn’t an OS that backs your OS have any means of backing itself up?

Steve Tibbets has been writing about his troubles with Windows Home Server.  His homebrew Windows Home Server box had a failing power supply and it hosed the registry on the way out.  When he replaced the power supply, he was forced to reinstall Windows Home Server and he’s facing the fun task of trying to recover the data across 4 drives.   Windows Home Server is based on Windows Server 2003, which has the System Restore functionality.  He should have been able reboot the Windows Home Server in recovery mode and restore the OS from the last good system backup.  But that was not the case.

That stuff kind freaks me out about Windows Home Server.  I was in the beta and I had taken my last development machine at home and configured it for Windows Home Server.  The machine had motherboard issues and went to the land where DOS is eternally blessed after a few weeks.  While it was running, I have to say Windows Home Server is pretty cool.  It has a set and and forget it approach for doing bare metal backups of your home machines.  Since it’s Server 2003 based, you get some of the Server 2003 functionality, like a full blown version of IIS.

I’ve been running a FreeBSD solution called FreeNAS to back key files on my home machines.  It doesn’t have the cool features of Windows Home Server, but the price was right and it just works.  FreeNAS will boot from a CD, if the current FreeNAS box dies, I can just slap the drives in another box and install FreeNAS in just a few minutes.  I’ve been toying with the idea of buying one of the HP MediaSmart Home Server with Windows Home Server, but for the amount of money one of those boxes cost, I can hang 1TB external drivers off each machine at home and run scripts every night to RoboCopy every thing to the external drives.

Why www.nbc.com wont load with IE7 on Vista (and how to get around it)

My kids wanted to watch the Olympic swimming events going on in Beijing.  Since NBC is streaming all the venues, I figures I would just fire up the web browser and wander over to www.nbc.com.   We have a “family” pc that everyone can use and it runs Vista Home Premimum (32-bit), with Service Pack 1 installed.  Since I knew that NBC was going to be using the Microsoft stack with Silverlight to stream the video, I figured I would have the least amount of headaches with Internet Explorer 7.  Wrong!

When I entered in http://www.nbc.com into IE, I got the following error: “Internet Explorer cannot display the webpage”.  I figured I mistyped the URL, that wasn’t it.  Out of the relatively small combinations that the letters N, B, and C can be arranged, I did have the right URL.  Could it be that NBC.com was done?  Nope, I tried “ping –n 1 www.nbc.com” and received the following

Pinging a1669.g.akamai.net [128.242.186.219] with 32 bytes of data:                               
                                                                                                 
Reply from 128.242.186.219: bytes=32 time=44ms TTL=55                                            
                                                                                                 
Ping statistics for 128.242.186.219:                                                             
    Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),                                         
Approximate round trip times in milli-seconds:                                                   
    Minimum = 44ms, Maximum = 44ms, Average = 44ms                                                

That tells us that their site is live and responding to requests.  Just for giggles, I launched FireFox 3 and entered in the URL.  Sure enough, that worked just fine.  What was the problem with nbc.com and IE7?  I did a search with Google (and Yahoo for a change of pace) and saw that a number of people were reporting the same problem.  No one knew the cause and the only resolution was “just use Firefox”.  Normally, that would be an acceptable answer for me.  Today, I’m feeling a bit cranky and I want to know what the problem is between nbc.com and IE7.  The odds are it’s something trivial on the nbc,com side.  We haven’t had any problems with IE7 on Vista before.

I did notice that a lot of people reporting the problem had Tablet PC’s. I don’t have a Tablet PC, it’s just an plain ol’ Dell desktop.  But I did install a Wacom Bamboo tablet and installing it’s drivers did activate some user input functionality in Vista that wasn’t there before.  Why would this affect the browser?  As it turns out, when Vista thinks it’s now a Tablet PC the user agent string sent by IE changes.

Here’s the typical user-agent string sent by IE7 for various operating systems.

For Windows XP SP2: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)

For Windows 2003 Server: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2)

For Windows Vista: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)

Note, these are the base strings, different applications can change or add to these values.  On my machine, the user agent has some information:

Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506; .NET CLR 3.5.21022; Tablet PC 2.0; Creative ZENcast v2.01.01)

That says that I’m running IE7 on Vista, with .NET 2, 3, and 3.5 installed.  Media Center extension are installed, it thinks it’s a Tablet PC, and I have Creative’s Zencast (a podcast download app).

Notice the text in bold, “Table PC 2.0”.  When that text is submitted to www.nbc.com as part of the user agent, the website is doing some sort of re-direct that is failing.  So we have what appears to the cause of the problem, now how do we fix it.  I tried faking out the user agent string with a download from Microsoft called the User Agent String Utility, version 2.  Don’t event bother with that one.  It opens up a new browser window that has been tweaked to report itself as IE 6.0 but that’s the only part of the user agent string that gets modified.  It still uses “Table PC 2.0”, so the problem still remains.

In theory, you can edit the list of items that get tacked on the user agent string by hacking at the registry.  With IE7, the list of fields added to the user agent string are defined as REG_SZ values in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\5.0\User Agent\Post Platform.  I tried removing “Tablet PC 2.0” from the list, but the OS kept putting it back in.  Plus, we really shouldn’t have to modify our systems, the problem is due to www.nbc.com not sniffing the user agent string correctly.

I did a little searching on the Internet and I found a working solution here.  Instead of using www.nbc.com as the starting URL, use www.nbci.com.  That site bypasses the user agent check and it allowed me to the live feeds of the Olympic events.  A very simple solution, but a typical home user would never figure it out on his own and just blame Vista for it.

How to log the TIDSmtp component

I have some Delphi code that needs to send a quick mail message so I was using the Indy 10 TIdSmtp component.  The code was working just fine for a few months, but this week it would fail with an EIdSMTPReplyError exception.  The message property of the exception was a empty string, not terribly useful.  After a bit of googling, I found references to using one of the Indy TIdLogXXXX components.  Sure enough, there is a TIdLogFile component that will log messages to a file.  That sounded like what I needed, but the help file did not make it clear on how to hook up a TIdLogFile to a TIdSmtp component.

I did some searching and found a blog post by Marshall Fryman on his Ruminated Rumblings blog that a great example of how to hook up one of the Indy logging components.  What I needed to do was to create an instance of the TIdSmtp’s IOHandler property and assign the TIdLogFile to the IOHandler.Intercept property.  He also recommended assigning the IOHandler.OnStatus event to TIdLogFile.OnStatus event

The way my code ended up was something like this:

      try
        try
          IdLogFile.Active := true;
          fsmtp.IOHandler := TIdIOHandler.MakeDefaultIOHandler(fsmtp);
          fsmtp.IOHandler.Intercept := IdLogFile;
          fsmtp.IOHandler.OnStatus  := fsmtp.OnStatus;
          fSMTP.Connect;
          fSMTP.Send(fMessage);
        except
          on e: exception do begin
            MessageDlg(‘Error sending message: ‘ + e.Message, mtError, [mbOK], 0);
          end;
        end;
      finally
        if fSMTP.Connected then
          fSMTP.Disconnect(true);
        IdLogFile.Active := false;
      end;

How to disable the Windows Shutdown Tracker Dialog

Rick Strahl posted a great tip on how to disable the Windows Shutdown Tracker Dialog. That’s the dialog that Serer 2003 and Server 2008 make you respond to when you reboot or power down the server.  As Rick noted, usually the only time that you need to reboot a Windows Server is when you install an update from Microsoft.  It’s collecting information that you’ll never use.  You can disable that dialog by making a change in the local computer Group Policy.

To disable the dialog, do the following:

  • Run the Group Policy Object Editor by typing “gpedit.msc” from the “Run…” dialog.
  • Navigate down to Local Computer Policy\Computer Configuration\Administrative Templates\System
  • Double-click on “Display Shutdown Event Tracker” and click on the “Disabled” radio button
  • Click the “Ok” button to close the dialog with the new setting.
  • Close the Group Policy Object Editor.

This will work for both Server 2008 and Server 2003.