Scott Hanselman

Managing Multiple Configuration File Environments with Pre-Build Events

September 21, 2007 Comment on this post [35] Posted in ASP.NET | Musings | Programming
Sponsored By

ScottGu mentioned an idea to me last week that he'd had for managing configuration files like web.config depending on what the current build config is. Bil Simser mentioned one part of this in January and Rob Chartier offered batch file help on a mailing list in June. Since ScottGu is busy Managing Generally (he IS the General Manager) so I said I'd prove the concept for him.

Here's the general idea. It's not too hard. I'll use an ASP.NET Web Site and web.config as an example, but this will work with most any kind of project, exe's or .dll's.

1. From Visual Studio, go File | New Project, and select ASP.NET Web Application.
Note: Do NOT "New Web Site" as we want a .csproj and we're going to use a Pre-Build Event, not supported by Web Sites. I've named mine FooFoo.

New Project (2)

2. Right click in the Toolbars and ensure that the "Standard" toolbar is showing. You'll know if you see a dropdown that says "Debug" next to one that says "Any CPU."

Click the dropdown and select "Configuration Manager."

image

You'll probably have Debug and Release configurations, but you can also make custom ones and base them on existing configuration. In this dialog I've made a new "Deploy" and I'll base it on the "Release" configuration.

WindowClipping (8)

Make sure to create a Solution Configuration AND a Project Configuration, as they are different. Here I've made one called Deploy for the Project also. If you get an error message, be aware of the "Create new project configurations" checkbox. You might get a warning if you are making a new configuration and the dialog tries to make another configuration with the same name; uncheck the checkbox if that happens.

deploy

Of course, you can have as many Configurations as you'd like.

3. Add some custom configuration stuff in web.config, like connectionStrings:

<connectionStrings>
    <add name="Foo"
         connectionString="Data Source=localhost;Initial Catalog=DatabaseName;
                           User Id=sa;Password=debug;"
         providerName="System.Data.SqlClient" />
</connectionStrings>

See now I've made the password in my nonsense connectionString = "debug"? Now, create three new web.config's by CTRL-dragging the web.config on top of the project. Name them web.config.debug, web.config.deploy, and web.config.release. Make the password equal to "deploy" and "release" respectively.

WindowClipping (6)

4. Ok,  now we've got different configuration and different configuration files. Let's create a batch file called "copyifnewer.bat" and here's the contents:

@echo off
echo Comparing two files: %1 with %2

if not exist %1 goto File1NotFound
if not exist %2 goto File2NotFound

fc %1 %2 
if %ERRORLEVEL%==0 GOTO NoCopy

echo Files are not the same.  Copying %1 over %2
copy %1 %2 /y & goto END

:NoCopy
echo Files are the same.  Did nothing
goto END

:File1NotFound
echo %1 not found.
goto END

:File2NotFound
copy %1 %2 /y
goto END

:END
echo Done.

Basically this batch file will copy a file over another if the files don't match. It's not strictly "copyifnewer" (like, not at all) but it does the job.

Why bother with a batch file to check for changes and not just copy over the file every time? Well, each time you copy over a web.config it restarts all the designers and running AppDomains that are watching that file. No need to copy over a file if it hasn't changed...everything will churn less.

Put this copyifnewer.bat file in the root of your project.

WindowClipping (10)

Why not use PowerShell? One word - speed. Batch files are fast. Full stop. This is a build, so it needs to be fast.

5. Create a Pre-build Event. Right-click on your Project and select Properties. Click Build Events and in the "Pre-build event command line" and enter this value:

"$(ProjectDir)copyifnewer.bat" "$(ProjectDir)web.config.$(ConfigurationName)" "$(ProjectDir)web.config"

 Notice the magic dust, the $(ConfigurationName) project variable, that contains "Debug" or "Release" or "Deploy."

WindowClipping (9)

6. Build. Now if you build, you'll see in the Build Output the batch file being run and the files being copied. Because it's a Pre-Build Event it'll be seen in both the Build Output in Visual Studio .NET. 

When you build within Visual Studio the currently selected item in the drop-down list is the current configuration.

image

The configuration value can also be passed in on the command line when building with MSBUILD. 

msbuild FooFoo.sln /p:Configuration=Deploy

 Administrator Visual Studio 2008 Beta 2 Command Prompt

And there you go. The connection string in the web.config now contains deployment-specific configuration data.

<connectionStrings configSource="separateConnStrings.config"/>

Bad things are that you've got to keep web.config's in sync if there's lots of settings, but you could totally break it apart via "include files."

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

The Nuclear Option: Resetting The Crap Out Of Your Network Adapters in Vista

September 21, 2007 Comment on this post [7] Posted in Musings
Sponsored By

I was having a number of strange network issues on a laptop today. Here's the complete nuclear option for resetting your whole IP stack. This is for when "Diagnose and Repair" isn't cutting it. Thanks to JohnP for his help.

  • Go to the Start Menu, type cmd and right click, and select "Run As Administrator"
  • Type the following commands, each followed by pressing enter.
    • ipconfig /flushdns
    • nbtstat -R
    • nbtstat -RR
    • netsh int reset all
    • netsh int ip reset
    • netsh winsock reset

UPDATE: On Windows 7, you'll need to do this to reset your network adapters:

  • ipconfig /flushdns
  • nbtstat -R
  • nbtstat -RR
  • netsh int reset all
  • netsh int ipv4 reset
  • netsh int ipv6 reset
  • netsh winsock reset

Now, reboot and pray. Possibly not in that order.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

The Mystery of the Failed Live Meeting Launch

September 19, 2007 Comment on this post [21] Posted in Bugs | Musings | Tools
Sponsored By

I've got to attend my first Microsoft Live Meeting in the morning, and since I'm remote I thought I'd just run the quick test of the Live Meeting Client before bed. You know, you visit a test page with your browser, and a Live Meeting client "jumps out" of the browser and connects. I've done it a million times before.

I open the Calendar Meeting, click, and...I get a dialog titled:

"RTC Router" - "The directory name is invalid"

Of course, I try it at least 10 times to make sure it's REALLY not working. You never know, it could work that 9th try, right?

OK. Now I'm getting tense. I need this to work, the LiveMeeting is in the morning. Um, reinstall, ok...just reinstall.

Microsoft has an internal website that you download all the corporate IT products you need for your regular job. I go back up in IE, am prompted for my Microsoft domain account and password (this machine isn't on the domain), find the right page, download the MSI and run the installation in place. OK. Whew. I go back open the Calendar Meeting, click, and...I still get a dialog titled:

"RTC Router" - "The directory name is invalid"

Crap. Ok, it's Procmon time. Who owns this dialog box? I give the dialog a good shake while Task Manager is open. That's a low-tech way of answering the Who's Process Is This question - grab a dialog with the mouse and shake it around the screen...the process that owns it will start using a little bit of CPU.

It's RunDll32.exe. That's a generic process that runs Procedures directly within DLLs. Basically a LoadLibrary()|GetProcAddress() command-line interface.

Now, I set the filters in Procmon to just watch two processes - iexplore.exe and rundll32.exe. I then reproduce the issue and watch the logs.

RunDll32

OK, looks like this is being called when I click the link in IE:

C:\Windows\system32\rundll32.exe "C:\Program Files (x86)\Common Files\Microsoft Shared\LiveMeeting Shared\RtcRouter.dll",RouteMIME %1

It's being launched because of the mime/type of the file being returned from the web server. The registry says that there's a .rtc and .rtc-ms extension of type "Microsoft.RTC.ConnectionFile."

Registry Editor

The Set Associations Dialog in Vista confirms it.

Set Associations

So, this RunDll32 RtcRouter.dll action is the "Microsoft Office Live Meeting Router." RTC is probably Real Time Communication, but at this point I don't care.

Now, I reproduce the failure again and look for the "Live Meeting" string.

MoreRegistry

This run shows three things that are important. First the very top shows the writing to a log file called pwconsole-debug30.txt...it contains just this:

[MC] 08:55:50:031 GMT [PID 9228] [THREAD 4996]  [I] RTCRouter - RouteMIME called
[MC] 08:55:50:033 GMT [PID 9228] [THREAD 4996]  [W] RTCRouter - Inserting for HKLM - {69CEBEF8-52AA-4436-A3C9-684AF57B0307}
[MC] 08:55:50:042 GMT [PID 9228] [THREAD 4996]  [W] RTCRouter - Using Target Product code : {69CEBEF8-52AA-4436-A3C9-684AF57B0307}
[MC] 08:55:50:043 GMT [PID 9228] [THREAD 4996]  [E] RTCRouter - Error launching console

Ah, but the second thing in Procmon that jives with this long is the GUID which is apparently a Microsoft Installer Product Code leading to a Component which is the LiveMeeting Console.

Notice the Access Denied in reading the PWConsole.exe. Ok, so this is a permissions issue.

I head down into C:\Program Files (x86)\Microsoft Office\Live Meeting 8 and get ACCESS DENIED! What? I can't even go into my own folder? I JUST made this folder when I ran that installer.

Hm. OK, I'm Administrator, so I'm taking over ownership. I open an Administrator cmd.exe and from within that folder, run:

takeown /f "Live Meeting 8" /r /a
SUCCESS: The file (or folder) is now owned by user QUADPOWER\scott

That'll teach you. Now, I took ownership, but I still need permissions, so I go into Properties, Security, and I'm sure to go into Advanced|Edit|Edit and select "Replace all existing permissions" as I want to make sure I'm taking control of the entire directory and all files, not just one directory and forgetting to recurse.

Console

NOTE:  I'm just reporting my experience here, be careful when you do crazy stuff as Administrator and don't come to me when it all blows up for you. YMMV. Seriously.

I immediately notice something I didn't see before...the PWConsole NOW has an icon. I had a generic one before. AH. I've got permissions. And by I, I mean, explorer.exe.

Console (4)

Cool, now I go back into Outlook, click on the Live Meeting Test Link, and I'm in:

Microsoft Office Live Meeting - livemeeting.com - Live Meeting 2007 Console Test

Conclusion

How did I get myself into this situation? Here's my working theory.

  1. When I’m remoted into Corporate authenticated as, say, MICROSOFT\mrscott on my home computer that
    1. doesn’t have a machine account
    2. and where MICROSOFT\mrscott is a temporary identity (it’s not admin, and it’s just hanging out launching some processes, and not others) and
    3. I run installations with that domain authenticated identity via direct launching from Internet Explorer
  2. THEN:
    1. those installations run as MICROSOFT\mrscott the whole time and regular LOCALMACHINE\scott can’t access them, resulting in chaos and confusion, directories and files created and owned by an account that isn't on this machine. Oh, and it results in blog posts like this.

Is this something others might be having trouble with and who should be told?  Or, is this totally obvious and easily discoverable?

Of course! Just don’t run MSI installers launched directly from a Intranet website when you're domain authenticated against that site as someone who doesn't have administrator privileges on the local machine. <sarcasm>It's so obvious!</sarcasm> Well, actually, stated like that, it does make sense. I can't add my domain account as an Administrator on this machine without joining the box to the domain, which I don't want to do. So, I'll download my installers from the internal sites and then run them from now on.

Good night!

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

DeskSpace - Beryl-like 3D Cube Virtual Desktop Manager for Vista

September 18, 2007 Comment on this post [23] Posted in Reviews | Tools
Sponsored By

Oh HELL ya. My buddy James at OtakuSoftware has done it again with DeskSpace. You remember him from TopDesk fame. He's back and it's insane.

UPDATE: I talked to the author, James, and he points out (and in the comments also) that he bought Yod'm a while back. It's posted in his forums also, so it's common knowledge I missed. However, DeskSpace is NOT a repackaging of Yod'm (I can attest to that, since I've been beta testing it for weeks) but rather the Next Version. The 3D Desktop code is an enhanced version of TopDesk, only the options dialog remains of Yod'm. The shared heritage was posted on DeskSpace for a while (Google Cache). It's all clear to me now. Sorry if I misrepresented things, it was only due to my own ignorance. It is a sweet app, though.

It's a Beryl-like 3D Cube Virtual Desktop App. I can talk about it all day, but a video (captured from my own computer) is worth a thousand words. What a great tool with a pile of configurable options. I've been running it across three monitors for about two weeks and it is surprisingly useful.

Go. Get. It.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

PNP Summit 2007 - One of these things doesn't belong

September 18, 2007 Comment on this post [43] Posted in Microsoft | Speaking
Sponsored By

This November 5-9, I'll be playing the famous Sesame Street children's game "One of These Things Is Not Like The Others" at the Patterns & Practices Summit on the Microsoft Campus.

Let's play now together, shall we?

The next patterns & practices Summit takes place November 5 - 9 in the Kodiak Room at the Microsoft Conference Center at Microsoft's main campus in Redmond, Washington.

Keynote presentations by:
Anders Hejlsberg, Steve McConnell, Scott Guthrie, Scott Hanselman, & John Lam

OK, seriously. Anders? Steve FREAKING McConnell? (He's literally changed his middle name to FREAKING just for this blog post.) Scott "My Boss's Boss" Guthrie? Family Friend and IronRuby Wonk Dr. John Lam?

SusanthesethingsIs it the head tilt that makes me odd man out? Possibly. Perhaps the "senior class photo" use of sepia tone? Maybe. The giant fore-fivehead? No comment there, lets just say I am hair-plug and hairpiece free as of the time this writing.

Perhaps the fact that I've never created a programming language? Or several. Possibly never written a genre-changing book? Or several. Possibly that I've never shipped or managed the shipping of a Microsoft Product? Or several. Or, maybe because I haven't got a PhD in biochemistry? Oh. What have I gotten myself into? The humanity!

I can only assume I was invited in the "Ze Frank" sense of invited, to provide social commentary and wit. Of course, lacking both, I need your help, Dear Reader. Which of these presentation ideas that I've been kicking around should I do?

Brainstorming Topic Ideas
  • It's Not That Scary - Remember that you do in fact know .NET 2.0 and even though 3.0 and 3.5 seem scary, we have the tools and knowledge it'll take to pick up these complementary technologies quickly.
  • MVC ASP.NET Frameworks - Why things like Monorail and the new MVC ASP.NET Framework from DevDiv should matter to Developers
  • ALT.NET - What is the ALT.NET movement and why should the average developer coding on .NET care?
  • Free VS2008 3rd Party Tools - The best of the 3rd party free utilties and tools, created by the community, that make Orcas just that much more fun to develop on.
  • LINQ in a Larger Context - How does LINQ fit into n-tier software development and OO design patterns? Does it help or hinder, pervert or promote good coding?
  • The Importance of Being IIS7 - Why IIS7 should be on the minds of developers, not just IT guys. How hard should developers push their tech leads and bosses to look at IIS7 and why will it make their lives easier?
  • Improving Your Sense of Code Smell - C# 3.0 and VB9 bring dozens of new programmatic idioms, many of which that are unfamiliar. How can we "update" our sense of code smell and know when an old familiar pattern needs a breath of fresh Anonymous Types or Explicit Conversion Operators?
  • Passion for the Craft - How does one find balance between being the best coder they can be and being the best everything else? Can everything get done at work and you still punch out at 5:01pm? What role does passion play in the life of the .NET developer?
  • The Coming Dynamic Storm (or Language Storm) - As C# 3.0 gains dynamic-like features, the DLR and no less than a dozen new dynamic language implementations from LISP to SmallTalk, Nemerle to Boo, and IronRuby to IronPython are coming into their own, not to mention F#. Is there room for 12 awesome .NET CLR-based languages? What does this mean for the C# and VB developer?
  • Mitigating the Angle Bracket Tax with LINQ to XML - Folks using XML need to take a hard look at System.Xml.Linq and their powerful bridge classes. LINQ is wonderful, we know, but the XElement and XDocument classes - independent of LINQ - provide a fresh new perspective on what working with XML should look like.
  • REST for the Rest of Us - Wait a minute? I thought WS-Security and WS-* were the future? Now WCF supports REST? Which is it and what does it mean to the developer on the front line?
  • Post RTM Tooling - What new Free Add-Ins to VS.NET 2008 will be available (around Jan/Feb) post RTM to handle interesting niche cases (like the WPF-based Visual XSD Designer) and other coolness?

At any rate, I encourage you to sign up to attend the pnpSummit. At least four of the five keynotes is likely to be quite good!

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.