Tuesday, December 27, 2005

How to replace a installed buggy .MSI file with a fixed one.

Aaron listed a couple of ways of removing a buggy .msi file that was installed, but would not uninstall. This is why I test all of my .msi files with VMWare. Being able to rollback changes to a virtual machine is priceless.

  1. Forcibly install a fixed version of the MSI - for this option, I took my newly fixed MSI that no longer had the uninstall bug and ran the following Windows Installer command line to force it to be installed over the top of the buggy one that was stuck on my system: msiexec.exe /fvecmus my_product.msi.  This command line forcibly replaced the old installation with the new one by running from the source MSI and recaching the copy of the MSI in %windir%\installer.  This removed the bug that blocked uninstall, and after that I was able to launch uninstall from Add/Remove Programs and everything worked as expected for me.
  2. Manually edit the cached MSI - for this option, I found the locally cached copy of the MSI in %windir%\installer (by looking at timestamps and finding the most recently created file in that folder), opened it in the Orca MSI editing tool, and then manually removed the entries from the LaunchCondition table that were blocking uninstall from running.  This option can be used to fix simple errors, but complex errors will likely be difficult to manually fix in an MSI editor such as Orca.


from [Aaron Stebner's WebLog]

Prototype vs. Atlas

I came across an interesting blog posting about the Prototype Javascript package and how it compares with Atlas. It boils down to they try to do similiar things, but come from different directions. Atlas is server-side centric and is designed to bolt into Visual Studio and Prototype is client-side oriented and isn't a .NET tool (100% Javascript). Check out the links to moo.fx and Rico in that article, they are doing some cool UI things with Prototype.

Thursday, December 22, 2005

Great, now they are targetting VMWare


A vulnerability has been discovered in vmnat.exe on Windows hosts and vmnet-natd on Linux systems. The vulnerability in this component affects VMware Workstation 5.5, VMware GSX Server 3.2, VMware ACE 1.0.1, VMware Player 1.0, and previous releases of these products. The vulnerability makes it possible for a malicious guest using a NAT networking configuration to execute unwanted code on the host machine.

VMware believes that the vulnerability is very serious and recommends that affected users update their products to the new releases available at www.vmware.com/download or change the configuration of the virtual machine so it does not use NAT networking.

from [Spyware Warrior]

Iv'e been using VMWare for years. I implement the installers for most of our companies products and there is no way I could test the installers with running various combinations of Windows inside VMWare sessions. I could use Virtual PC as it comes with my MSDN subscription, but I think VMware is still a better product.

Wednesday, December 21, 2005

The joy of editing the Mac OS X hosts file

I have a G4 iMac on my desk. You know, one of the ones that looks like a desk lamp. It competes for space with my two XP boxes. I do my development under XP, the iLamp is for testing our web apps. The ilamp more or less sees our network, but it can't resolve workstation WINS names to actual IP addresses. Since I know zip about configuring Mac OS X networking, I figured I would cheat and just add the workstation IP addresses to the hosts file on the iLamp. In a normal OS, you just edit the hosts file and be done with it, not with the iLamp. No sir, you have to mix the cutting edge of 1978 technology with arcane Mac OS X commands. After some googling, I found what I needed here at macosx.com. You have to run a unix/linix/whatever shell, edit or create the hosts file, then load it with niload. And that's the simple way to do it. If you want to do it with the GUI tools, it's pretty damn tedius.

Launch netinfo, located at /Applications/Utilities/NetInfoManager
Under the Domain menu, select Security, and Authenticate. Type a username and password with admin prividledges.

Select, in the Directory Browser, / and then 'machines'.

Either press apple-n, the icon that looks like 'new folder' or go to the Directory menu, and select 'new sub directory'.

This should insert a flag at /machines/net_directory

Unless you are creating an entry for a host named 'new_directory' you'll want to rename it.

Select, in the 'Directory: new_directory' plane that has 'property and Value(s)' stuff the first, and only entry ("name | new_directory").

Under the 'Directory' menu, select 'Delete value'.

The entry should now read 'name | '. Which is good.

Now, enter the hostname, which can be something simple like myfileserver or as 'complex' as files.danz.quons.net or whatever.

So, select the name and line, and go to the directory menu, and select 'insert value'. (option-apple-i)
Now type the hostname.

Next, we need to input an ip address.

First, insert a new property, called 'ip_address'.
apple-shift-n or apple-shift-i (eye - look in the directory menu, you'll see it).

where it says 'new_property', click and type 'ip_address'.

Where it says 'new_value', type the ipaddress that goes with the host you inserted.

If you wish, you can enter more than one hostname, so if for example you wish matrixbaby.graphics.ddn.net and matrixbaby both to go to the same IP, just insert an additional value to the name property:

Select 'name' and under, the 'directory' menu, select 'insert value' (apple-option-i).

That should do it, close out of netinfo, and you're set. If you wish to properly name your computer, either insert/modify the entry called 'localhost' and give it a name, in addition to localhost. I think thats what I did. you can also modify the /etc/hostconfig file, change the HOSTNAME= localhost to whatever you wish.

I guess it could be worse, at least Mac OS X has a command line.

Monday, December 19, 2005

Jon Galloway has a quick, consise post on how to restore a SQL Server 2000 database from a backup. I have all of this encoded, plus a something things, in ToolMS; but it's good to keep it on on file.

[JonGalloway.ToString()] DOS batch script to restore a SQL 2000 database and grant permission to ASPNET account

Friday, December 16, 2005

I’m in the market for a new 802.11g adapter for my wife’s PC.  I started out with a Linksys USB adapter, but it gets horrible reception. I ended up taking one of the SMC wireless bridges from one our Tivo's and putting it on here PC. The SMC bridges get incredible reception, but they are twice the price (or more) of a decent 802.11g adapter. One a week, I take the bridge off the PC and slap on the Tivo so it can phone home and get the latest program updates. Hawking just announced a new 802.11g adapter with a directional antenna, the HWU8DD. It looks like a cheap TV antenna but they are claiming a 8dBi gain in signal strength. In comparision, most 802.11 g adapters have a 1 or 2 dBi antenna. As you can see from the picture, the adapter has a small dish on it. This is a directional antenna, you get a better signal because you are aiming the adapter at the wireless access point and/or router. I may have to get of these puppies when they hit the retail market.

I have one of their Hi-Gain laptop cards and it gets an incredible signal, largely due to it's directional antenna. If you need to add a wireless card to your notebook, you will be hard pressed to find one with better reception than this one.

Adding "Install as..." to context menu

This comes from Michael Willers, by way of Dana Epp. This makes it easier to install .msi packages when logged in as a non-admin use. Too many home PC's are running in Admin mode, one of the many reasons why we have so many virus attacks out there.

If you run your box with a non admin account the "Run as..." entry in the context menu is very comfortable. Wouldn't it be nice to have something like "Install as..." for MSI-Packages? This is just a registry hack away

  1. Run regedit.exe under an account with administrative privileges

  2. Create the key HKEY_CLASSES_ROOT\Msi.Package\shell\runas\

  3. Set the default value to Install &as...

  4. Create the key HKEY_CLASSES_ROOT\Msi.Package\shell\runas\command\

  5. Set the default value to msiexec /i "%1"

Wednesday, December 14, 2005

Disabling the VMWare network adapters

When you are not running a VMWare session, you may want to disable the VMware virtual network adapters. I have found that they can slow down network operations on the host. Anything doing a UDP broadcast that is sentg over all adapters will take much longer to run if they broadcast over the VMWare adapters. The ListAvailableSQLServers function call in the SQLDMO library is one example that I came across that slowed down dramaticly with the VMWare adapters running.

You have at least three ways of enabling and disabling the network adapters. You can open up the Device Manager (click the "Start" button, select "Run...", enter devmgmt.msc), select the "VMware Network Adapter VMnet1" and "VMware Network Adapter VMnet8" adapters and press the disable button in the tool bar. The second option is to right click on "My Network Places" in the Start menu and select "properties". You can then right click on the "VMware Network Adapter VMnet1" and "VMware Network Adapter VMnet8" adapters and enable or disable them. The third method is via the command line, so that you can script it.

Microsoft, in it's infinite wisdom, does not provide a command line means of enabling or disabling network adapters out of the box. For that, you'll need DevCon.exe, the command line alternative to Device Manager. You can get from Microsoft as Knowledge Base article Q311272. With devcon, you can disable/enable a netwoirk adapter by it's hardware id. You can get the id from Device Manager, or by running devcon.exe like this:

devcon hwids =net

That will spit out a great deal of information, the ID's that you are looking for are *VMnetAdapter1 and *VMnetAdapter8. You can disable them individually or do both with a wildcard

devcon disable *VMnetAdapter1
devcon disable *VMnetAdapter8


devcon disable *VMnetAdapter*

The former probably executes faster, the latter is simpler. I run with the adapters disabled and I only enable them whem I am running a VMWare session.

If you are running Windows 7, you should head to Windows Driver Kit (WDK) Version 7.1.0 Release N, which includes a version of devcon that will install under Win7 64bit.  If you have an older release of the WDK, you can extract the devcon.exe out manually.  A commenter left a link to a post that included the following instructions:

  1. Download the “Windows Driver Kit (WDK) 7.1.0 from MS, it is an ISO image of several hundreds meg in size.
  2. Using UniversalExtractor (http://legroom.net/software/uniextract) extract the ISO to a temporary folder.
  3. Again using UniversalExtractor, extract the install file "WDK\setuptools_x64fre.msi" to a temporary dir
  4. In that temporary dir you will find "WinDDK\7600.16385.win7_wdk.100208-1538\tools\devcon\amd64\devcon.exe". It may be in a different folder hierarchy, but it should look like.

Along the way UniversalExtractor will prompt you with some warnings, just click OK. With Windows Vista and Windows 7, it will need elevated administrator rights to run.

Exceptions and Threads

Scott Allen has a good post about a difference in how unhandled exceptions are dealt with in .NET 2 from how they were handled in 1.1 In 1.1, if a thread has a unhandled exception, the app would continue to run and there wouldn't be any notice of an error. In .NET 2.0, an unhandled exception in a thread will take out the app, just like if it had occurred in the main thread.

I'm not sure how other people will like that, but that's good news in my book. If an unhandled exception is going to take down an application, then it should happen across the board, not just in the main thread.

One of the projects that I am working on now is a set of services (.NET 1.1) that collect data from 3rd party GPS vendors. They are multi-threaded and I have spent a good deal of time working on the concurrency issues and error handling. If one of the background collection threads goes down, I really want to know about. I have try/catch in all of the places that need it, but if I have missed something, I want it to go down in flames instead of pretending nothing has happened.

Service applications, by their very nature, need to be able to document when an exception occurs. Writing to the Windows event log is pretty much a requirement. When the excrement hits the rotating air displacement device, the event log is your friend. I've been using Log4Net and logging error messages to my email account through it's SmtpAppender.

Log4Net was a pain to getting working, but it's a much simpler mechanism than the Logging block in Enterprise Library. One of the requirements of the service is that it be easy to configure for the end user. I don't want the end user to have run or even know about the "Enterprise Library Configuration console" that the Enterprise Library uses to manage the configuration settings. It's a whole lot of overkill for what I needed.

Monday, December 12, 2005

Saving and restoring a forms location on

Raghavendra Prabhu has the start of some code to save/restore a form’s position.  This requires the Application Settings feature in 2.0, so this is mostly theoretical for me.

 private void Form1_FormClosing(object sender, FormClosingEventArgs e)
     Properties.Settings.Default.MyState = this

if (this.WindowState == FormWindowState.Normal)
   Properties.Settings.Default.MySize = this.Size;
   Properties.Settings.Default.MyLoc = this.Location;
   Properties.Settings.Default.MySize = this.RestoreBounds.Size;
   Properties.Settings.Default.MyLoc = this.RestoreBounds.Location;



private void Form1_Load(object sender, EventArgs e)

this.Size = Properties.Settings.Default.MySize;
this.Location = Properties.Settings.Default.MyLoc;
this.WindowState = Properties.Settings.Default.MyState;


As noted in the comments to his post, this code doesn’t take handle conditions like multiple instances running (each additonal app should offset it’s location) or if the resultion changed and the app is not off the screen.  But it’s a start.
via [jfo's coding]

Multiple remote connections to XP SP2

via [ISerializable - Roy Osherove's Blog]

Friday, December 09, 2005

I love nerd humor

This was from a Saatchi & Saatchi ad campaign. You don't often see CMYK humor.

"This is worse than a Star Trek convention."

That was a comment posted on a Gothamist blog entry about making fake MTA posters. The designer types are arguing over fonts typefaces. It's very much like the Kirk vs Picard arguments found on the Star Trek boards.

Oh, and it would be Kirk.

Set the wayback machine to late 1980's

SteveX posted some tidbits about his work on VirusX, a virus checker for the Amiga. I get Lattice flashbacks whenever he does that.

I learned how to program in C on Lattice. At my first real job, we used the Lattice C compiler for Unix and MS-DOS. I bought the Amiga version and taught myself C with it. Back in the early 80's, Lattice was the only game in town for getting commercial C compilers. Even Microsoft repackaged it as Microsoft C until they came out with their own compiler (MS C 4.0). By the time I was using it (1988), Lattice was being eclipsed by Microsoft's own C compiler and Borland's Turbo C. We eventually dropped it for the Watcom C compiler, a C compiler that ran circles around Microsoft C back then. It's hard to imagine, but Microsoft used to have serious competition in the compiler area. Watcom C was nearly 100% compatible with Microsoft C at the source level, but it would compiler smaller executable that ran faster than the same code compiled with Microsoft C. Mind you, this was back in the early 90's and Visual Studio did not exist. Lattice was eventually bought out by the SAS Institute, who then effectively killed it.

I was surprised to see that Watcom C is still around as Open Watcom C/C++ and FORTRAN. Sybase ended up owning Watcom and realized that maintaining the compilers didn't make a lot of business sense. So they open sourced it about 5 years ago. It looks like you can still build Netware NLM's with it. If you ever needed to write a NLM, this would be the way to do it without having to spend any money.

Cool site for sysadmins

I just came across adminfoo.net, a site with resources for system administrators for Linux, Windows, and Mac.  It’s got a lot of cool stuff.

Tuesday, December 06, 2005

VMware-authd.exe slowing down my PC

I was doing some work on one of my PC's and I had the processes list open in Task Manager. Out of the corner of my eye, I noticed that one process, VMware-authd.exe, was going from 0 to 10% of the CPU. I didn't know what that process did, I went out on a limb and assumed that it was somehow related to VMWare. VMware is one of my favorite tools, but I wasn't running any VMWare sessions. Time to go Googling. Apparently it's a service that provides administrator priviledges to to a running VMWare session if the host use isn't logged in with administrator access rights

If you are logged in with admin rights, you don't need to have this service running. VMware-authd.exe is the name of the executable for the "VMware Authorization Service" service. You can go into Services and shut that service down and then set it's startup type to "manual". There are no other services that depend on that service to be running. You can also stop the service from the Windows command line with the following:

net stop VMAuthdService

[Edited on 3/5/08]

If you need to restart the service from the command line, use the following:

net start VMAuthdService


Today our main app’s help system broke.  I hate that when it happens.  This app is built with Delphi, which supports WinHelp (*.hlp) files for context sensitive help.  A long time ago, I added some code to allow our apps to use HTML Help (*.chm).  It was fairly trivial to implement and once I got it working, we never had to look at that code again.

Until today.  The latest build of the help file didn’t work.  We pressed the help button and nothing happened.  Yet, if we ran the help file outside our app, it loaded up just fine.  Obviously something had changed, the question was what had changed.

The first step was to fire up the app and step through the code.  To use HTML Help with Delphi, I use some open source code that provides a Delphi wrapper for the function calls in hhctrl.ocx.  When I stepped through the code,   I ended up here:

h := HtmlHelp(0, PChar(mHelpFile), HH_HELP_CONTEXT, 5000);  // data = helpcontext id

The mHelpFile variable is the full path the .chm file.  HtmlHelp mapped to HtmlHelpA in hhctrl.ocx.  5000 the context id for the start page in the .chm.  It’s set to 5000 because nothing defaults to that value.  If the context id’s are not defined correctly, it wont have a context ID of 5000.  The code would call HtmlHelp and 0 was being returned.  In this context, 0 means that the context id of 5000 doesn’t exist in the .chm file.  It’s the same thing as calling the HtmlHelp executable, hh.exe, with the -mapid parameter.

hh.exe -mapid 5000 myfile.chm

So that’s my theory, next step is to prove that ID’s are missing or incorrect.  The guy who generated the .chm file was gone for the day and I don’t have to toys used to create the .chm file.  But I did have the .chm file.  Keyworks has a nice (and free) utility called KeyTools for working with HTML Help files.  One of the things it can do is to decompile the .chm file back to the source files.  I did that and opened up the .hhp file and sure enough the context id’s were all wrong.

Delphi Interview Questions

Nick Hodges posted a list of interview questions for Delphi programmers. While I usually like his posts, I didn't agree with this one. I've been using Delphi since version 2 and I would get a brain freeze if I got all of those questions in an interview. I know them all, but to repeat them back in an interview, that's not going to happen. The sole exception would be writing of a function to reverse a string. If I was interviewing someone, I would make them write a function like that. It shows how they think and hopefully what processes they are accustomed to following.

Another thing I do is to describe a wierd bug that would have been submitted that no one could reproduce and ask the interviewee what steps he or she would take. I would describe a real of fictious application (it really doesn't matter) and then describe a loose series of steps that will crash the application, but only on a certain. You can adapt the description to match the perceived skill level of the applicant. This is closer to real life and you can hopefully learn a few things about the applicant. How does he react under stress? How well does he know the debugging tools and methodologies. You'll want to see what steps or directions he would go in order to isolate and reproduce the problem.

I would also ask some generic SQL questions. Every job that I 've had (OK, it's a short list) has involved SQL at some level or another. I don't think you avoid databases and every programmer should have some level of familiarity with SQL.

The rest of the questions in Nick's list show that you have memorized the help system, it doesn't tell you if you actually know to use it. Unless you are writing components, how important is it to enough about how components are read in to repeat it back in an interview. In our shop, we have 7 developers who use Delphi. Only one of us (me) has any real experience in writing a new component from scratch, and doing it the right way. And that's OK. We're not in the component development business, we're in the business of writing applications.

These questions would weed out a skilled programmer who never used Delphi. I would greatly prefer getting an experienced programmer up to speed with Delphi, then dealing a programmer with Delphi experience, but otherwise horrible.

Here are some suggested Delphi interview questions:

  1. Describe how components are loaded from a DFM file at runtime.

  2. What is the difference between TGraphicControl and TWinControl?

  3. Write a function that reverses a string.

  4. If a component has another component as a property (example:  TDatasource has a TDataset component as a property), what happens if the “pointed to“ component is deleted?

  5. Where does TCustomControl fit into the VCL heirarchy?

  6. What is the purpose and significance of the TPersistent class?

  7. What are the three methods required for an implementation of IInterface?  What do they do?

  8. What class in the VCL heirarchy implements IInterface?

from [Nick's Delphi Blog]

Monday, December 05, 2005

Free icon sets from IconBuffet

Thanks to a tip posted on Forevergeek.com, I came across a site that offers free commercial quality icon sets.  IconBuffet.com sells a wide variety of icon sets for app and web work.  What they also offer are free sets.  You register with them and once a month they send you a free set of icons.  To raise it up a notch, they will send different people different sets each month.  You are allowed to send each set up to 5 times to other people through IconBuffet’s web site.  They call it “Free Delivery”.

I just signed up and I have the “Oslo Finance” set.  There are about 10 or 11 different images, in a wide variety of formats: BMP, GIF, Mac ICNS, Win ICO, TIFF, and PNG.

If anyone with an IconBuffet account wants this one, just leave a comment here or email me at anotherlab{at}gmail{dot}com.  I’m looking for the other sets, with my eye on the Shanghai Tech and Shanghai Tech Vector sets.

 [2nd edit]

I just got my first deliveries (thanks Dan!).  It’s the Shanghai Tech Vector and Shanghai Tech sets.  Duncan sent me all 5, I now have a complete set.  I’m not sure what I’m going to do with them, but they are cool.

[Edited on 12/7/05]  I have the following sets left

  • Oslo Atmosphere, 3 deliveries remaining
  • Oslo Finance, 2 deliveries remaining
  • Shanghai Tech, 1 delivery remaining
  • Taipei Buddies 1, 2 deliveries remaining
  • Taipei Buddies 2, 3 deliveries remaining
  • Taipei Night Market, 3 deliveries remaining

Technorati tag:

From the Department of People with way too much time on their hands...

It's just an animated GIF, but it's mesmerizing.

Scott Allen list of ASP 1 to ASP 2 resources

I grabbed this from Scott Allen's blog. I will probably need it sooner than later....

Scott Guthrie: VS2005 Web Project System: What is it and why did we do it? Yes, Microsoft did think about the changes.

MSDN: Step-By-Step Guide to Converting Web Projects from Visual Studio .NET 2002/2003 to Visual Studio 2005. Don’t go in blind, go in with a plan.

MSDN: Common ASP.NET 2.0 Conversion Issues and Solutions. The migration tool is still undergoing some improvements. This document explains some of the pitfalls.

Scott Guthrie: HTML Validation Checking (and how to turn it off). I recommend you turn off HTML Validation checking when migrating a project and concentrate on getting a working application. Once all the migration issues are resolved, turn validation back on.

MSDN: Web Deployment Projects. This is an invaluable tool for moving bits into production. It is still a beta preview. Most of the issues I’ve seen with the tool revolve around merging assemblies.

Rick Strahl: Understanding Page Inheritance in ASP.NET 2.0. Rick provides excellent coverage of the how the new model works, why the new model is an improvement, and what to watch out for.

Scott Allen: Debug & Release Builds in ASP.NET 2.0. This post also covers a lot of the compilation differences.

via [K. Scott Allen's Blog]

Tuesday, November 29, 2005

How to pre-populate assemblies to the Add References dialog in Visual Studio 2005

This one is good to keep track of when working in a team enviroment where everyone uses their own folder structures.

Here are some options I found that worked for me when I tried them on my machine:

  1. Add a new sub-key under HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v2.0.50727\AssemblyFoldersEx (or the same sub-key under HKEY_CURRENT_USER if you want the assemblies to appear only for the current user instead of all users).  The default value of the sub-key should be the folder path that you want Visual Studio to look in for assemblies to include in the Add References dialog.  This registry path is specific to VS 2005 and the .NET Framework 2.0 and will not work for previous versions of VS or the .NET Framework.  It is documented in this MSDN document.

  2. Add a new sub-key under HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\AssemblyFolders (or the same sub-key under HKEY_CURRENT_USER if you want the assemblies to appear only for the current user instead of all users).  The default value of the sub-key should be the folder path that you want Visual Studio to look in for assemblies to include in the Add References dialog.  This registry path is global and any folders listed here will be processed by VS .NET 2002, VS .NET 2003 and VS 2005 as well as the .NET Framework 1.0, 1.1 and 2.0.  It is documented in this KB article.

  3. Place a copy of the file in the folder c:\Program Files\Microsoft Visual Studio 8\Common7\IDE\PublicAssemblies.  This path is dependent on the version of Visual Studio that you have installed and whether or not you installed it to the default path, so you may need to adjust it as needed for your system.  The path that I list is for a default install of VS 2005.


[Aaron Stebner's WebLog]

Monday, November 28, 2005

Installing SQL Server Express

There's a good article on MSDN for controlling the installation of SQL Server Express. If you are bundling Express with your application, you may want to handle the Express options to make it simpler for the user. There some nice code for determining if Express is already installed.


I was reading some of the older postings in James Bach's excellent blog, Training the minds of testers, when I found a little gem called "counterstrings".

A counterstring is a graduated string of arbitrary length. No matter where you are in the string, you always know the character position. This comes in handy when you are pasting huge strings into fields and they get truncated at a certain point. You want to know how many characters that is.

Here is a 35 character counterstring:


Each asterisk in the string occurs at a position specified by the immediately preceding number. Thus, the asterisk following the 29 is the 29th character in that string. So, you can chop the end of the string anywhere, and you know exactly where it was cut. Without having to count, you know that the string "2*4*6*8*11*14*17*2" has exactly 18 characters in it. This saves some effort when you're dealing with a half million characters. I pasted a 4000 character counterstring into the address field of Explorer and it was truncated at "2045*20", meaning that 2047 characters were pasted.

I realize this is may not be a very interesting sort of testing, except perhaps for security purposes or when you're first getting to know the app. But security is an increasingly important issue in our field, and sometimes when no one tells you the limits and dynamics of text fields, this can come in handy.

[James Bach's Blog (Testing)]

This is a really cool and simple way to verify the length of an entry field in an application. He also has a small applet, downloadable from that blog entry, that will let you create counterstrings of various patterns. I may code a clone up in Delphi for my own nefarious purposes.

Friday, November 25, 2005

Fun with the MSDE: installing

Dana Epp has posted a request for information about the MSDE on his blog. He wants to install an app that that requires a named instance of the MSDE and wants to include the smallest footprint of the MSDE installer bits. On machines that already have the MSDE, he wants to install an additional named instance and wanted to avoid including the MSDE bits since it was already installed. With SQL Server named instances, you can't do that. Adding a second instance isn't a reconfiguration of the existing install of SQL Server/MSDE/Express, it's a completely separate install. It's considered to be a separate application by the installer and the OS.

I'm not sure why Microsoft went that way, but it's tied to how the Windows Installer works. A Windows Installer file (.msi) installs just one install of itself. If you try running it again, the installer locates itself on the machine and brings the installer up in maintenance mode. It's not designed to let you install multiple copies of a single application. If you want to do that, you have to go down the multiple instance transform route. A multiple instance transform file (.mst) is basicly the difference between two .msi files. You use the .mst file to change some of the values in a .msi file so that it gets considered to be a different installer by the Windows Installer runtime. By that's a whole 'nother story in and of itself.

Because each instance is essentially a separate installation, you don't want to mess around with the source installer bits. Otherwise, you'll make it difficult to install patches or upgrades. I'm pretty sure that's why Microsoft prefers that you to use their executable to install SQL Server/MSDE/Express. If you use the .msi files, then the patches have be generated against the .msi files that you used. If you merged the SQL Server .msi into your .msi, then upgrades to SQL Server on that machine will required your .msi file. Ouch.

Each instance has to have a .mst file, it's a one to one relationship. I'm not sure what MS is doing under the hood in the SQL Server install process, but my guess is that it's creating .mst files at runtime when you specify an instance name. Otherwise it have to include X number of .mst files in the package, and if they did that some twisted person would try to install X+1 instances and break the installer. Creating a .mst file on the fly is doable, but it's not something I would want to implement. When the user specifies a new instance you need to take your .msi installer file, copy it to a new .msi file. Then you modify that .msi file with the instance name, increment a property, and generate a new product GUID. You then generate the .mst file from the difference between the original .msi file and the new one. After that, you delete the new .msi file, it's no longer needed. Then you call msiexec with the .msi file and the .mst with the appropriate parameters. I'm not sure that you could reliably generate installer patches (.msp files) under that scenario.

I'm not a fan of how Microsoft implemented the multiple instances. When I wrote the server end of e-Link, I used the Windows Installer to install the service. If the user wants to install a second instance of e-Link, they can use an administration utility that I wrote that can register additional instances of the service, but using the same executable. It provides the same functionality to the user, but only requires one set of files. This makes updating the service much easier as the patch only has to target one installed instance.

I can see why MS went along the single instance route with Windows Installer. It prevents the user from accidently installing 8 copies of "Hunt the Wumpus". It makes it easy to allow installers to repair existing installations or modify the original setup. It does makes some tasks extremely difficult for installing. The big thing that I can see what would require multiple installs are web sites. There you could have multiple installations as people usually install a web a couple of times to try different settings, of have "live" and "staging" versions of a site.

If you want to install a web site with Windows Installer multiple times on the same machine, you have a few choices.
  • You could limit the install to a single instance. If the user wants multiple copies of the web site files, they have to do that part manually. We do that with the web gui end of e-Link and we document how to do it. Another way (which I have not tried) would be to rename the web site or virtual directory and it the physical name of the folder that it was installed into. Then run the installer again. It will come up in maintenance mode and you would select repair and it should install another set of files into the previously selected location. The draw to both methods is that the installer will repair or uninstall only the files it knows about. If you add anything manually, then you must remove it manually.

  • You could supply a fixed number of instance transforms. If you do this, you'll need an intelligent front end application to your installer so that you can prompt the user for the instance name. Then you have to check to see if that instance is already installed. If not, then you get the next available instance number and see if you have enough transfoms to use one for this install. Lots of error checking required here, it's not something I would want to do.

  • You could generate instance transforms at run time. Much of the same logic as the previous option, plus the additional work of creating the transform. I definitely don't want to ever have to do this.

This is why you don't see many .msi files for installing web sites.
Trackback to Dana's post

Wednesday, November 23, 2005

RE:How to determine if the current user is an administrator

This is pretty cool. A lot of the stuff that I write is low level admin type of utilities. As my coding meter moves further away from the Win32 Delphi to C#, I'll need stuff like this more often.

Following, is the method that I use to determine if a user is an Administrator. Note that in .NET 1.0/1.1 the using construct wrapped around the creation of the WindowsIdentity won't compile as its implementation of IDisposable is new for .NET 2.0. Previously you had to rely on the finalizer of the object to run so that the handle of the user token could be freed.

        using System;
        using System.Security.Principal;
        using System.Windows.Forms;

        public static bool IsAdministrator
                if (SystemInformation.Secure)
                    using (WindowsIdentity identity = WindowsIdentity.GetCurrent())
                        WindowsPrincipal wp = new WindowsPrincipal(identity);

                        return wp.IsInRole(WindowsBuiltInRole.Administrator);

                return false;

There is also a check to determine if the operating system is secure (ie Windows NT platform) - the documentation states that the IsInRole method returns no results on Windows 98 and Windows Millennium Edition. I'm not entirely sure how a method that returns a boolean value can return no results, so it is wrapped in the Secure check just in case an exception is thrown when using it on Windows 9x/ME.

from [Managed from down under]

Monday, November 21, 2005

Why you wont find C# example code for writing Shell Extension handlers

Jesse Kaplan posted the following (thanks to Junfeng Zhang)

Writing in-process \shell extensions in managed code is actually a very dangerous thing to do because it has the effect of injecting your managed code (and the .NET Framework) into every application on the machine that has a file open dialog.

The problems occur because only one version of the .NET Framework can be loaded in a process at any given time (other shared components such as java and msxml have the same property and thus the same restriction).

If you write your shell extension using the 2.0 .NET Framework and an application built with the 1.1 .NET Framework uses a file open dialog, your shell extension will fail because it can not run on an earlier version. Things can get even worse if your shell-extension manages to get loaded in a process before another applications managed code does: your extension may force an existing application onto a different runtime version than the one it was expecting and cause it to fail.

Because of these problems we strongly recomend against using any single-instance-per-process runtime or library (such as the .NET Framework, java, or msxml) in an in-process shell extension.

Interesting scientific study about font usage on web pages.

Jeff Atwood posted a cool article from Wichita State about font legibility. Serif mono-spaced fonts were the worst (sorry Courier) and Tahoma did the best.

The study is worth reading, the testing methodology was objective and at pretty much validates what fonts you think should be used for a given type of web site. The other good tip in Jeff's post was that Software Usability Research Laboratory (SURL) at Wichita State has an excellent newsletter that documents their usability studies.

Client vs Developer

Client vs Developer wars.
This is stuff isn't directly applicable to our development patterns, but it has some useful information.
"Grayscreen" prototyping (building a simple HTML model of a website) provides an extremely effective way of communicating a website's content, structure, and functionality before design and programming begin. Prototyping overcomes many other difficulties commonly associated with web development, such as managing expectations, communicating effectively, working through the design process, and creating and delivering content.
It's another example of how design up front methods save time and money.

Good article plus a free book in PDF format.

Thursday, November 17, 2005

Grimmy weighs in on blogs

It's subtle, but I like it. If I was ever to write a blog posting tool, the icon for posting the entry would look like the first panel in that strip. If you like that strip, you can access at the archives at Grimmy.com.

Wednesday, November 16, 2005

That pesky SQL Server Express. I'm going to have to support it, it's time to start collecting tips from the veterans....

These problems left me stranded for days, then today, on another machine, I hit a different set of problems I kept getting the following "Failed to generate user instance of SQL Server due to a failure in starting the process for the user instance. The connection will be closed." and if I set "User Instance" to false the following "An attempt to attach an auto-named database for file C:\[app_path]\ASPNetDB.mdf failed. A database with the same name exists, or specified file cannot be opened, or it is located on UNC share."


If you don't want to follow the link, the short answer is that SQLExpress creates a directory per user in "c:\Documents and Settings\[user]\Local Settings\Application Data\Microsoft\Microsoft SQL Server Data\SQLEXPRESS" that it uses to store information. Deleting this directory has fixed both of my problems.

[from Enjoy Every Sandwich]

New tool bar icons for VS 2005

I'm putting this here to I'll remember where the bits are

A customer from Las Vegas DevConnections asks:

It seems like, but I may be mistaken, that you said something about posting some new set of toolbar icons on your blog? Was I in a Vegas-induced stupor or did you really say that?

Yes, I really, really did - however I totally forgot to link to it.  Aaron talks about the library here.  ...and Soma talks about how the new image library came to be

Instructions for finding the image library can be found here:

To install the Visual Studio 2005 Image Library
Locate the file VS2005ImageLibrary.zip. This file is normally installed in \...\Program Files\Microsoft Visual Studio 8\Common7\VS2005ImageLibrary\.

  1. Right-click VS2005ImageLibrary.zip and click Extract All.

  2. The Extraction Wizard appears.

  3. Follow the directions in the wizard to extract the images.

It looks like, this is something you'll need the full Visual Studio install for - the zip file does not install with the Express editions of Visual Studio.


[via jfo's coding]

Tuesday, November 15, 2005

File this one under "Huh?"

Rick Moranis has a Country Album. I'm having trouble picturing The Keymaster singing honky tonk, but that's just me.

Building ASP.NET 2 projects

On K. Scott Allen's blog, you can find a really good description of how the build process for ASP.NET projects has changed from 1.0/1.1 to 2.0.

One of the adjustments to make when moving from ASP.NET 1.1 to 2.0 is how to produce debug and release builds.


Here is the most important concept to come to terms with in 2.0: Visual Studio 2005 knows nothing about compiling a web application. In 1.1 VS built the code-behind and ASP.NET built the web forms. In 2.0 Visual Studio 2005 delegates all compilation responsibilities to the ASP.NET platform.


Jump here for the full article, it neatly describes what has changed and how it works. He doesn't go into why it changed, that's the part I don't get. What's the advantage of the new build method? In the end, as long as I can get FinalBuilder to build it, I'll be happy.

Monday, November 14, 2005

Test drive of writely.com

This message was entered with writely.com, a web based document collaboration tool. I usually enter my blog entries with w.bloggar, but I'm game to try something new. It doen't work with Opera 8.5, I'm using IE 6 right now. As a rule, I only use IE when I have to do, and that's enough to limit my usage of writely. It does work, it's just a little bit sluggish.

A suggestion for "Just Think of Canada as 11 More States"

Steve's has a bone to pick with us.

I’m a loyal Canadian. I enjoy Tim Hortons, and don’t mind the Canadian Tire guy. But as Canadians, I think we need to get the message across to Americans that we’re not all that much different from them, and not that far away.

Why do I say this? Because one too many times I’ve been shopping online, found the exact product I want, and then find the dreaded statement:

Sorry, we are able to ship (and mail printed catalogs) only to the US, its territories and possessions, and APO or FPO addresses.

Why? Why why why?

What you need to do is convince FedEx and/or UPS to offer virtual mail addresses. Packages sent to a virtual address would automaticly get forwarded to a real Canadian address, with the recipient paying the additional fees. It's mailbox forwarding, except with non virtual bits. It's a win-win situation for everyone. Steve gets his reasonably priced borosilicate lab glassware, the vendor makes a new sale, and the delivery company makes a few dollars (or loonies).
Allen Bauer has a cool post on reporting bugs and the common sense etiquette that should be used.

I hope folks understand that by following a few simple rules and creating a defect report that you would like to get is actually you contributing to your own success.  In this one case I have to say that karma is the best way to describe this process.  But paying it forward and actually becoming a part of the solution, it will all eventually come back to you.  Even though you may think your contribution is tiny and insignificant, the fact of the matter is that your contribution when compounded with everyone else's can pay back in large dividends.

Having been on both ends of the defect report, I completely concur with Allen. A long time ago (and in a galaxy far away), I was moonlighted as the tech support "department" for a well known reporting package that used to be installed with Delphi. On average, I would get between 30 to 60 emails a day from other developers who bought this package. It never failed to amaze me how hard it would be to get people to send specific information to duplicate a badly worded or vague bug description. Mind you, this reporting package had plenty of issues to deal with, but many times I couldn't duplicate the bug that was reported by the description that was included. I would usually send a followup email asking for the steps required to duplicate the bug.

I tried to avoid getting sent entire projects. This was 1997-2000, and I was doing support from a dialup account, it woul take forever to download everyone's projects as they usually sent me everything, binary files included. Sometimes, I needed the full project to duplicate the problem. That part was always interesting, you learn that the users will use the code in ways that you did not expect. There were always a few people who would refuse to provide detailed information and I would get a ranting email about not wanting to peform QA work for free. I actually received an invoice from one guy for the "services" that he had provided in tracking down the problem. [more about that when I finally decide to blog about that job].

On the other end of the spectrum, I spent a considerable amount of time documenting flaws in Sybase's ADO provider for Adaptive Server Anywhere. In the beginning, they wouldn't take my bug reports seriously. They would tell me that it was a Delphi ADO issue and not a problem with their provider. The problems were not with Delphi or it's ADO components, but they couldn't duplicate the bugs from my descriptions and they were not inclined to look at Delphi source code. I ended up coding detailed examples as VBScript files. One of the nice things about ADO was that it behaved the same way no matter who it called it. With those examples, I was able to get Sybase to spend time tracking down the problems that I was having. They were never able to fix those problems, but I did appreciate their efforts. What came out of those examples was that I was using Sybase's ADO provider in a different way than they were testing and apparently, their testing did not include all of the features supported by the provider.

Friday, November 11, 2005

RE: A better BackgroundWorker : CancelImmediately and other goodies

Hmm, I can use this for a service testing application that I'm working on...

One of the nice new features you get in .NET 2.0 Winforms is the new BackgroundWorker component. It allows safely executing long tasks in a different thread than the GUI, while allowing an easy event-driven interface to perform the task and respond to events (such as detecting work progress). There are even versions of this for .NET 1.1 courtesy of Juval Lowy.
One of the things it does not support is the ability to Cancel the running task immediately rather than waiting for the code to process the Cancel Request (which is vital if your "DoWork" code contains tasks that individually take a long time to process). With some Reflectoring, I was able to overcome this obstacle and provide a solution for this problem.
For the full details and download in VB.NET and C#, read the full article:
[ISerializable - Roy Osherove's Blog]

[Update] There's a good article by Juval Löwy, titled Asynchronous Windows Forms Programming that covers this in great detail

Another way of deleting data in chunks

I'm bloggin this because I'll need it in a few weeks....

Michael Campbell has blogged about removing data from a table in chunks http://sqladvice.com/blogs/repeatableread/archive/2005/09/20/12795.aspx. This can be simplified even further in SQL Server 2005

DELETE TOP (2000) FROM MyBigTableWHERE someCondition = true  ORDER BY Dateolumn ASC


  [ via WebLogs @ SqlJunkies.com]

Thursday, November 10, 2005

Who was Microsoft kidding when they promised to end "DLL Hell"? The long dark night of the SQL Server 2005/Visual Studio .NET 2005 beta produced a series of seeming incompatible .NET frameworks. I didn't do much beta testing with the 2005 bits, but when I did, I did so from the safe confines of various VMWare sessions. I'm now looking at some automated build tools and one of our developers suggested MSBuild. That's the last thing you would want, a build tool that will be dependant having the appropriate runtime installed. Plus I want something that supports more than .NET compilers, we are still building Delphi Win32 apps here as well as .NET assemblies.

On a slightly separate target, why RSS Bandit is such a resource hog? I loved the interface, but it would bring the performace of my PC to a flying stop. I just started using Omea Reader, and it plays well with others much better than RSS Bandit did.

....Microsoft promosed that DLL Hell would go away, but with the .NET Framework betas, they dropped us into the biggest DLL Hell I’ve ever seen. I can’t uninstall MSH from my system because I installed the .NET Framework 2.0, which required that I uninstall the beta versions. The MSH uninstaller requires the beta framework, which I uninstalled, so I’m stuck. I can’t install the release version of MSH. This sort of thing is just silly, and I thought it was a problem that we’d solved. (To be fair, they did promise that this won’t be a problem for release versions of the framework, but how many millions of times were the betas downloaded?)

from Stevex's blog

Wednesday, November 09, 2005

See What Services Are Associated with a Process?

There's a cool tip on the tech-recipes site to show how to see what services are being run under each instance of svchost.exe. From a command line run the following:

tasklist /svc /fi "imagename eq svchost.exe"

That will list each instance of svchost.exe with all of the services being run by that instance.

Bender, Smender. I want Robbie!

Forbidden Planet has always been one of my favorite movies. As a kid, I always wanted my very own "Robbie the Robot". If I start playing the lottery, I can now order one from the Hammacher Schlemmer catalog for the mere sum of $49,999.95.

Robbie was a cool robot. None of this wimpy C-3PO nonsense. Robbie embodied the cutting edge of 1950's computer technology. Vacuum tubes glowing, relays clacking, and don't forget little metal spinning things on the side of his head. That's a man's robot.

I know a few people who were deeply affected by that movie. There used to be an audio store just outside of Albany, NY, named "Altair Audio". It was named after the planet Altair IV. It was actually a decent place, they carried the high end stuff and knew how to sell it. And of course, they carried the Krell line of amplifiers.

And the movie had Leslie Neilsen back when he was known as a dramatic actor. It's hard to watch him in serious roles after seeing Airplane and the Naked Gun shows/movies. I actually Leslie Neilsen once. About 15 years agao, I went to Irvine CA to visit my brother. On the way back, I flew out of John Wayne (aka Santa Ana) airport. While I was waiting for my fliight, I saw a production crew fiming a commercial. The commercial featured Leslie Neilsen. He had a break in the filming and I walked up to him and introduced my self. He was very gracious and we chatted for a minute or two. I was probably stammering like an idiot. I was too nervous to get a picture of the two of us. I do have a blurry picture of the back of his head.

Then a couple of older women came up. They were huge fans of his dramatic roles and they just kept talking and talking. They would ask him a question and then talk about something else before he could answer. And that's when the fun began. Mr. Neilsen had a llittle device in his suit jacket pocket that made fart sounds. He would stand there and smile at the women or make small talk, and at the same time, he was pressing the button on the fart sound device. The women didn't know how to react. They were trying to get their cues from Leslie, but he played it straight. I wanted to laugh so hard, I was dying. If he was goiing to play it straight, I was going to do so. I wanted to see how far he could take this. After a few minutes, I had to leave to catch my flight. I never knew how far he was able to play the gag, but I still laugh to myself just picturing it in my head.

Monday, November 07, 2005

More news on Sony's rootkit

The story of Sony's rootkit continues to live on. After Mark Russinovich first documented his analysis of the rootkit installed by content protected Sony audio CD's, just about everyone and their grandmother linked to Mark's site. Oddly enough, CNN didn't. That's another story. Mark has provided updates to the rootkit story and it continues here.

The latest addition to the story is still worth reading. The company that wrote the rootkit, First 4 Internet, responded to Mark in a comment on his blog. They address his concerns item by item, and of course, obsfuscate the issues. Mark's latest blog entry goes over First 4 Internet's comments, blowing huge gaping holes on each of their points. When this finally blows over, the Sony/First 4 Internet saga will be a text example of how NOT to address a growing PR disaster.

Thursday, November 03, 2005

The arrival of Delphi Man and Doctor Deadline

After coming back to Cubeland from lunch, I saw a small package on my chair. It had airmail stamps and came from Middlesex, England. I had no idea what it was, so I ripped it open to find Boland's inflatable action figures. The images are courtesy of the crapmatic instant picture device. The top one is Delphi Man, lord of the cubicle. The lower picture is of Doctor Deadline, trusty companion of Delphi Man.

There are limited edition items, Borland only made 1000 of each one. So far they haven't turned up on eBay. Oddly enough, the website that advertised the super duo, www.delphisuperhero.com has been replaced with the Delphi 2006 web site. In addtion to registering to win the inflatable characters, there were PDF files that you could download and print your own.

Wednesday, November 02, 2005

China's Little Green Book

Thomas Friedman had an interesting column today. It's titled "China'a Little Green Book" and he talks about how the growing conservation movement in China. China is poluted to a scale beyond anything we ever saw here. When we were over there in the summer of 2003, I was astounded by amount of smog in the air. It's good to see that they are going to doing something about it.

Tuesday, November 01, 2005

Sony now installs a flawed rootkit

This is lovely. Sony is now putting a rootkit installer on their Music CD's. Mark Russinovich discovered a root kit on his machine while testing a rootkit detection tool (RootKitRevealer   ) that is was working on. He documented the process on his blog and it's required reading. He cleary documents what he found, how badly written it was, and what he had to go through to remove. The rootkit installed by Sony is a Digital Right Management service, but is so badly written it will have all sorts of nasty side affects. This thing will really mess up your computer. If you don't remove it correctly, you will lose access to the CD/DVD drive in your PC.

Debugging services

Simon Carter has a tip on debugging services. It boils down to calling the Windows Sleep API in your service constructor code. This gives your debugger enough time to attach the your process in time to step through the service start up code. Usually when you attach to a running process, it has already gone through it's normal initialization code ("We now join this program already in progress"). If you are trying to diagnose a problem in the startup code, it's already too late by the time you can attach to it. That is the joy that we call Windows Service programming.

I prefer to take a different tack for debugging a service. I separate the code of what the service is supposed to do from the actual service code. I'll build a Windows App (or Winforms app) that calls the same code that the service would call. It's much easier to debug the code from an application instead of a service. 99.9% of the time, the problem is not part of the service controller code, it's the in the code that service uses. The other 0.01% of the time where the problem is in the service creation code, I just add a lines to send data to the Windows event log. This technique works well for Win32 Delphi and .NET programming.

Thursday, October 27, 2005

Voices of reason in a sea of hype

I am so tired of the term "Web 2.0". When ever I see that that term bandied about, I get a mental flashback to an old Verizon commercial where a consultant is pronouncing the word paradigm as "Pair-Uh-Dig-Um". It's another example of "buzzword bingo". What does it mean? And I do mean that specificly.

You get the impression that there is a line drawn somewhere, that separates "Web 1.0" from "Web 2.0". As near as I can tell, the definition du jour of "Web 2.0" is that it's interactive web services with dynamic content and social participation. That right there is vague enough to mean anything and nothing. Now I'm starting to blog postings that describe "Web 2.0" as a metaphysical process. This isn't Aug. 16, 1987, people. Let's just look at the web for what it is, a means of communication, and leave the mumbo-jumbo stuff out of it.

Nicholas Carr has a great article, "The amorality of Web 2.0", that pretty much nails how I feel about this thing. Joel Spolsky (required reading for anyone in software development) has a very good rant "Architecture Astronauts Are Back", with a followup with the links to see what made him crazy (but crazy in a good way).

Wednesday, October 26, 2005

RE: Yet another command line parsing system

This looks like a logical way to handle command line parameters while still following convention of using an app.config file.

....I used another arguments parser from Code Project, "C#/.NET Command Line Arguments Parser".
I like it because it works like the ASP.NET querystring parser - it handles the parsing (quoted strings, different delimiter styles) and exposes a string dictionary with the results.

I use a GetSettings accessor that reads the default from the app.config file, but allows overrides via command line. I like this approach because settings are their standard location (app.config), and any config setting can be overriden via command line without an attribute change and a recompile.

private static int Main(string[] args)
    Processor processor1 = 
new Processor(args);
return processor1.Process();

private Arguments arguments;

public Processor(string[] args)
this.arguments = new Arguments(args);

public Process()

private string GetSetting(string key)
string setting = string.Empty;
if (this.arguments[key] != null)
        setting = 
        setting = ConfigurationSettings.AppSettings.Get(key);
if (setting == null)
return string.Empty;
return setting;

[via [JonGalloway.ToString()]]

RE: //TODONT: Use a Windows Service just to run a scheduled process

I made this mistake once. But I feel much better now thank you.

A Windows Service is the wrong solution to scheduling one-off custom processes. The right solution for scheduling simple processes is the Windows Task Scheduler.

Read the whole posting here

[From [JonGalloway.ToString()]]

Fun with BCP

Here's a quick and dirty way to export a table to a text file with SQL Server. With some minor tweaking, it should also work for views and stored procedures that return result sets.

Here is a simple method of exporting all the data from SQL Server table to a Text File

CREATE Procedure BCP_Text_File

@table varchar(100), 
@FileName varchar(100) 

If exists(Select * from information_Schema.tables where table_name=@table)
        Declare @str varchar(1000) 
        set @str='Exec Master..xp_Cmdshell ''bcp "Select * from '+db_name()+'..'+@table+'" queryout "'+@FileName+'" -c''' 
    Select 'The table '+@table+' does not exist in the database'

Execute this procedure by giving Table Name and the File Name

EXEC BCP_Text_File 'Employee','C:\emp.txt'

Now all the data from Employee table will be exported to the text file which will be located at C:\emp.txt

[from WebLogs @ SqlJunkies.com]

Tuesday, October 25, 2005

Whither DAAB?

If you were looking for a reason to dump DAAB, it looks like the good parts have already been folded into ADO.NET 2.0.
The ADO.NET data providers in .NET 2.0 provide factory and common ADO.NET classes that make it easy to keep your code independent from a particular ADO.NET data provider or database product.
[Simple Talk]

How much is your blog worth?

In my case diddly squat....

A blast from the past

Back in the Amiga days, SteveX was a name every programmer knew from his VirusX, ScreenX, PointerX applications. These days, he's in the .NET world and has a cool link for string formatting in C#.

Quick lesson on how to strip text out using RexEx

There's just something about RegEx that makes my ears bleed. Fortunately other people get it. Here's an example of how to filter text out of an expression, courtesy of Jeff Atwood's Coding Horror....

For example, if the word fox was what I wanted to exclude, and the searched text was:

The quick brown fox jumped over the lazy dog.

... and I used a regular expression of [^"fox"] (which I know is incorrect) (why this doesn't work I don't understand; it would make life SO much easier), then the returned search results would be:

The quick brown jumped over the lazy dog.

Regular expressions are great at matching. It's easy to formulate a regex using what you want to match. Stating a regex in terms of what you don't want to match is a bit harder.

One easy way to exclude text from a match is negative lookbehind:


But not all regex flavors support negative lookbehind. And those that do typically have severe restrictions on the lookbehind, eg, it must be a simple fixed-length expression. To avoid incompatibility, we can restate our solution using negative lookahead:


You can test this regex in the cool online JavaScript Regex evaluator. Unfortunately, JavaScript doesn't support negative lookbehind, so if you want to test that one, I recommend RegexBuddy. It's not free, but it's the best regex tool out there by far-- and it keeps getting better with every incremental release.

Monday, October 24, 2005

New device detected: Boeing 747

I would have loved to have seen that ono pop up on the scrren.

Back in 1994, Boeing considered equipping each seat with a serial modem.
Laptop users could hook up to the modem and dial out. (Dial-up was the primary means of connecting to the Internet back in those days.)

We chuckled at the though of attaching the serial cable and getting a Plug-and-Play pop-up message:

New device detected: Boeing 747

[via The Old New Thing]

Deleting lots of data in batches

The fun part is in the "where..." bit, knowing how to set your query to only get a portion of the data is heavy lifting here.
I know where I'm going to be using this in some soon to be written code. For the code, the data will timestamped, I can safely iterate by day and nuke all of the records for each day.

So we've all come across the need to delete 10 million records. however we all no that this won't be quick and will result in a large log file and as we get nearer deleting the 10 millionth row the process is going very slowly.

Well the standard way around this is to run the command in batches, this way our transaction is never very big. So you can write a while loop and check an iterator, but first you need to get into the loop so you need to store the iteration in a variable and have something like this

set rowcount 10000
declare @rc int
set @rc =0
while @rc < 1000 
  --Do my update/delete etc 
  delete from mytable where ....
 @rc = @rc+1

Well in SQL 2005 in SQLCMD mode and the new TOP clause in an update/delete you can do the following

--your update statement
delete top (10000) from mytable where ....
:go 1000

which of these looks easier to you. I vote for number 2.

[via WebLogs @ SqlJunkies.com]

Regular Expression Tools

I'm still at the point where I can use stuff like ^\d{3}[-| ]?\d{2}[-| ]?\d{4}$ and not fully understand the pieces. So i'm always looking for decent RegEx tools. Eric Gunnerson had a good post about suing RegEx to validate a SSN

But first, a word about tools. It's a lot easier to use a tool to do this sort of thing than it is to write code to do it. So, I suggest one of the following

RE: Another Blast of Cold Water in the face - "The Build Master" by Vincent Maraia

Bill lists a couple of good references for doing the build the right way. I want these two books.

Eric Garulay, one of the uber cool folks over at Addison-Wesley shot me a copy of The Build Master Microsoft's Software Configuration Management Best Practices by Vincent Maraia ( Build Master Web Site ) . Well, looks like Kim is going to appropriate the book from me so I need to hurry up and get it read, fortunately that's not a problem because it's pretty amazing.  Let me step back a second.  A while ago, my buddies at http://www.apress.com sent me a book titled Expert .NET Delivery using NAnt and CruiseControl .NET  and it was a real eye opener.  Until then, my build strategy was about as sophisticated as “Get Latest Version” from Visual Source Safe, flipping the Release bit and compiling. 

For rest of the posting, go to [Bill's House O Insomnia]