PITADEV
Curiosity killed the developer's project.

Windows 7 "Repair Install" (AKA "Did I fall asleep?")

Saturday, 24 October 2009 14:51 by kevin

...a highly questionable method that works... or at least worked once for me. 

I'm going to give smaller disclaimers a few times, but let me start out with a comprehensive one: I am not an expert in Windows, nor do I really do PC system administration for a living, nor did I hear from anyone else that this idea was OK.  Also, I did it just last night, and if I set myself up the [time]bomb, I won't know for a while.  Also, for all I know, it could only work this way on certain combinations of hardware.  Absolutely do a disk image backup before trying this, and absolutely do not try this with a machine that you need to have working tomorrow or your kid won't get his life-saving medication. In fact, it is my recommendation that you don't do this at all.  That said, I'll tell you what I did to move a fully functional Windows 7 system hard drive from a 2-year-old Dell Latitude laptop to a 1-month-old Dell Studio XPS desktop.

If you find yourself reading this, you probably already know that Windows 7 has no straightforward "Repair Install" option of the type you could use on Windows XP to move a hard drive to a system with completely different hardware.  According to what I've read, people often would do this when replacing motherboards.  You've probably also been annoyed to find out that the Windows 7 install disk, and the Vista and Windows 7 resources you find via Google search, tend to be obtuse about the reasons people would want to do such things: they assume you can successfully log into Windows at all on the relevant machine, but you still need to "repair" your installation.  You boot up the Windows installation disk, tell it you want to "Upgrade" your existing installation (the method of "Repair Install" that everybody recommends), and it tells you to remove the disk, shut down, boot up Windows, and stick the disk into the drive again after you're in Windows.  Well, when you've moved your system disk to a system that has a completely different motherboard, that's not really an option.  Usually, you get a fatal error and an infinite reboot cycle.  But by all means, if you can get into Windows on your relevant system, and you still need to do a Repair Install, follow the instructions at the sevenforums.com link; don't do what I did.

To make this work, you need to have access to the old, working system (the "source" system).  So this may not work for a lot of motherboard replacements, especially if the old one is burnt out or you didn't find out the system didn't boot until the whole rebuild was done, and you don't want to undo everything and start over. But if you're just trying to clone an existing system so you don't have to go through the weeks-long process of reinstalling all your software and redoing all your miscellaneous config settings, or if you're trying to move a system from any old (working) hardware to any new hardware, this might work for you.

So without any further ado, here's what you do: 

1. Boot up your working (old) system, using the hard drive that belongs in the new system as your system drive.

2. Begin the "Repair Install" process as described in the sevenforums.com link.  Go about the beginning of the Upgrade process as if you were Repair Installing to your old system.

3. When the Windows installer tries to reboot for the first time -- a few minutes after it has said "That's all the information we need right now" -- forcibly TURN OFF your computer* in the few seconds after the installer OS has unloaded and before the installer OS loads up again.  I believe the first reboot attempt happens after it's done with the "Expanding files" step, but I'm not 100% sure (please tell me if I'm wrong).  Just make sure the system is at least in your peripheral vision while the installation is happening, so that you'll see when the monitor goes blank.

4. Move your hard drive to the new system.  I also put the installation disk into the DVD drive, but I doubt that was necessary.

5. Boot up the new system, making sure that it boots to your hard drive, not the installation disk.  If you have a choice on your bootloader screen, choose the entry that says something like "Windows 7 Setup", not the one that says something about "Rollback".

6. Let the installer do its thing.  In my case, it seemed like the installer took a while longer than it has usually taken for me, but then, I usually am not running an Upgrade, but a new installation, so this could be normal.

The process itself is a lot simpler than explaining why you would want to do it.  Basically, it's the Repair Install process, but with the hard drive moved to the new system partway through, after the installation files have been prepared on the system drive.  My guess is that all of the assigning of low-level hardware drivers -- the stuff that makes it impossible to move the system hard drive without any hassles -- simply happens later in the installation process.

If you're still reading, be sure that you have a good reason for wanting to do this.  I did it because I had spent many hours installing development tools onto my new SSD drive.  I decided I wanted that drive in my new desktop, and I didn't want to reinstall everything.  And because this machine wasn't one of my two "main" computers, I didn't feel like I was risking much.  Even so, I made sure to take a Windows Home Server backup before beginning the process, just in case I wanted to get that experimental system back.

I cannot stress these things enough: 

  1. Don't do this if you don't feel like you know what you're doing.  
  2. Don't ever do this with a system drive that you're relying on for anything important, unless you're 100% confident you can restore it quickly.  Even so, I probably wouldn't do it.
  3. I don't know whether this would work for other people's hardware.
  4. I'm not really recommending you do this at all, and even if I were, you shouldn't think of me as an authority, as I'm just a guy on the internet.

 

For anyone who heard me telling everybody a couple weeks ago about how Windows 7 was awesome because it lets you just move a hard drive from one machine to another, and just figures it out: consider this a revision to that.  I had seen two cases where Windows 7 installations seamlessly figured out new hardware: 1) a VHD-based Windows 7 system had zero difficulty moving from running in VirtualPC to having that VHD file running on native hardware as a bootable VHD.  It may seem counterintuitive to some, but as far as the OS is concerned, this is one case of moving seamlessly between "hardware" setups.  2) When I moved a hard drive from a Latitude 820 to a Latitude 830 and back, Windows 7 had no problem with it.  If this sounds like nothing: I had tried to do the same thing, between the same two specific laptops, with XP system drives in the past, and they crashed hard.

* usually works by holding down the power button, but if you didn't already know how to force your PC to turn off, as opposed to turning it off via "shutdown", you shouldn't be doing this.

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Categories:  
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed

Stifling the Oral Tradition; Documenting Self-Documenting Code

Friday, 7 August 2009 12:54 by aj

I have a hard time interviewing people.  No, it’s not because I don’t enjoy being a complete asshole or because I don’t know about the perfect interview question.  It has everything to do with the fact that I’m a fatally honest son-of-a-bitch.  So, when someone comes into an interview for a developer position at my company and asks what methodology we use, I always answer, “We don’t.”  It’s not that we’re completely disorganized (although sometimes we’re close), it’s that we are extremely production-oriented, and since we’re not a software company, our executives could care less about Kanbans, Scrums, and Waterfalls.  I’m not excusing this.  I think it’s a crime that we aren’t following something.  But it’s the reality of the situation and it’s going to take a long time to change.

One of the biggest problems any haphazard development department like mine encounters is a total lack of documentation.  It’s a cliché that developers hate documentation.  Especially project documentation.  I’m not even sure developers should be responsible for project documentation.  However, following these simple steps, I have found that I almost enjoy documenting my large libraries and frameworks, making life easier on my peers as well as satisfying auditors, PMs, and other business riff-raff.

Note: The following has a “tutorial” feel to it.  Both Sandcastle and GhostDoc are so easy to use that if you don’t want to follow these steps as guidelines for best-practices, then just go get them and start using them.

  1. If you’re not already, get familiar with Visual Studio’s built-in XML documentation capabilities.  In C#, type “///” (‘’’ in VB) above a class, method, property, namespace, whatever.  You’ll see a nice set of comments fill in for you:
    			/// <summary>
    	
    			/// A method that does stuff.
    	
    			/// </summary>
    	
    			/// <param name="stuff">A <see cref="IDictionary{TKey,TValue}" /> that has stuff in it.</param>
    	
    			private static void DoStuff(IDictionary<string, int> stuff)
    	
    This is a well-known feature of VS, so I’m not going to spend a great deal of time on it.
  2. Use very descriptive names for everything!  I could give a crap if you name a property “ContainerForAccountInformationThatHasAReallyLongName.”  At least I have some idea what the property is.
  3. Download and install SubMain’s GhostDoc.  Let it integrate with Visual Studio as it installs.  Don’t be afraid, it’s probably smarter than you are, and it’s free.  Once you have it installed, open up your favorite project and find a class or member with a really nice signature.  Something with a lot of parameters, generic type parameters, etc., and make sure everything is following item 2.  Put your DocumentThis cursor on the member signature, right-click (or use the built-in hotkey) and select “Document This.”

    GhostDoc extends the built-in XML documentation and interprets not only your member and parameter names, but what the description text should possibly be.  And if you are naming things well, it’s usually pretty damn close to right.  It is quite configurable and even attempts to interpret situations where you should add remarks along with summary documentation.  Using GhostDoc has greatly decreased the amount of typing I do for inline XML documentation.  Here’s an example of a method documented by GhostDoc with no changes made:
    		/// <summary>
    	
    		/// Locks the process item.
    	
    		/// </summary>
    	
    		/// <typeparam name="TProcessItem">The type of the process item.</typeparam>
    	
    		/// <param name="processItem">The process item.</param>
    	
    		/// <returns></returns>
    	
    		protected override TProcessItem LockProcessItem<TProcessItem>(TProcessItem processItem)
    	
    Notice it doesn’t fill in the value for “returns,” but if you think about it, there’s really no way for it to know that.  Besides, this is the sort of typing that we should do, because it eventually provides a synopsis of what the method does.
  4. Document your code and build your project.
  5. Download and install Sandcastle.  Fire it up.  The default empty environment will set you up with a new project.SCAddSource  After saving/naming the project, in Sandcastle’s Project Explorer, right-click  “Documentation Sources” and browse to the build .exe or .dll for your project.  Alternatively, you can use the .Net solution or project file.



  6. In the Project Properties, find “HelpFileFormat.”  This is how you can configure what sort of help files you want Sandcastle to build.  There are currently three options:

    HtmlHelp1x – Standard CHM help file that we’ve all come to know and love, built with HHC.exe, which you should already have installed.
    HtmlHelp2x – HxS help file.  Note that you need to have HXCOMP.exe, which is part of the Visual Studio SDK.
    Website – A rather robust HTML website that looks a bit like an older version of MSDN.  I haven’t experimented with this, but the Sandcastle site has a lot of tips on how to use third-party plug-ins for Ajax and other cool stuff.

  7. Configure all of the other Project Properties in Sandcastle as you see fit.  You’re going to miss some stuff.  Don’t worry, Sandcastle makes it easy to see what you’ve missed.  Leave the log-related properties as their defaults.
  8. Under the “Documentation” menu, select “Build Project.”  After a short time, your build will complete.  Navigate to your “OutputPath” folder and look at your awesome new help documentation!  Then, package it up with your project so that everyone can use it, send it to your boss, and go get some ice cream.

 

While browsing through your documentation and feeling really good about yourself, you may notice some points where Sandcastle will have marked in bold-red font, [Missing <something> documentation for “a particular thing”.]  You can easily repair this by going back to your project and adding the missing XML documentation, or, if it’s a namespace, you can add namespace documentation to the Sandcastle project by using the Namespace Summaries editor found in the Project Properties for “NamespaceSummaries.”  Also, if you would rather not dig through every single page generated by Sandcastle, you can easily find missing documentation by looking at the build log, which can be accessed through “Window—>Build Log Content.”  Sandcastle highlights any warnings for missing documentation in the build log, making it very easy to scroll through and see what you might have missed.

BuildLogWarn

 

So, with a little extra work (as opposed to a ton of extra work), you can feel a bit better about your documentation habits.  I’ve found that using these simple steps has made me a better programmer as well as a better teammate.  Looking at the output from Sandcastle and adding meaningful information to my code with GhostDoc makes me pay more attention to its structure and design.  That, in itself, makes it worth the effort.

Currently rated 4.5 by 2 people

  • Currently 4.5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Setting an EventLogAppender’s Event Source at Runtime

Friday, 17 July 2009 09:37 by aj

I’m switching one of my big frameworks over from a homegrown logging solution to the beautifully simple and powerful log4net.  One of the many conveniences offered with log4net is the ability to log messages to many different message repositories with one call.  Our application requires three logging repositories: a table in our DB2 database, SMTP email, and the event log.  Using the built-in thresholds, the DB2 table receives all messages, while email and the event log only receive Error and Fatal messages.

This particular framework runs under a Windows Service, which uses a Factory to load multiple implementation assemblies that all execute on their own child thread.  Each implementation is responsible for its own set of activities, of course, and the service itself knows only to check the child threads every now and then to make sure they aren’t dead.  Using the default setup for the EventLogAppender, you can set the event source in the configuration by setting the EventLogAppender’s ApplicationName property.  In this case, all of the configuration for log4net is set in the service’s app.config file, which means that the settings for each appender are global to the service.  That’s fine, for most applications, but in this case it would be very convenient to change the event source to something that’s indicative of the specific implementation thread making the logging call, making it much easier to find messages related to a particular implementation.

The obvious way to do this would be to set the ApplicationName property at runtime before each logging call.  However, after much Googling, I wasn’t able to find an example of how to do this.  So I mused and ruminated and muddled about for a while, and eventually started fiddling in the Immediate Window while debugging my test application, attempting to figure out how to access specific appender properties at runtime.  Turns out the solution is simpler than I could have imagined.  Using the excellent tutorials provided by Sir Beefy, I set up my log object like this:

   1: //Console app, global
   2: private static log4net.ILog log;
   3:  
   4: //In void Main()
   5: log4net.Config.XmlConfigurator.Configure();
   6: log = log4net.LogManager.GetLogger(
   7:     System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

Then I provided a Log() method in the abstract class that is required for each implementation that looks something like this:

   1: protected void Log(string appName, 
   2:                    string message, 
   3:                    Exception ex, 
   4:                    log4net.Core.Level entryLevel)
   5: {
   6:     //Set the application name of the EventLogAppender
   7:     ((log4net.Appender.EventLogAppender)
   8:         log.Logger.Repository.GetAppenders().Single(
   9:         a => a.Name == "EventLogAppender")
  10:         ).ApplicationName = appName;
  11:     //do whatever else to log the entry
  12: }

That’s it.  It might be a better idea to use a GetType() call to find the Appender of type EventLogAppender and set the ApplicationName property that way, but I don’t think that’s necessary here.  So if you’re looking to change the Event Source at runtime using log4net to an event log, this is one way to do it without having to change the configuration file on the fly.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:  
Categories:   .Net | Tools
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed

Which.bat -- "whereis" for old Unix people who hack their Windows something fierce

Wednesday, 17 June 2009 16:20 by kevin

(file under: interesting info that's difficult to Google)"Vintage Plastic Witch with Bat" photo by Flickr user "riptheskull"

If you're like me*†, you download a huge amount of open-source and free utilities that don't have installers, write a bunch of batch files and scripts to automate common tasks, and use cmd.exe constantly‡.  So, you're setting up a new VirtualPC image, and you know you want to have the Sysinternals utilities on your new machine €, but you don't want to re-download them and you don't know where the heck you unzipped them to.  Where oh where could pslist.exe be?  Wait, you're an old Unix guy.  When you want to know where in your path an executable file is, you say "which".

Gladly, the great Raymond Chen solved your problem years ago, though you didn't know it till now:

@for %%e in (%PATHEXT%) do @for %%i in (%1%%e) do @if NOT "%%~$PATH:i"=="" echo %%~$PATH:i

Paste this line into a file in your Windows directory (or elsewhere in your path; c:\scripts or something like that), save as "which.bat" (or "whereis.bat" if you're not really an old Unix guy and you've just been pretending up till now).  Use like so: "which pslist".  To which it replies "c:\Program Files\Sysinternals\pslist.exe".  Simple as that.

Talk to you next season! 

 

*alive!  All recent appearances to the contrary.

and I realize you probably aren't, aside from being alive

 I tried getting into PowerShell a few times, and I'm sure I'll eventually end up there, but at some of the basic shell commands, it's just not fast enough for me. I sometimes do this cycle 20 times in a minute:

cd [beginning of dir] [tab-to-complete] [enter]
dir /od
cd [other dir beginning][tab-to-complete][enter]

I just cant wait 5 seconds (every single time.) for PowerShell to "Get-ChildItem" when it would have taken 1 second for cmd.exe to "dir".  

(yes, €) You may not have known that you know you want the Sysinternals Suite until now.  I'm glad I could be part of your self-discovery process.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Categories:   Dev Info
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed

ReSharper C# FTW (again), VB not so much

Wednesday, 3 June 2009 13:24 by aj

resharper I write both VB and C#.  Anyone who’s read this blog knows that I prefer C#, but VB is my company’s standard, so anything I write that will be deployed is written in VB.  To keep my skills from decaying and in something of a silent protest, I do all of my prototyping and test code in C#.  I have ReSharper 4.5 Full Edition installed, and although JetBrains states that 4.5 has enhanced VB9 support, I’m still amazed at how much more it does for me when I switch over to a C# project.  It’s possible I don’t have it configured correctly, and I haven’t customized it at all yet (too busy coding, I guess).  Either way, here’s an example of what ReSharper does with the exact same method, first in C#, then in VB.

The method is a simple string parsing method.  I have a DB2 table full of strings.  Somewhere in each string is an eight digit number that I need.  However, this data was populated using a regular expression (^\D?\d{8}\D?$) that searched for all strings that have one non-digit wildcard before or after an eight digit string, which made room for situations where an octathorpe (#), parenthesis, colon, or anything else may have been directly in front of or following the desired string.  Since the eight-digit string is all I really care about, here’s what might be a typical (albeit poorly written to accentuate ReSharper’s capabilities) little method to chop off the leading and/or trailing wildcard, if it exists, and return the meaningful eight digit string:

   1: private String GetRealFieldData(string regexMatchData)
   2: {
   3:     if (regexMatchData.Length == 10)
   4:         return regexMatchData.Substring(1, 8);
   5:     else if (regexMatchData.Length == 9)
   6:     {
   7:         if (System.Text.RegularExpressions.Regex.IsMatch(regexMatchData, @"^\D"))
   8:             return regexMatchData.Substring(1);
   9:         else
  10:             return regexMatchData.Substring(0, 8);
  11:     }
  12:     else
  13:     {
  14:         return regexMatchData;
  15:     }
  16: }

Ugly, ain’t it?  ReSharper thought so, too.  Here’s what the snippet looks like in my IDE with ReSharper’s default options enabled:

ResharperCs1

Look at all of the possibilities that ReSharper found!

ResharperCs2First is the method signature, which (since for this blog I put this code in a console application) can be made static. That’s pretty boring by ReSharper standards, but I went ahead and let it do it anyway, since it doesn’t really hurt anything and I am generally of the mind that members should have explicit and accurate modifiers.

ResharperCs3 Let’s get to the meat, which surrounds all of the if-else conditions.  Notice that they are all grayed out, and that ReSharper put a green underline under the if’s.  Anything that gets grayed out is unnecessary code, and I love brevity, so I told ReSharper (by hitting the default ALT+Enter keyboard combination to expand the little light bulb) to go ahead and fix the bad else’s, which resulted in this snippet:

   1: private static String GetRealFieldData(string regexMatchData)
   2: {
   3:     if (regexMatchData.Length == 10)
   4:         return regexMatchData.Substring(1, 8);
   5:     if (regexMatchData.Length == 9)
   6:     {
   7:         if (System.Text.RegularExpressions.Regex.IsMatch(regexMatchData, @"^\D"))
   8:             return regexMatchData.Substring(1);
   9:         return regexMatchData.Substring(0, 8);
  10:     }
  11:     return regexMatchData;
  12: }

OK, that’s a little better.

ResharperCs4   But the real fun lies in the green underline under the embedded if statement, where Regex.IsMatch() is called.  I was curious to see what the light bulb said, and even more curious after the light bulb offered a “Replace with ‘return’” option.  So I let it rip, and was delighted to see the results, which will ultimately make me a better C# programmer since I learned a little more C# syntax.

   1: private static String GetRealFieldData(string regexMatchData)
   2: {
   3:     if (regexMatchData.Length == 10)
   4:         return regexMatchData.Substring(1, 8);
   5:     if (regexMatchData.Length == 9)
   6:     {
   7:         return System.Text.RegularExpressions.Regex.IsMatch(regexMatchData, @"^\D") 
   8:             ? regexMatchData.Substring(1) 
   9:             : regexMatchData.Substring(0, 8);
  10:     }
  11:     return regexMatchData;
  12: }

Then, I took the same method in its original (crappy) form, and translated it to VB to see what ReSharper would do.  Here’s the method again, VB this time:

   1: Private Function GetRealFieldData(ByVal regexMatchData As String) As String
   2:     If regexMatchData.Length = 10 Then
   3:         Return regexMatchData.Substring(1, 8)
   4:     ElseIf regexMatchData.Length = 9 Then
   5:         If System.Text.RegularExpressions.Regex.IsMatch(regexMatchData, "^\D") Then
   6:             Return regexMatchData.Substring(1)
   7:         Else
   8:             Return regexMatchData.Substring(0, 8)
   9:         End If
  10:     Else
  11:         Return regexMatchData
  12:     End If
  13: End Function

Even uglier than it was in C#, but I guess that depends on who’s looking.  Here’s the view in my IDE:

ResharperVb1

Wow, that’s quite a difference!  Aside from the method signature (VB console apps default you to Module1.vb rather than program.cs, so static/shared isn’t an issue here), none of the stuff that was marked by ReSharper in the C# version of this method is marked in the IDE for a VB application.  However, the light bulbs still do show up, I just had to move through line by line to see them.  ResharperVb2 Going to the ElseIf statement brings up a bulb offering to change the if statement to a select case statement, but nothing is said about converting unnecessary else’s to returns.  Also missing is the option to convert the Regex.IsMatch() condition to an If/Iif statement, my favorite part of the C# example.

So I guess the added support for VB in ReSharper 4.5 still lags well behind the power this plug-in provides for C# programmers.  And you know what?  I don’t blame JetBrains at all.  I believe that ReSharper is as much a best practices tool as it is a productivity tool.  When it comes to .Net best practices in books and online, a huge percentage of the examples you see are in C# rather than VB.  I applaud Microsoft for supporting both languages as .Net moves forward, even though VB has been behind in several language features, but why would JetBrains spend a great deal of time and money integrating VB support into ReSharper when the majority of the developers that use their product are coding in C#?  I have many more theories on this, which I’m sure I will expand on in days to come, and I’m hoping that I find ways to make ReSharper a better tool for VB coding.  But for elegance, productivity, and best practices, the true value of this tool is still found in C#.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:  
Categories:   C# | Tools | VB | Visual Studio
Actions:   E-mail | del.icio.us | Permalink | Comments (4) | Comment RSSRSS comment feed

Raw Power

Wednesday, 27 May 2009 12:56 by aj

One of the problems that comes along with writing my own blog on software development is that I often expose my own ignorance.  I don’t pretend to know everything, by any stretch of the imagination, but writing stuff that anyone can read comes with a modicum of “assumed authority,” which I clearly don’t have.  However, I sometimes stumble across things that are so cool that I just have to write about them, no matter how behind-the-times they may make me look.  So, I’ll just come out and say it now: Powershell rocks my world.

Yesterday I was dinking around with a web-forms app that required some mildly tricky string manipulation.  When coding in Visual Studio, I’ve often found myself wishing that there were some way to use the Immediate Window to evaluate runtime behavior at design time.  For example, I can never remember string formats.  The .ToString(“format”) method is extremely common, but I’ve already got too much crap crammed in my skull to remember all of the possible values for “format.”  What I’ve always done in the past is fire up my project in Debug mode, put a breakpoint somewhere, and then use the Immediate Window to figure out which argument I need to pass to ToString().  There’s probably a better way to do this in general, but somehow my string of searches yesterday led to Powershell, and goodness am I happy about it.  It’s not that I didn’t know that Powershell existed.  Brad’s been singing its praises forever.  I just never took the time to understand how powerful it is. 

A known bug with the Immediate Window that I don’t believe has been solved yet is the “'RegularExpressions' is not a member of 'Text'” exception.  If you’ve ever tried to execute RegularExpressions in the Immediate Window, you’ve probably seen this.  After downloading and installing Powershell, I started out working on how to test the evaluation of a Regex.Replace() statement.  First, I had to figure out how to get the System.Text.RegularExpressions namespace loaded.  I found a nice blog post that taught me how to do that, and I’m pretty sure that you can have a Powershell script execute on launch as part of your profile.  This little guy will definitely be a part of it when I have time to figure it out.

   1: PS > $GacRootDir = Join-Path -Path $Env:SystemRoot -ChildPath "Assembly/Gac"
   2: PS > Get-Childitem -path $GacRootDir -recurse -include *.dll| Foreach-Object {$_.FullName} | Foreach-Object {([Reflection.Assembly]::LoadFrom($_))}

 

After that, most of what you can do is a matter of learning the syntax, and for a guy who spent the first six-odd years of his programming career using VIM in command prompts, I must admit that it’s strangely comforting to get back to a little command-line scripting.  Once my GAC assemblies were loaded, I set about solving my string manipulation problem.  Specifically, I needed to set a NavigateUrl property to a UNC path, which then got sent to a JavaScript method.  The code-behind is VB, but JavaScript, of course, likes it’s back-slashes to be escaped like C#.  For some reason my brain thought that I should use Regex.Replace() for this (maybe scripting reminded me enough of Perl that I wanted to do a little $foo =~ s/\\/\\\\/g; or something).  Testing this in Powershell was simple:

RegexReplacePS Lovely.  Really, it was.  I didn’t have to fire up a debugging session to find out that Regex.Replace() is going to be funny about back-slashes too, which, if I’d actually taken two seconds to think, I would have already known.  Then, I remembered String.Replace():

PSStringReplace I know, I know, this is elementary stuff.  But the beautiful thing to me here is that Powershell let me do this in a matter of seconds at design-time rather than having to write a separate application or fire up the debugger

Even more fun, I learned how to load unsigned .Net assemblies (and COM!) into Powershell so I can run methods for testing and support issues without having to write a test app.  Simply using System.Reflection.Assembly, same as I would to load an unreferenced assembly in code, I can initialize a new object and then view its members and execute its methods. 

So, maybe I just made myself look ignorant, but I needed to say something because I’m so excited to be finally learning to work with this powerful tool.  If you’re a .Net developer and you’re not already using Powershell, I highly recommend that you go and check it out.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:  
Categories:   .Net | Tools
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed

A Necessary Evil

Tuesday, 19 May 2009 08:50 by aj

Creative Commons user Paulus Veltman

One of the most well-known code smells in .Net development is explicitly messing with the Garbage Collector.  In my coding travels, I’ve had at least a couple of situations where a performance/memory consumption issue was traced back to a GC.Collect() call.  In my own applications, I’ve generally followed Rico Mariani’s Rule #1, “don’t use it.”  I figure the .Net Framework team has a much better idea of how to handle that sort of stuff than I do, and for the most part, their ideas work just fine.

I’ve been working on a project for the last month or so that requires the use of an OCR API to read type-written words from TIFF images and then run them up against a set of regular expression patterns looking for useful data.  There are several OCR libraries available for purchase, but after significant testing and analysis, we decided that the Microsoft Office Document Imaging (MODI) library that comes with Office 2003 works about as well as anything else, and has the added benefit of being free, since our workstations haven’t been upgraded to Office XP.  I spent some time figuring out how to use MODI for OCR, then found a nice tutorial on Code Project that would have saved me some time.

Our TIFF images are stored in a homegrown database/file system setup that, after years of working with FileNet, is a cool breeze on a hot day.  Through more prototyping, I found that MODI OCR’s performance was best if I copied each multipage TIFF file to the local system, split them into single page files, and then ran each file through the OCR process, cleaning everything up afterward.  Here’s a chopped down version:

   1: MODI.Document modiDoc = null;
   2: MODI.Image modiImage = null;
   3: MODI.Word modiWord = null;
   4: List<String> filesToProcess = null;
   5: try
   6: {
   7:     filesToProcess = SplitTif(inputFile, workingFolder);
   8:     foreach (var fileToProcess in filesToProcess)
   9:     {
  10:         try
  11:         {
  12:             modiDoc = new MODI.Document();
  13:             modiDoc.Create(fileToProcess);
  14:             modiDoc.OCR(MODI.MiLANGUAGES.miLANG_ENGLISH, true, true);
  15:             for (var i = 0; i < modiDoc.Images.Count; i++)
  16:             {
  17:                 modiImage = (MODI.Image)modiDoc.Images[i];
  18:                 for (var j = 0; j < modiImage.Layout.Words.Count; j++)
  19:                 {
  20:                     modiWord = (MODI.Word)modiImage.Layout.Words[j];
  21:                     if (System.Text.RegularExpressions.Regex.IsMatch(modiWord.Text, regexPattern))
  22:                     {
  23:                         //Do stuff that needs to be done when there's a hit
  24:                     }
  25:                 }
  26:             }
  27:         }
  28:         finally
  29:         {
  30:             if (modiWord != null)
  31:                 DisposeCom(modiWord);
  32:             if (modiImage != null)
  33:                 DisposeCom(modiImage);
  34:             if (modiDoc != null)
  35:                 DisposeCom(modiDoc);
  36:             modiWord = null;        //This may be redundant...?
  37:             modiImage = null;
  38:             modiDoc = null;
  39:         }
  40:     }
  41: }
  42: catch (Exception ex)
  43: {
  44:     //handle it
  45: }
  46: finally
  47: {
  48:     //Cleanup temp files
  49:     if(filesToProcess != null && rdoNIS.Checked)
  50:         filesToProcess.ForEach(System.IO.File.Delete);
  51: }

Notice all of the cleanup.  I’ve learned the hard way that it’s never a bad idea to be very explicit about cleaning up COM objects, especially since a lot of COM objects don’t implement anything close to IDisposable.  So, with this code, I thought I was good to go.

And for the most part, I was.  My company has two main data centers: one in the building where I work, in a city I’ll call St. Small, and one that’s roughly 1,300 miles away, in a city I’ll call Sunville.  The TIFF images and the database I’m persisting data to are in Sunville.  The workstations that I started out running my client application for the OCR process are all in St. Small.  They worked fine, albeit slowly due to network latency and crappy hardware. But I wanted the process to run faster, since we have a lot of images to sift through, so I nabbed up the only workstation I could find in Sunville, set up my client, and started to run a batch.

I was quite surprised when I repeatedly and inconsistently received OutOfMemory exceptions from the MODI OCR method.  I checked all of the system resources, running programs, and RAM, and everything looked fine.  It’s running a dual-core processor at 2.4 GHz with 2 GB of RAM, which should be totally adequate for the MODI process, right?  Wrong.  No matter how hard I tried, I could not get these exceptions to go away.  What was even more interesting is that I wasn’t getting the errors on the workstations in St. Small.

So what’s the difference?  Duh.  Since the Sunville workstation doesn’t have nearly as much network latency to deal with, it does run quite a bit faster.  Since it’s able to run faster, it’s creating and destroying MODI COM instances much more frequently than the copies running on the St. Small systems.  So I did some more web research, more testing, and with a cringe, I added this line of code (and the comment) to my finally block: 

   1: //THIS IS VERY VERY BAD YOU BAD BOY
   2: GC.Collect();

I tested it on my workstation and performance didn’t seem to suffer too much.  So I dropped the new version of my application on the Sunville workstation and fired it up, thinking I’d solved the problem.

Nope.  The Sunville system still threw random OutOfMemory exceptions.

Creative Commons User Photos o' Randomness

What gives?  I thought GC.Collect() was the magic baseball bat that beat the crap out of everything?  If it isn’t, why is it so terrible to use it?  Well, the answer is, it is terrible to use.  Read Rico’s post and the many other articles on Garbage Collection, if you don't believe me.  But in my situation it seems necessary, since we have so many images to process and I don’t want to babysit every instance of the application.  I still had the problem, though.  Why wasn’t GC.Collect() working?

Because I wasn’t using it correctly, that’s why.  The client application I wrote was a quick and dirty Windows Forms app, so all of the MODI OCR calls were synchronous.  GC.Collect(), on the other hand, is not.  However, you can force it to be synchronous by adding one line of code, which I did, and now my application runs wherever I want it to.

   1: //THIS IS STILL VERY BAD AND YOU ARE STILL A BAD BOY
   2: GC.Collect();
   3: GC.WaitForPendingFinalizers();

It’s funny—I can actually see the points when the code execution is sitting on that line.  It doesn’t happen often, but it clears up all of my errors.  If anyone knows a better way, I would love to hear it.  I don’t want to use it, but for this project, I’ve come to believe that forcing garbage collection is a necessary evil.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:   , ,
Categories:   .Net
Actions:   E-mail | del.icio.us | Permalink | Comments (2) | Comment RSSRSS comment feed

The Essence of Punk

Saturday, 16 May 2009 06:40 by aj

One of my favorite things about being a programmer is that I get to listen to music all day.  I know that many of my peers do this as well, and we’ve all seen silly suggestive lists of “the best music to code to.”  I’m old enough and cynical enough to know that my taste in music is better than everyone else’s, so I’m not going to waste any time arguing about what’s good or bad.  It did occur to me the other day as I rocked-out-with-my-Mock-out that there are certain songs that define certain genres for me.  So, I guess I’ll go ahead and start a silly suggestive list.

Musical genres themselves are stupidly annoying.  Show me the person who says they can definitively state the differences between between punk, hardcore punk, and metal-core, and I’ll show you a person who’s argument is easily Swiss-cheesed.  Genres are different for every person.  What’s punk to me may be rock and roll to someone else.  An original punk rocker might listen to some of these songs and say, [In sloppy British accent] “Whot tha fock, that’s fockin’ rocknroll, not punk!” 

So, with that lengthy and broken disclaimer made, I now propose three songs that, to me, are quintessential punk rock.  When I think of punk, I think of songs like these:

Scared of Chaka – “A Lie and a Cheat”

This is the song that made me think about doing this list in the first place.  The classic, lo-fi sound, pounding drums, and ripping guitar, along with the understated distorted lyrics make this song a lot of fun to bounce around in an office chair to.

 

Dillinger Four - “Mosh for Jesus”

Sure, they’re from the same city as me, but I still think that Dillinger Four is one of the exemplary punk rock bands of the last 20 years.  The sharp contrast between vocals and the unapologetic rampage of guitar and drums always get me nodding my head.  Besides, what a great song title!

 

The Arrivals - “Born with a Broken Heart”

Not only is this a great punk song, it’s a great rock song.  There I go, mixing genres again.  Swiss-cheese is me.  The bridge alone in this song makes it brilliant.

 

 

Those are the only three I can think of right now, but I’ve been missing my old days as a music reviewer, so I’ll probably whip out more totally off-topic and completely subjective posts like this in the future.  Meanwhile, dear readers (assuming I have more than one), what songs scream PUNK to you?

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Some Things Are Worth Paying For

Friday, 15 May 2009 06:42 by aj

DualMonitorsWork

I am a huge proponent of multiple monitor setups for developing.  The more real estate I have, the more productive I am, and the happier I feel.  Sure, it’s hard to come up with metrics for this sort of thing, which is exactly why many companies (that aren’t software companies, most of whom understand that hardware is cheap and brains are not) won’t spring for extra monitors for their programmers.  My current company is that kind of company.  I even went so far as attempting to find ways to convince them to invest in things like multiple monitors and ReSharper, but have been so busy that I haven’t been able to put Mr. MacIntyre’s plan into action.

My boss, however, is quite reasonable about things like this, so much so that he went to an auction site and used his personal money to buy us each (there are only three of us right now, so he didn’t have to shell out too much) an extra monitor as long as we were willing to chip in for the hardware needed to run it.  We have the standard Dell low-profile desktop workstations with on-board video that only support one VGA monitor, and I didn’t want to crack the case on something that my company owned, so I was presented with a bit of a conundrum.

Then I learned about one of the coolest little products I’ve seen in a while, the EVGA UV 12+.  After a quick driver install, plug this little box (it measures about 3” x 3” x 1”) into a USB 2.0 port, then plug your extra monitor in (DVI is the default, but they provide a VGA adapter), and voilà, dual monitors!  You can even stack more than one UV 12 to run even more monitors.  Our little Dells only push 1440x900, which is the max widescreen resolution on the UV 12 (and is adequate on the twin 19" widescreens I have at work), but if you want higher resolutions you can upgrade to the more powerful UV 16.

So, with a generous boss and about 46 bucks with shipping, I now have dual monitors at work, and this pleases me.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:  
Categories:   Hardware | Tools
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed

Stack Overflow Dreams

Thursday, 14 May 2009 11:25 by aj

I, like thousands of other developers, have fallen in love with Stack Overflow.  I still use Google for the random programming questions that my teammates and I come across during the work day, but I am always stoked when an SO link comes up on my searches.  I generally check the site periodically throughout the day, although I don’t have time to troll it (like several other users seem to) and haven’t quite committed to setting up an RSS feed for it.  It is a tremendous resource, and though I was initially skeptical about its completely user-driven format, I’ve come to realize that that is exactly what makes it such an effective site.

For some odd reason, I’ve had particularly vivid dreams lately (no, it’s not as a result of Chantix, although it should be).  The other night I dreamt that I was sitting in my chair in our living room with my laptop on my lap, as I do most evenings after work.  I think we were watching the Twins bullpen throw another game, and my daughters were in their various states of chaos.  All in all, a very normal evening, except I was dreaming it.  Anyway, in this dream, I was in the midst of one of my frequent evening scrolls through the Unanswered question list on Stack Overflow, and noticed that my reputation had suddenly increased by 50 points.  I went to my user-profile page, and it had increased again, along with two new silver badges.  I clicked on the logo to go back to the SO homepage, and my reputation had increased by thousands, with gold badges and silver badges and accolades galore.  I was euphoric! 

Shamelessly Paint.Netted from Skeet's rep

It was such a realistic dream that I actually checked my reputation right away the next morning, only to see the sad reality  that is my true reputation.

Some day, 500!

This got me kind of mad.  I mean, what do I care what a bunch of other geek/dork/nerds think of my geek/dork/nerd abilities?  Just because I don’t hang on every single (often unintelligible) question that is posted shouldn’t make me less important or intelligent than the Stack Overflow Pantheon.  I mean, seriously, do these guys even have real jobs?  Do their bosses know that they’re spending hours of precious coding time scanning for reputation fodder?

Being a ruminant son of a bitch, I reflected on this for a while, and realized that I do care about my Stack Overflow reputation, and that’s OK, because beside being the best place on the web for software developing questions, Stack Overflow has become a center of excellence.  It is the premier community of software engineers on the internet, and having a good reputation among your peers is always a good thing.

Lately I’ve been posting more answers because I’ve decided that, good or bad, answers always help everyone.  Even if they’re bad or incorrect, they are a learning experience for both me and everyone else that sees how the community reacts to them.  It’s like a class that you really want to learn from; good students understand that in order to learn, they need to pay attention and put themselves out there, both by asking and answering questions.  And the brilliance of the site’s underlying mechanisms is that you are rewarded for putting yourself out there.  Every now and then I’ll hit the site and notice that my reputation has been bumped up by ten points because someone up-voted something I posted months ago.  That’s really frickin’ cool, if you ask me.

So, I say kudos to Spolsky and Atwood for designing a site that has become such a powerful community.  And even if my reputation sucks, I’ll still be reading, asking, answering, and ultimately, learning.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:  
Categories:   Around the Web
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed