Announcing poshrunner.exe so MyScript.ps1 can use MyScript.ps1.config instead of powershell.exe.config

I have a tendency to do odd things with technology so that things don’t just work. When I point out the obscure edge cases I find, most people tell me, “well don’t do that.” I usually ignore them and dream of tilting windmills. Well today a windmill has been tilted, and this is the epic tale.

I’m a developer that fell in love with PowerShell. As such I often call .NET API functions from powershell scripts. This usually just works. However, it kind of falls apart when you have to use settings in the app.config file. This means its basically impossible call functions from a DLL that use NHibernate, Entity Framework or WCF Service references. (However, WCF Services can be called direcctly from PowerShell quite easily)

The solution is to run the PowerShell script in a new PowerShell Runspace in a second AppDomain that uses its own app.config. However, things quickly fall apart because you need to write three classes that inherit from PSHostRawUserInterface, PSHostUserInterface and PSHost respectively or else Write-Host will throw an exception.

Now all this is a lot scarier than it sounds. However, it stops two important groups of people from ever using PowerShell to call DLLs that absolutely require you to manipulate your app.config:

  • People scared off by the word AppDomain
  • People that realize they have better things to do than everything I described above

Lucky for these two groups of people, I wasted my time so they didn’t have to! The project is currently called AppDomainPoshRunner, and I ILMerge it (via IL-Repack) into poshrunner.exe. Right now poshrunner takes one command line argument, the path to a script. If the script exists it will run it in an AppDomain whose config file is scriptname.config. Log4net configuration is read from a file called ADPR.log4net.config in the same directory as poshrunner.config.

The full background is to long and convoluted for this post. This was all born out of a problem with calling New-WebServiceProxy twice in the same PowerShell console. I use log4net to write the console messages so this has the potential to be quite extendable. Then Stan needed to run PowerShell scripts from msbuild and was complaining to me about it over twitter. He didn’t like the hacky solution I had then. Eventually I realized this was the way to simplify my previous solution.

So download the zip file. Try it out. Complain to me when you find bugs!

TLDR; Unlike powershell.exe -file foo.ps1, which uses the shared powershell.exe.config, poshrunner.exe foo.ps1 uses foo.ps1.config, for great justice. Download it now!

Visual Studio 2010 and TFS Hosting

Yesterday, Stan, the founder of this blog, gave me a link to a project host on the Team Foundation Service (visual I tried to connect to it with Visual Studio 2010. it simply refused to work.

Visual Studio Add TFS Server Error

After much annoyance, he asked me to try adding the TFS server to Visual Studio 2012 and it worked (Why didn’t I think of that?). Eventually I figured out that I needed to install the Visual Studio 2010 SP1 Team Foundation Server 2012 Compatibility GDR (KB2662296). Then I was able to add the solution to Visual Studio 2010. It seems there are several updates for Visual Studio 2010 SP1, some specifically dealing with Windows 8 compatibility. Unfortunately Windows update does not prompt me to install them. I will search for and install these tonight to prevent future issues.

Windows Internals Study Group – First meeting

Last night myself and two others had out first planning meeting via google huddle for our Windows Internals Study group. We will be meeting next Wednesday 2012-11-17 at 20:30 EST to discuss the first two chapters of Windows Internals 6th edition. If you still want to participate its not too late, just let me know.

One thing we decided was to make all our notes public. Right now they are being stored in a google drive shared folder that is publicly accessible. The information there will grow with time.

My ConEmu Tasks

Update: Thanks to the author of ConEmu for some constructive feedback in the comments!

I’ve fallen in love with ConEmu, after being introduced to it by a Scott Hanselman blog post. While my initial attraction to it was its integration with farmanager, that was only its initial selling point. The ability to have one resizable tabbed window to hold all my cmd.exe, powershell.exe and bash.exe consoles is what makes it a killer app.

While 90% of my command line needs are met by a vanilla powershell.exe or far.exe command line, sometimes I need my environment set up in another way. For example, sometimes I need the vcvarsall.bat run that sets the environment up for a particular version of Visual Studio or the Windows SDK. Also, on occasion I will need to fire up the mingw bash instance that comes with git. (Generally, this is only to run sshkeygen.exe). Finally, while a 64 bit instance of PowerShell 3.0 captures 99% of my PowerShell needs, I want easy access to both 32 and 64 bit versions of the PowerShell 1.0, 2.0 and 3.0 environments.

So I set all these up in ConEmu, and exported the registry keys into a gist repository, and now I share them here as a pastebin (because githup lacks syntax highlighting):

Breakdown of settings

All the settings are stored in subkeys of HKEY_CURRENT_USER\Software\ConEmu\.Vanilla\Tasks with the name TaskN where N is a base 10 integer. In addition, that key has a DWORD value named Count that contains the number of tasks.

Each task contains the following key/value pairs:

  • Name This is the name of the task
  • GuiArgs These are the ConEmu configuration options. In all my cases I use /single /Dir %userprofile%. The /single flag adds the task to the currently open ConEmu instance, if there is one. The /Dir %userprofile% switch sets the working directory to my home directory.
  • CmdN These are the commands executed. Each one represents a command executed in a new tab by a task. All the tasks I have configured execute exactly one tab.
  • CountThis is the number of tabs opened by this command. Like the TaskN keys, it should match up to the number CmdN Values in a Task.
  • Active I set this to zero, but if you have a task that open multiple tabs you can set this to the tab number you want activated after running that task. For example, If you have a task with a Cmd1 that opens mongod.exe, and a Cmd2 that opens up an instance of tail.exe tailing the mongo logs, setting Active to 2 will display the console running the tail.

ConEmu’s true power is your ability to customize it, so by showing you how I customized it, I hope you have found it to be more powerful.