torsdag, januari 21, 2010
Deploying applications to Windows and Windows Phones which supports dynamic modules
Many .Net applications being developed today are leveraging the greatness of dependency injection using some sort of inversion of control-container. So do we at RemoteX when we develop the product called RemoteX Applications. The product has two client applications which roughly adresses the same use cases. One is targeting desktop computers and the other one is targeting Windows Phone (you can read more here and here).
As you can tell by the name, the product consists of several applications (or rather modules). Using frameworks like Prism or Caliburn we can, in code, easily manage each part of the product. And the deployment is taken care of using ClickOnce technology using mage.exe (the MAnifest GEnerator).
But that's for the desktop client targeting WPF.
So the big question is, how are we going mobile with this?
What regards an inversion of control-container we are "almost there". We have a home-grown container in place which have been around for a while now, even though it lacks some basic features you would expect an ioc container of year MMX to have.
Speaking of deployment to the Windows Phone you probably know you are kind of locked to using CABinet files. If you are using the tools Microsoft brought to us, you probably also use their Device Setup projects in Visual Studio.
They are good, but you must use Visual Studio to choose the contents of and create/build your CAB file.
What this basically means is that we need to use devenv.exe to build each customer's customized CAB file.
So up til now we have not had per customer customized CAB files.
All I wanted was ClickOnce technology and a manifest generator for the Windows Phone. So what's the solution on that?
Say hello to the PowerShell script New-CabWizInf.ps1:
.\New-CabWizInf.ps1 -path .\myapp.inf -appName "My Application" -manufacturer "RemoteX" -fromDirectory .\MyApplication\bin\Release
It works like mage.exe with its -fromDirectory switch and creates the necessary .inf-file (like an Visual Studio Device Setup project would). All needed from that point is to call CABWIZ.exe and Set-AuthenticodeSignature in PowerShell to create and sign the CAB file.
The real power is the -fromDirectory switch which allows us to create custom CAB files on the fly.
So here is a peek of what our setup package scripts now looks like:
Setup Package for Windows using ClickOnce
mage -new deployment -tofile MyApp.application -fromdirectory bin\Release -name "My App" -publisher "RemoteX"
mage -sign
Setup Package for Windows Phones using CAB files
.\New-CabWizInf.ps1 -path MyApp.inf -fromDirectory bin\Release -appName "My App" -manufacturer "RemoteX"
cabwiz MyApp.inf /dest .\
Set-AuthenticodeSignature .\MyApp.CAB
So right now I'm a very happy camper since our packaging tools for Windows AND Windows Phone have equal capabilities which allows us to use dependency injection with dynamic module selection.
Next stop, Prism and Silverlight for the Windows Phone?
As you can tell by the name, the product consists of several applications (or rather modules). Using frameworks like Prism or Caliburn we can, in code, easily manage each part of the product. And the deployment is taken care of using ClickOnce technology using mage.exe (the MAnifest GEnerator).
But that's for the desktop client targeting WPF.
So the big question is, how are we going mobile with this?
What regards an inversion of control-container we are "almost there". We have a home-grown container in place which have been around for a while now, even though it lacks some basic features you would expect an ioc container of year MMX to have.
Speaking of deployment to the Windows Phone you probably know you are kind of locked to using CABinet files. If you are using the tools Microsoft brought to us, you probably also use their Device Setup projects in Visual Studio.
They are good, but you must use Visual Studio to choose the contents of and create/build your CAB file.
What this basically means is that we need to use devenv.exe to build each customer's customized CAB file.
So up til now we have not had per customer customized CAB files.
All I wanted was ClickOnce technology and a manifest generator for the Windows Phone. So what's the solution on that?
Say hello to the PowerShell script New-CabWizInf.ps1:
.\New-CabWizInf.ps1 -path .\myapp.inf -appName "My Application" -manufacturer "RemoteX" -fromDirectory .\MyApplication\bin\Release
It works like mage.exe with its -fromDirectory switch and creates the necessary .inf-file (like an Visual Studio Device Setup project would). All needed from that point is to call CABWIZ.exe and Set-AuthenticodeSignature in PowerShell to create and sign the CAB file.
The real power is the -fromDirectory switch which allows us to create custom CAB files on the fly.
So here is a peek of what our setup package scripts now looks like:
Setup Package for Windows using ClickOnce
mage -new deployment -tofile MyApp.application -fromdirectory bin\Release -name "My App" -publisher "RemoteX"
mage -sign
Setup Package for Windows Phones using CAB files
.\New-CabWizInf.ps1 -path MyApp.inf -fromDirectory bin\Release -appName "My App" -manufacturer "RemoteX"
cabwiz MyApp.inf /dest .\
Set-AuthenticodeSignature .\MyApp.CAB
So right now I'm a very happy camper since our packaging tools for Windows AND Windows Phone have equal capabilities which allows us to use dependency injection with dynamic module selection.
Next stop, Prism and Silverlight for the Windows Phone?
Etiketter: .net, ioc, netcf, remotex, scripting, software, windows mobile
torsdag, november 19, 2009
How to get $VerbosePreference applied on remote commands
If you use Write-Verbose in a script executed on a remote computer, you may not get the result you expect.
The above will only output "hello" and not "there" in the host window.
I thought I was clever by just passing along the $VerbosePreference value:
But, still no luck! Only the statement using Write-Host is included in the output when the command is invoked on the remote computer.
What's going on here is that the argument sent to the remotely executed script block is converted to an integer, which is the base integral type of the underlying enum type of $VerbosePreference.
So I figured that typing the argument in the param() clause will bind the parameter to the correct data type, and voila, it now works as expected.
Now you can toggle the verbose output of your remote script using the switch of your local script:
Example TestRemoteCommand.ps1:
The above will only output "hello" and not "there" in the host window.
I thought I was clever by just passing along the $VerbosePreference value:
But, still no luck! Only the statement using Write-Host is included in the output when the command is invoked on the remote computer.
What's going on here is that the argument sent to the remotely executed script block is converted to an integer, which is the base integral type of the underlying enum type of $VerbosePreference.
So I figured that typing the argument in the param() clause will bind the parameter to the correct data type, and voila, it now works as expected.
Now you can toggle the verbose output of your remote script using the switch of your local script:
Etiketter: powershell, winrm
onsdag, november 18, 2009
Enable-PSRemoting is broken in PowerShell?
Yesterday I installed the RTM bits of WinRM 2.0 on a Windows Server 2003 machine and it were really no issues at all getting it working.
Today I tried to do the same thing but on a Windows 2008 Server (R1) that is not joined to any domain, and it fail on step 1 of the configuration.
In both cases I started out downloading the patch. Then I run "Enable-PSRemoting" in an elevated PowerShell prompt, which succeeded on the Windows 2003 Server but not on the Windows 2008 Server.
The error I got was "Access denied".
I thought I followed the troubleshooting guide for WinRM, but apparently there is slight difference of two different ways I found on how you set this up. You can either run "Enable-PSRemoting" or you can run "winrm qc". If I run the quick config tool using the "winrm" command everything works out just fine, but if I use "Enable-PSRemoting" I get "Access denied".
The most mysterious part of this is that "Enable-PSRemoting" WORKED on Windows Server 2003, but not on Windows Server 2008. Strange!
If you have any clues about this, please leave me a comment!
Etiketter: powershell, troubleshooting, winrm
tisdag, november 17, 2009
Note to self: If you get error code 12250 from ISA server 2006...
"Error Code: 403 Forbidden. ISA Server is configured to block HTTP requests that require authentication. (12250)"
Everything works from and to the protected networks but traffic from the external network is blocked with the error response above.
Solution: Stop using the darn "Publish web site" wizard and copy already existing stuff :)
-or- make sure that the "Allow client authentication over HTTP" check box is checked.
Found at the HTTP Listener properties - Authentication tab, click Advanced.
Etiketter: http, isaserver, troubleshooting
torsdag, november 12, 2009
Swedish Alt.Net UG Coding Dojo at Avega, Stockholm
Yesterday I was at my very first Coding Dojo with my fellow collegues Morten and Sebastian. I was somewhat nervous before this event. Coding in group is not an every day occasion for me :). But it went very well and I can only concur on what Morten blogged about.
Adding to that I must say it were so popular that we needed to split up into two conference rooms. Each room was equipped with a projector, a decent table with room enough for about 15 people.
However, even though we split up into two teams (that focused on the same Kata, see link in Morten's post), we were just too many people around the table. I'm not sure about the exact head count but I guess we ended up with about 9 or 10 people. The most disappointing thing was that one guy was "rolling his own private solution" on his machine during the session. No hard feelings though; I believe this is a sign that we had too many participants in each group.
Worth to say is that each rotation was time limited to 4 minutes with a break of 15 seconds. That means each 4 minutes you rotate around the table and the next person takes the keyboard and continues where the last person left off. The person to the left of the person at the keyboard is the navigator in the pair.
Really nice experience and very nice and bright people in the user group! Thanks Avega (especially Joakim Sundén and his collegues) for hosting the meeting at their office here in Stockholm.
Today I couldn't resist thinking of how we could do this internally at work (we're 6 persons writing code at RemoteX so it seems to be just too perfect). Oh, so much cool code to write, so little time. :)
Etiketter: alt.net, codingdojo, programming, social, testing
onsdag, november 11, 2009
Pimping PsUnit with constraint based assertions
Using PsUnit one can set up scripted "unit tests" for PowerShell scripts. I have sort of just started using PsUnit at work and right now I feel that a lot of the basic features of other test frameworks are missing.
PsUnit has one function for doing constraint based assertions. This may be familar to those who are using NUnit. Basically the syntax for this is:
Using NUnit and this constraint based model, a simple assertion can look like this:
I quite don't like the "barebone" scriptblock you need to write to use Assert-That in PsUnit, so here is what I came up with (using my example of above):
I also added another constraint which allows you to assert that some code throws something:
This complements the already built-in feature of PsUnit which allows you to add a parameter, $ExpectedException, to the test. If you have been using MSTest you would use the method attribute ExpectedException for this.
Here is another example which tweaks the constraint to a somewhat more specific type of exception:
A more usable test using the ThrowsException constraint could be:
The biggest improvement using these new constraints is the output in the test result.
While using PsUnit out-of-the-box...
...results with "Assert-That returned false!" in the test result.
Using the constraint in this blog post...:
...results with "ActualValue 'bar' is not equal to expected value 'foo'".
The same level of detail is provided by the ThrowsException constraint, which may result in "No exception was thrown, expected exception of type 'System.ArgumentException'".
Any ideas, suggestions etc.? Please don't hesitate to drop a comment!
Using NUnit and this constraint based model, a simple assertion can look like this:
I quite don't like the "barebone" scriptblock you need to write to use Assert-That in PsUnit, so here is what I came up with (using my example of above):
I also added another constraint which allows you to assert that some code throws something:
This complements the already built-in feature of PsUnit which allows you to add a parameter, $ExpectedException, to the test. If you have been using MSTest you would use the method attribute ExpectedException for this.
Here is another example which tweaks the constraint to a somewhat more specific type of exception:
A more usable test using the ThrowsException constraint could be:
The biggest improvement using these new constraints is the output in the test result.
While using PsUnit out-of-the-box...
...results with "Assert-That returned false!" in the test result.
Using the constraint in this blog post...:
...results with "ActualValue 'bar' is not equal to expected value 'foo'".
The same level of detail is provided by the ThrowsException constraint, which may result in "No exception was thrown, expected exception of type 'System.ArgumentException'".
Any ideas, suggestions etc.? Please don't hesitate to drop a comment!
Etiketter: powershell, scripting, testing
Integrating PsUnit and MSBuild
The last month I have been digging into, adding new and refactoring the Powershell scripts we use in RemoteX Applications. We primarily use PowerShell to configure and deploy our product.
Using this batch target, all that needs to be done is to add PsUnitTest items to the build script. Just like the way we set up TestContainer items for use with MSTest:
So far so good, but when tests are failing, the build is successful. This is because the Exec task only reports a build error when the executed command returns an exit code other than zero (0x0). So I started looking into the test runner of PsUnit (PsUnit.Run.ps1) and discovered that it didn't send any output nor produced some other exit code than 0x0. The only output PsUnit will send you is some nice colorful information written to the PowerShell host.
This makes PsUnit.Run.ps1 send the test results along the pipeline.
This makes the Exec task report a build error if we find any failing test in the test result from PsUnit - and last but not least - the name of the failing test and the reason ends up nicely in the MSBuild log file.
More often or too many times - with our latest releases - our fellow collegues at Customer Operations have been telling us "The xyz powershell script doesn't work anymore, what have you done to it???"
I could have answered: "- We don't have automated tests on those scripts, so what do you expect? Manual testing? Pfffff...", but for obvious reasons I didn't :).
So it was time to add some automated tests for those scripts so I could get this guy at Customer Operations back to work.
All compiled code (C#) is automatically tested in our Continuous Integration builds when someone checks in, but until now we haven't had automated tests for our PowerShell scripts. With "automated" I mean that a test runner executes a test suite during a build.
In order to test our PowerShell scripts I have started using PsUnit. Since we are using Team Foundation Server and MSBuild for our CI builds, I needed to integrate PsUnit with MSBuild somehow.
There are several ways to invoke Powershell from an MSBuild script - we have chosen the Exec task which invokes powershell.exe.
First of all I created a separate build target which invokes PsUnit:
Using this batch target, all that needs to be done is to add PsUnitTest items to the build script. Just like the way we set up TestContainer items for use with MSTest:
So far so good, but when tests are failing, the build is successful. This is because the Exec task only reports a build error when the executed command returns an exit code other than zero (0x0). So I started looking into the test runner of PsUnit (PsUnit.Run.ps1) and discovered that it didn't send any output nor produced some other exit code than 0x0. The only output PsUnit will send you is some nice colorful information written to the PowerShell host.
So I ended up with the following:
1. this tiny tweak at the end of PsUnit.Run.ps1:
This makes PsUnit.Run.ps1 send the test results along the pipeline.
2. A small wrapper for the test runner which returns some exit code other than 0x0 to the Exec task in MSBuild:
This makes the Exec task report a build error if we find any failing test in the test result from PsUnit - and last but not least - the name of the failing test and the reason ends up nicely in the MSBuild log file.
So now when somebody checks in a change to compiled code, which affects the result of our setup scripts, we will be able to detect errors ASAP! Yay!
Etiketter: msbuild, powershell, scripting, testing
måndag, november 09, 2009
Yay, PowerShell v2 is finally RTMed!
PowerShell v2 is finally RTMed for the rest of us who still has a couple of boxes not running Windows 2008 Server R2 or Windows 7.
Etiketter: powershell
Prenumerera på Inlägg [Atom]



