Archive for the ‘Uncategorized’ Category
Being new to the world of NServiceBus, I just thought I’d share a few gotcha’s as I experience them.
When everything’s up and running there’s no easy way to see what’s going on as messages appear and disappear from the normal message queue very quickly. You can use an audit queue to log all messages appearing on a queue. To do this, in your app config you simply need to use the ForwardReceivedMessagesTo attribute, like so:
NServiceBus won’t automatically create an audit queue, so when you do so manually.
You can do this in code using:
Alternatively, you can create it using the admin interface, but you need to ensure it has the same settings and permissions as the NServiceBus queues. Notably, that SYSTEM has permissions on the queue, and that it is transactional (if your queue is) – otherwise your audit queue will remain empty!
Running MsDeploy is awesome for automated deployments of websites, but it’s also possible to use it to deploy other applications to the file system – such as associated windows services. You just need to jump through a few more hoops to get things up and running.
I’m using TeamCity for our integration server, but the basic steps will work regardless of the system you are using. I tend to set up TeamCity to have a general “Build entire solution” configuration. This builds the entire project in release mode, and performs any config transformations you need (check out my post here if you to transform app.config files for your service).
Next, for each component and configuration we want to deploy (ie website to staging, website to production, services to staging, services to production), I create a new build configuration, with a dependency on the “build entire solution” configuration. This means we can assume that the build has completed successfully.
After the build, there’s a few steps that need to complete:
- Stop the existing service and uninstall it
- Copy over the output from the build to the target deployment server
- Install the new service and start it
Stopping and starting the services
For the first and last steps, we can define two simple batch files for each, with a hard coded path of where we’ll install the service on the target server.
net stop MyServiceName
C:\Windows\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe /u /name=MyServiceName “C:\Program Files\PathTo\MyServiceName.exe”
C:\Windows\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe /name=MyServiceName "C:\Program Files\PathTo\MyServiceName.exe"
net start MyServiceName
These should be saved in source control as part of your project resources (I put them in a Deploy folder), and so accessible from the build server. These are very basic at the moment – they could equally be PowerShell scripts doing far more complicated things or accepting configurable parameters – but this will do us for our example scenario!
We will use MsDeploy’s preSync and postSync commands to execute these batch files before and after it performs the synchronization on the file system.
Let’s now take a look at the MsDeploy command needed:
"tools/deploy/msdeploy.exe" -verb:sync -preSync:runCommand="%system.teamcity.build.checkoutDir%\tools\deploy\MyServiceName.PreSync.cmd",waitInterval=30000 -source:dirPath="%system.teamcity.build.checkoutDir%\src\MyServiceName\bin\%env.Configuration%" -dest:computerName=https://stagingserver:8172/msdeploy.axd?site=DummyWebSiteName,userName=%env.UserName%,password=%env.Password%,authType=basic,dirPath="C:\Program Files\MyWindowsService\" -allowUntrusted -postSync:runCommand="%system.teamcity.build.checkoutDir%\tools\Deploy\CodeConversion-PostSyncCommand.cmd",waitInterval=30000
Let’s just break this down:
- verb:sync – we are syncing!
- preSync:runCommand – before we perform the deployment, we can pass the path to a batch file that will be streamed to the deployment server and executed. By default, this will be run under a restricted local service account (“The WMSvc uses a Local Service SID account that has fewer privileges than the Local Service account itself.” – from MSDN).
- source:dirPath – this sets the path we want to copy files from. We’re using a parametrized build template in TeamCity to pass in the full path to the source directory, and the current configuration)
- dest:computerName – this is actually several parameters combined. I tried various permutations, and this is what worked best for me. I’m not using NTLM authentication here (so authType=basic) because my staging and production servers are on an external network. The username and password are for an IIS Management Service user that we’ll set up in a minute (and are also parametrized by TeamCity – but you could hard code them here).
- allowUntrusted – allows MsDeploy to accept the unsigned certificate from our target server. You don’t need this if you’re using an SSL certificate from a trusted authority.
- postSync:runCommand – the command we run after a successful deployment.
There’s one gotcha with the preSync and postSync operations at the moment – any error codes returned by preSync or postSync (such as being unable to install the service or start it), the whole MsDeploy action still return success. I haven’t found a nice way round this yet – you’d have to write some powershell script to parse the output and detect errors. Microsoft know about the issue so hopefully it will be fixed in the next release.
Before we try and run this command, we need to set up a few things on the target server we are deploying to. I’m assuming you’re already using MsDeploy to deploy websites, and so you can already see IIS Management Service, IIS Manager Permissions, IIS Manager Users, and Management Service Delegation appearing as options under “Management” in your main IIS server configuration screen.
- Create a new IIS user from the IIS Manager Users screen. Alternatively, you can create a Windows user and use that instead.
- Even though we’re installing a service, we still need a target IIS website to associate our credentials with. This could be a dedicated empty website (it doesn’t need to be running) or an existing one. Make sure you replace “DummyWebSiteName” in the command above with the name of the actual website you choose. The underlying path doesn’t matter, as we override the target path as part of our MsDeploy command.
- Go into “IIS Manager Permissions” for the dummy website you are using, click “Allow user” and select either the IIS or Windows user you created above.
- Next, go into “Management Service Delegation”. We need to create two permissions – one so we can deploy the files to the file system, and another so we can run the pre/post sync commands. For the first, click “Add Rule”, select “Blank Rule” and then type “contentPath” in the providers field, * in the actions, set the Path to the one where you are going to deploy the service to. Save that, and add another blank rule.
- For this second rule, type “runCommand” in the providers field, “*” in actions, and choose “SpecificUser” under the Run As… Identity Type field. We need to run under elevated permissions in order to stop/start services and install them. Choose a user account that has these credentials.
File and user account permissions
In order for everything to work, we need to ensure that MsDeploy can access the folder we’re deploying to. We also need to extend the Local Service account so that it can impersonate a more elevated user in order to run the console commands necessary to stop/start and install services (note there are security implications for this – see MSDN for more details.).
- Add read/write access to Local Service account to the target deployment folder
- Run the following command on the console
sc privs wmsvc SeChangeNotifyPrivilege/SeImpersonatePrivilege/SeAssignPrimaryTokenPrivilege/SeIncreaseQuotaPrivilege
- Finally, you need to restart the Web Management Service for this to take effect.
If all has been set up correctly, you should now be all good to go – services will automatically deploy and get started!
In a similar fashion to when deploying websites, you may find you wish to preserve logging folders and similar during deployment. You can do this by adding some additional parameters to the MsDeploy command. For instance:
will preserve any files in the Logs directory.
Common error messages & troubleshooting
When starting out with MsDeploy it’s likely you’ll hit a fair number of permission denied errors – without too much more information. Logging is your friend.
Request logging - enabled through the Management Service configuration window in IIS, you will find requests logged to %SystemDrive%\Inetpub\logs\WMSvc
Failed request tracing – enabled through the Management Service Delegation configuration window, click “Edit Feature Settings” and “Enable failed request tracing logs”. You will find these at C:\inetpub\logs\wmsvc\TracingLogFiles\W3SVC1
Web Management Service Tracing - enabled through a registry key, described on MSDN.
Below I’ve included some common error messages and some possible causes.
“Connected to the destination computer (“xyz”) using the Web Management Service, but could not authorize. Make sure that you are using the correct user name and password, that the site you are connecting to exists, and that the credentials represent a user who has permissions to access the site.”
Probably because the username and password you are using are invalid (they haven’t been set up) or do not have permissions set for the particular “dummy” website you are targeting.
“Could not complete an operation with the specified provider (“runCommand”) when connecting using the Web Management Service. This can occur if the server administrator has not authorized the user for this operation.”
Most likely you have not set up the correct delegated services through the Management Service Delegation window – either no runCommand permissions have been set, or the delegated user doesn’t have permissions to run the command.
Could not complete an operation with the specified provider (“dirPath”) when connecting using the Web Management Service. This can occur if the server administrator has not authorized the user for this operation.
Either you haven’t set the dirPath permissions via the Management Service Delegation window, or the Local Service account does not have read/write access to the specified directory.
This occurred for me if you haven’t given the Web Management Service permissions to impersonate another user using the
sc privs described above, or you have, but haven’t restarted the service yet.
Info: Updating runCommand. Warning: Access is denied. Warning: The process ‘C:\Windows\system32\cmd.exe’ (command line ‘/c “C:\Windows\ServiceProfiles\LocalService\AppData\Local\Temp\giz2t0kb.0ay.cmd”‘) exited with code ’0×1′.
This occurred for me if I had set the Management Service Delegation for runCommand, but left the service running as it’s built-in identity rather than “RunAs”… “Specific user”.
I hope this helps someone!
Just a quick note – if you switch from Community Server to WordPress like I have, in order to keep your links working you can add a simple regex rewrite rule to IIS. I simply used the following:
where /james_crowley/ was where my blog was installed previously (on weblogs.asp.net as it happens).
Having been caught out by this issue once again this weekend, I thought I’d better blog about it so I don’t scratch my head searching around again for a third time!
If you’ve been getting some wierd “Cannot use a leading .. to exit above the top directory.” exceptions occuring on your site (you *do* log those, don’t you?), that you can’t reproduce in the browser, stay tuned. The issue crops up with URL Rewriting in .NET 2 SP1 – and the reason I’ve hit this again is when our production server was upgraded to .NET 3.5… evidentally this installed the service pack as a side-effect. So much for our patching strategy.
Anyway, this triggered a flow of errors for “Cannot use a leading .. to exit above the top directory.”, all stemming back to a call to System.Web.Util.UrlPath.ReduceVirtualPath – but apparently only for particular visitors to the site – specifically search engine bots, including Googlebot. The issue occurs, as far as I understand, because .NET is specifically targeting code to particular browsers – in this case, I believe the issue results because it knows the user-agent doesn’t support cookies, and is therefore trying to work accordingly.
There are two workarounds out there.
1. In your web.config,add the following:
<forms cookieless="UseCookies" />
2. Create a .browser file to match the user agents that are causing the issue. Check out this article that describes how.
protected override void OnInit(EventArgs e)
// we use this so that we can set the enableViewState property in the web.config
// although it sets it at the page level, it doesn’t pass it on to the master page
this.EnableViewState = this.Page.EnableViewState;
This announcement is well overdue, but better late than never!
After much hard work by the DPE team at Microsoft in the UK – thanks in particular go out to Clare – we’ve now integrated the Developer Fusion events feed with the Microsoft UK community pages. This means that anyone who submits a Microsoft technology-related event to Developer Fusion will also automatically appear on the MSDN and TechNet community pages too – talk about some great free exposure!
Any events on Developer Fusion also get automatically posted to Upcoming.
I’m also working with the larger user groups in the UK to ensure we can automatically pull in their events through the same feed format. If anyone would like more info on this, just get in touch.
For those of you foolhardy enough to be running Vista x64 (myself included!), VS 2008, and the latest build of the ADO.NET Entities framework… you may well hit the following error message:
The specified metadata path is not valid. A valid path must be either an existing directory, an existing file with extension ‘.csdl’, ‘.ssdl’, or ‘.msl’, or a URI that identifies an embedded resource.The catch is that apparently the designers are not supported on 64-bit machines. The workaround is to copy two files from %windir%Microsoft.NETFramework64v3.5 to %windir%Microsoft.NETFrameworkv3.5:
then restart Visual Studio and rebuild your solution.
Thanks to Tommy Williams @ MSFT (found on the forums)
Since getting a shiny new machine running Vista, I’d been having a bit of grief trying to get it to print to my Canon i6500 printer shared through another Windows XP machine. Vista has built-in support for the printer (running locally), but when trying to add it across a network, as the XP machine could not supply the correct 64bit Vista drivers, the Vista machine wasn’t too happy – pointing to the correct location of the local device drivers didn’t help either!
After sifting through various solutions – this was the one that worked for me.
On the Vista machine,
- Choose to add a local printer
- Create a new local port, and set its name so it matches the network share (\servername)
- Manually select the appropriate printer driver from the automatically supported set (or select an appropriate vista driver)
This then tricks Vista into thinking we have a local printer – so it can install the correct drivers – that actually redirects to the network printer.
I think this should work in the reverse direction too, if Windows XP is geting upset printing to a device shared through Vista.
Hope this helps someone!
There’s so many great events coming up all around the UK at the moment – and best of all, they’re free. If you haven’t tried one yet, check out the UK developer event listings to find one near you. Here are just a few
Wednesday, 10 October 2007, 19:00 – 21:00 in Glasgow, United Kingdom. FREE (Scottish Developers)
Jim Paterson describes the key features of db4o, and shows how to save objects in the database, use the db4o query mechanisms, control transactions and object activation, refactor databases, replicate data to a relational database and use db4o in a web app. You will also find out about extensive the developer resources provided by the db4o community.
Friday, 12 October 2007,10:00 – 14:00 in London,United Kingdom. FREE! (Content and Code)
Discover the multitude of solutions offered by a Microsoft® SharePoint® Server 2007 platform. Enjoy interactive breakout demonstrations as well as a buffet lunch. Demonstrations will focus on: data capture, enterprise content management, document management, search, forms server as well as business intelligence, dashboards and KPIs.
Monday, 15 October 2007, 19:00 – 21:00 in Birmingham, United Kingdom. Free to members. Non members can attend 2 meetings FOC. (NxtGenUG)
Intrepid Explorer Liam Westley takes a trip back in time as he dives into Windows and looks at developing Windows Services. Remember those? Well, in case you hadn’t noticed they’re all around us in the development world, but hard to see and hard to capture with a debugger! Liam shows us how we can make our lives easier when writing and working with Windows Services including some of the differences between NT and Windows Vista Services. Other gigantic things to see on the night : Pizza-o-sa…
Tuesday, 16 October 2007, 18:00 – 21:20 in Edinburgh, United Kingdom. FREE (Microsoft)
Come along and find out what’s in store for both the ASP.NET platform and Visual Studio in the upcoming release. As web developers, there’s a lot to get excited about including many features you can take advantage of in your existing projects.
Thursday, 18 October 2007, 09:00 – 13:00 in Bradford, United Kingdom. FREE (Black Marble)
Black Marble present a seminar on SQL2008 with an Introduction for
IT Managers. This outlines the change in emphasis from “words and
numbers” to “sights and sounds”
Future of Web Apps have a run a great set of events in both the US and the UK - and there’s one coming up in London on Oct 3-5. Just to give you a taster, there are speakers from
Not bad eh? Even better – Developer Fusion has organised a 20% discount off the full ticket price, which brings the two day conference pass down to less than £200. Give me a shout too if you’re going to attend – I’m planning to make it.