A more robust way of converting a string to an enumerated value (enum)

A while back, I had blogged about a tip that Mark Wagner had posted about converting a string to an enumerated value.  Tim Sneath posted a similar tip even earlier, except his had some additional error logging.  Tim’s post made it to DotNetKicks, which is good because having the additional error handling is just good coding practice. 

enum Sushi
{
Ika,
Hirameh,
Tako
}

// ...
Sushi lunch = (Sushi) Enum.Parse(typeof(Colour), "Tako", true);
Console.WriteLine("Sushi Value: {0}", lunch.ToString());

// To avoid an ArgumentException for strings that do have
// corresponding enumerate values, call Enum.IsDefined()
// first.

string NotSushi = "pizza";

if (Enum.IsDefined(typeof(Sushi), NotSushi))
{
lunch = (Sushi) Enum.Parse(typeof(Sushi), NotSushi, true);
}
else
{
// Add your error logic here
}

Mucho gracias to Tim & Mark…

Troubleshooting SQL Server connectivity issues

Xinwei Hong (MSFT) wrote a great troubleshooting guide on how to identify and resolve SQL Server connectivity issues on the SQL Protocols blog.

Xinwei broke it down to 6 possible causes:

  1. Network issue.
  2. SQL Server configuration issue.
  3. Firewall issue.
  4. Client driver issue.
  5. Application configuration issue.
  6. Authentication and logon issue.

For each cause. Xinwei lists some background on why that cause could a problem along with specific commands to run to help diagnose the problem.  For example, to determine if #2, SQL Server configuration issue, is the root cause of the problem; the following steps are listed:

You need to make sure the target SQL Server is running and is listening on appropriate protocols. You can use SQL Server Configuration Manager (SCM) to enable protocols on the server machine. SQL Server supports Shared Memory, Named Pipes, and TCP protocols (and VIA which needs special hardware and is rarely used). For remote connection, NP and/or TCP protocols must be enabled. Once you enabled protocols in SCM, please make sure restart the SQL Server.

 

You can open errorlog file to see if the server is successfully listening on any of the protocol. The location of errorlog file is usually under:

%ProgramFile%Microsoft SQL Server/MSSQLxx.xxx/MSSQL/Log

If the target SQL instance is a named instance, you also need to make sure SQL Browser is running on the target machine. If you are not able to access the remote SQL Server, please ask your admin to make sure all these happen.

 

This guide is definitely worth keeping bookmarked.  When a client calls and they can’t connect to their database, having a list like the one Xinwei provide should make it easy to resolve the problem.  Or at the very least, rule out the usual suspects.

I just installed the PowerCommands for Visual Studio 2008

I just installed the PowerCommands 1.1 for Visual Studio 2008.  This is a set of extensions to the VS 2008 IDE that provide some additional functionality.  The available commands are listed here.  The Collapse Projects command sounds pretty basic, but it’s something I’ve always wanted and it’s great for large solutions. 

The best part of PowerCommands?  You get the source code, which would be handy if you ever want to write your own VS extension.

My "Windows Feedback" copy of Office 2007 Ultimate just came in

I just received a NFR copy of Microsoft Office 2007 Ultimate in the mail.  Last December, I signed up for the 2008 Microsoft Windows Feedback Program Sweepstakes.  This was a three month program run out of the Windows Feedback Program.  As part of the program, I installed some software on one of my home PC’s that recorded some basic metrics such as Windows settings, hardware details, how the common document folders are being used, changes to the system, and problems that may occur.

This information was sent back to Microsoft to provide information on how our PC was being used.  In return for allowing MS to collect this data for 3 months, I was given a choice of several different products from Microsoft (Vista Ultimate, Office Ultimate, Money Plus Premium, Encarta Premium, or Streets and Trips).  I opted for Office 2007 Ultimate.  I didn’t need another copy of Office right now, but it would handy the next time I get a new machine.   Apparently the response to this offer was so huge that Microsoft closed the program to new entrants after only a day or so.

In addition to the monitoring software, I was required to answer at least one survey during that time period.  Oddly enough, I was only prompted once during the 3 month period to answer a survey.  At this point, I’m no longer obligated to run the monitoring software and I haven’t decided whether or not to uninstall it.  I’m not a big fan of monitoring software, but I’m not seeing any performance impact and I’m satisfied with the privacy issues with the data being sent back.  I know some people roaming the series of tubes were calling this spyware, but technically the WFP software isn’t spyware.  Most definitions of spware define it as software that collects data or controls a computer surreptitiously and was installed without informed concept.  I knew what it was doing and I opted in, which means it’s not spyware.  At most, Microsoft now knows how much time my kids spend at Webkinz World.

It would be nice to see what data was being sent back to the mothership, but if MS is following their own Terms of Use for this program, my privacy concerns have been satisfied.  This is in strong contrast to a program launched by Sears Holding Corp (SHC). at roughly the same time, where they wanted to install some software that would be a lot closer to the definition of spyware.  The software that Sears wanted to install was a web proxy from ComScore (never identified as such by Sears) that would track all of your web usage and sent that data to Sears.

The software used by SHC is a web proxy program supplied by Comscore.  It redirects all of your web browser activity through the Comscore software and that data can be sent to Sears.  SHC notifies the user that the user is about to install some software, but it does not go into full detail about what data is being collected and what is being sent to Sears.  At no point during the installation process or preliminary email is the software identified or it’s functionality  described.  A person with computer security experience would realize what is going on, but the average computer user would have no idea what they just installed.

With the security breaches on Sears web site earlier this year, I would be very hesitant with letting Sears have access to my personal information.  I understand why Sears would want to know what I shop for online, and I don’t mind sharing that information.   Sears has no business knowing how I pay for those items and has no business viewing my email.  Comscore’s tracking software would monitor all of that.  All privacy issues aside, that’s a horribly inefficient means of tracking online shopping.

It also looks a little funny that the guy in charge of this program, Rob Harles, was a former senior vice president at Comscore.  Comscore is the vendor for the tracking software that the SHC wants to install. Ben Edelman, assistant professor at the Harvard Business School who focuses on spyware practices, did a great write up about the SHC sofware.  He documented in clear detail (with screenshots and video) that the installation steps violate FTC guidelines.  If you Google for Sears & spyware, you’ll get close to a quarter of million hits.  That’s not what you call good publicity, but I digress.  When I participate any sort of consumer feedback program, I take a close look at what would be installed and what will be collected.  I also check to make sure that the company collecting the data is collecting the right data and will respect my privacy.  Microsoft met those concerns.

How to identify who has a terminal session and how to kill it

Having the ability to use a terminal service (aka Remote Desktop) session to manage a Windows Server (2000, 2003, and 2008) is very useful.  If you don’t have a Terminal Services license installed, you are limited to to two active sessions (plus a bonus connection that I’ll get to in a minute).  If a person disconnects from a session without logging out, it can leave that session running.  That allows you to start a long running task and come back to it later, but it does use up one of the available connections.  If both sessions are being used, you will not be able to create a new terminal service connection to the server.  At this point, you have three options:

Yell down the hallway and ask “Who has a connection to server XYZ”.  This never works because either the person who left the connect forgot about it or didn’t realize that he (or she) was supposed to logout.  The other problem is that you could be working from home and the only thing that the yelling accomplishes will be to attract your dog and your child, both of which will be looking for cookies.

Use the command line tools to identify the open sessions and kill one of them.  There are two tools, qwinsta and rwinsta.  If you run “qwinsta /?” from a command shell, you will get the following:

qwinsta /?
Display information about Terminal Sessions.
QUERY SESSION [sessionname | username | sessionid]
              [/SERVER:servername] [/MODE] [/FLOW] [/CONNECT] [/COUNTER]
  sessionname         Identifies the session named sessionname.
  username            Identifies the session with user username.
  sessionid           Identifies the session with ID sessionid.
  /SERVER:servername  The server to be queried (default is current).
  /MODE               Display current line settings.
  /FLOW               Display current flow control settings.
  /CONNECT            Display current connect settings.
  /COUNTER            Display current Terminal Services counters information.

                                

If you run “rwinsta /?”, you get the following:

rwinsta /?
Reset the session subsytem hardware and software to known initial values.

RESET SESSION {sessionname | sessionid} [/SERVER:servername] [/V]

  sessionname         Identifies the session with name sessionname.
  sessionid           Identifies the session with ID sessionid.
  /SERVER:servername  The server containing the session (default is current).
  /V                  Display additional information.

For the sample server XYZ, you would run “qwinsta /server:xyz”  That will return something like:

 SESSIONNAME       USERNAME                 ID  STATE   TYPE        DEVICE
console                                     0  Conn    wdcon
rdp-tcp                                 65536  Listen  rdpwd
                   gatesb                    1  Disc    rdpwd
rdp-tcp#93        jobss                    3  Active  rdpwd

From that output, we can take one of the IDs that was returned for the remote sessions and use rwinsta to kill that session.  You would use something like:

rwinsta 1 /SERVER:xyz

And that will terminate that session, allowing you to open a new session.  You will need admin rights to run that command, but if you are using the admin terminal service connections to the server, then you would already have the necessary access rights to the server.

There is a third option, you can connect to the console session.  This is the bonus option that I had referred to earlier.  This is the session that you would get if you were physically in front of the server and were logging in on the server’s mouse and keyboard.  You can specify the console session as a command line parameter to the remote desktop client, mstsc.exe.  The following syntax can be used to connect to the console session of a server:

mstsc /console

That feature will work with Server 2003 and later.  On some machines, qwinsta and rwinsta may have been renamed to query.exe and reset.exe, respectively.

[Updated at 2:42 pm]
Steve listed an alternative to qwinsta and rwinsta on his blog.  He uses quser.exe and logoff.exe, which provide pretty much the same functionality.  On my machine, quser.exe was buried in c:\windows\system32\dllcache, which was odd.  I wonder why it wasn’t in system32?  quser has an advantage over qwinsta, it lists the logon time and idle time for each session.  That gives you a little more data when you have to kill someone session and you can’t determine which one must die.

System Restore and Vista

After reading the comments posted to my blog entries for USB issues caused by KB938371, I can’t over emphasis how valuable it is to have System Restore enabled.  While trying to find a work around for the mouse problems that I reported here, here, here, and starting at here; I noted that a few of the people who had posted responses or had sent private email did not have System Restore available.

I was surprised by that as System Restore is enabled in all SKU’s of Vista by default and it’s greatly improved over the System Restore feature in XP.  If you are not familiar with System Restore, I’m going to borrow the following from the Wikipedia entry

it’s a feature that periodically takes a snaphot of the current state of the operating system, typically referred to as a restore point.  Windows uses Shadow Copy (aka Volume Snapshot Service or Previous version) to create a file that contains system files, registry settings, drivers, installed programs and stores the data in a single compressed file.  User settings and files are typically not covered.

This restore point will be generated under the following conditions:

  • when a piece of software is installed
  • when Windows Update installs new updates to Windows
  • when the user installs a driver that is not digitally signed by Windows Hardware Quality Labs
  • every 24 hours of computer use , or every 24 hours of calendar time, whichever happens first
  • when the operating system starts after being off for more than 24 hours
  • when the user requests it.

When Windows Update pushed KB983371 down to my machine, System Restore created a restore point of the current state of the OS just prior to the installation.  This allowed me to easily roll back the installation of the update.  Since 938371 does not allow itself to be uninstalled, roll back the system via System Update was the only documented way of removing 938371, short of reinstalling Vista.

If for some reason you have disabled System Restore, you really should consider turning it back on.  I have seen a few sites mention how to turn it off (but for the most part they do warn you of the consequences), but you really want to leave it on.  I have had to use System Restore a couple of times and it really got me out of jam.  If you need to re-enable System Restore, the following steps should work for you:

  1. Click on the Start button.
  2. Right click on “Computer” ,and then select Properties. (Also reachable as the “System” applet on the Control Panel.
  3. On the left hand side of the Control panel->System dialog, click Advanced Settings.  If the User Access Control dialog rears it’s ugly head and propmtps you to permit the action, click on Continue (or OK) to allow you to continue.
  4. Click on the System Protection tab.
  5. In the group box labeled “Automatic Restore Points”, check the checkboxes listed for your hard drives.  Some PC’s come with special partitions used for vendor specific diagnostic and restore functionality (Dell PC’s typically have a special partition labeled “RECOVERY”, leave those partitions unchecked.
  6. Press OK to save the changes.

There’s rarely a free lunch in this business, and there is a cost to using System Restore.  This cost is pretty simple, it will use up to 15% of the space on the drive, with 300MB as a minimum.  You also need to have a drive larger than 1GB to use System Restore.  With the huge drives now available to today, the benefit clearly out weighs the cost.

Dealing with the "Cannot generate SSPI context" error message

One of our sales engineers came up to me with with a problem that I had not come across before.  He was getting the error “Cannot generate SSPI context” when he tried to back up a database. Before getting too deep into the problem, I’ll lay out the background of how the problem occurred.

Our applications work with SQL Server 2000 and 2005.  Our desktop applications have the ability to back up the SQL Server database and store the backup on the local machine.  The backup command is issued to the database server, typically on it’s own server.  The account that SQL Server runs under typically can only access the local file systems.  You can get around that by running SQL Server under an account with network access, but as a shrink wrapped application, we want to under the default installation of SQL Server.

To get around the file system access, I wrote a win32 service that runs on the same machine as SQL Server.  Our applications back up the database through my agent service.  When the agent receives a backup request from a client, it does the following:

  1. Performs some preventative maintenance on the database
  2. Defragments the log file
  3. Backs up the database to local path
  4. Compresses the database backup to a .zip file
  5. Sends the compressed backup to the client
  6. Deletes the backup and compressed backup from the server.

It does a few other things, but those steps are the highlights of the backup process.  Our engineer was getting the “Cannot generate SSPI context” error right at step one.  I have never come across that error so it was time to fire up Google and go searching.  One of the top hits for goggling that error message was a KB article, 811889.  It was informative, but not especially helpful for me.  The top hit was much more helpful, “Cannot generate SSPI context” error message, when connect to local SQL Server outside domain, on the SQL Protocols blog.  Who knew that SQL Protocols had it’s own blog.  This post had all of the good details of what was happening and suggestions on how to resolve it.  I like that.

In short that error can occur when all of the following are true:

  1. The hosting machine of SQL Server is connected to a network, including home network or dialup connection, but it is disconnected from its domain.
  2. The OS of the hosting machine is Windows XP or 2000. Not windows 2003.
  3. The connection is to a local SQL Server.
  4. Connection configuration causes network library to choose TCP/IP provider.

The root cause is that agent service is using integrated security to connect to the local server over TCP/IP.  The SSPI in the error message stands for Security Support Provider Interface.  SSPI is a set of Windows API that handle delegation and authentication over data transport layers (TCP, Named Pipes, etc).  With TCP/IP and SSPI, the Kerberos protocol is used to authenticate the user account.  This will attempt to access the Active Directory services of the domain that the user is logged into.  If that domain is not accessible, the authentication attempt will fail.  This check will only occur if SSPI detects that it is on a network.  If it’s not on a network, it will use NTLM, which for our situation will work just fine.

In our case, the engineer has a laptop and he logs into it with a domain account.  If he’s demoing the products at a clients site, he may have a network connection, but not be connected to our domain.  The immediate work around was for him to close his network connection and do his backup.  Literally all he needed to do was to press a button on his laptop to turn off his wireless adapter.

The long term solution will be for me to change conditions #3 or #4.  The code is currently hard coded to connect to a sever named “(local)”, I may try replacing that with the TCP/IP loopback address 127.0.0.1.  If that doesn’t work, I add a setting that allows the agent service to connect with the Shared Memory or Named Pipes providers.

Looking forward to stackoverflow

Not an actual stack overflow, but the new site, stackoverflow.com, run by Jeff Atwood and Joel Spolsky.  Their aim is to provide some sort of programming Q&A site.  Accurate and up to date information that’s easy to find by having programmers ask questions and other programmers answer them.  I hope that they can pull it off.  My usual method of learning something programming related is by what Joel referred to as “page-fault” learning.  I start out with a Google or forum search, get the basics, and start implementing until I hit an error or a mental block.  Then I jump back on the Intertubes to research a little deeper.

I’m so tired of hitting Experts-exchange when I google a topic.  So much that I’ll specifically exclude it from my Google searches by tacking on  “-site:www.experts-exchange.com” to the search string.  There’s something about that site that just rubs me the wrong way.  it’s like “We’ll tease you with the question, now pay up for the answer”.  And you’ll have no way of knowing if the answer is correct or applicable to your need until after you have paid them.  No sir, I don’t like it.

Right now, the only thing up on the site is a podcast of a conversation between Jeff and Joel.  I’ve been listening to it and it’s pretty good.  I can’t wait for the site to take form and I hope to be able to contribute to it in some small form.

There’s no privacy with infant video monitors

We still have a video baby monitor on our youngest, Laura.  She’s 5, but we never got around to taking it down.  At bedtime, Laura and her older sister Kathryn will perform for each other in front of the camera while the other one is watching the monitor.

Last night when the girls went to bed, I turned on the monitor.  All I could see was static and some form of interference. The camera to monitor connection is wireless.  You can pick one of two channels and fiddle around with the antenna, but that’s about it.  It’s very much like watching TV on a B&W portable, circa 1976.

As I fiddled around with the antenna, the view on Laura’s room disappeared and I could see an infant lying in a bed with a pacifier in his mouth.  I called out to my wife, “Look, they canceled the Laura Show and replaced it with a new one.”  We think this baby is our next door neighbor’s baby.  They just had a baby boy a couple of months ago.  I’m going to over and talk to them on the weekend and let him know that we are picking up their video signal.

For now, we have stopped using the monitor.  Laura is will past the age of needing a monitor, and it feels too much like voyeurism to be watching and listening to someone else’s baby.  

Handy tip for debugging a Windows Service

Debugging a Windows Service is always a pain. You can’t run a service like a regular application, you have to run it from Windows Service Control Manager (SCM) and then have your debugger attach to the process while it’s running. The problem is that it’s difficult to debug problems with the service startup as the debugger can’t attach to the service in time.

I came across a tip on the .NET Tip of The Day site, “How to debug Windows Service startup”. Basically, you just add a line that calls Debugger.Launch() or Debugger.Break() in your startup code. When your code hits one of those lines, the Visual Studio Just-In-Time Debugger dialog will be invoked and you can select your debugger to handle the error. That will allow you to continue along in the code and debug until the cows come home.

That works better than a service debugging tip I posted a couple of years back, calling the Sleep API in your startup code to allow enough time to attach a debugger to the service. That was a hack, this is much cleaner.

All in all, I still prefer to separate the functional code from the service specific code. I can then run that code from a desktop app, making it much easier to debug. That works about 99.9% of time. Every now and then, I do need to run the actual service code and the Debugger.XXXX() calls will make that task much easier.