|
Monday, August 16, 2010
In Part 1 I hadn’t decided if I was going to use Web Deploy as the base of this blog series or the PowerShell scripts I already had in production. I decided to give Web Deploy a chance. In the end I didn’t regret it, but I must admit it was not straight forward. Hopefully this post will make it a breeze for you  THE commands The two commands below solves all the requirements I listed in my previous post. I spent a great deal of time learning and studying Web Deploy in order to come up with this, so I hope you find it useful. It might not look too hard now, but nothing is when you have the solution in front of you I’m always open for better ways if you find one though. If I could ask the Web Deploy team for a new feature, it would be to make the two commands below really simple. The rest of this post will discuss these commands in detail. Text in blue can be replaced with your own values. Create package: msdeploy.exe
-verb:sync
-source:manifest=PackageManifest.xml
-dest:package=Package.zip,encryptPassword="certificatePassword"
-enableLink:AppPoolExtension
-disableLink:CertificateExtension
-disableLink:ContentExtension
-replace:objectName=httpCert,targetAttributeName=hash,replace=08bf3e051bd10cd8d89ac1a3ac431887886ed343
-replace:objectName=logFile,targetAttributeName=directory,replace=C:\Web\Logs
-replace:objectName=virtualDirectory,targetAttributeName=physicalPath,match="C:\\WebDeployTemplateWebSites",replace="C:\Web"
-declareParam:name=HttpsBinding,kind=DestinationBinding,scope=webSiteName,match=.*:443:
-declareParam:name=HttpBinding,kind=DestinationBinding,scope=webSiteName,match=.*:80:
-declareParam:name=AppPoolUsername,kind=DeploymentObjectAttribute,scope=processModel,match=processModel/@userName
-declareParam:name=AppPoolPassword,kind=DeploymentObjectAttribute,scope=processModel,match=processModel/@password
Install package:
msdeploy.exe
-verb:sync
-source:package=Package.zip,encryptPassword="certificatePassword"
-dest:manifest=InstallManifest.xml,computerName=FQDN,username="domain\user",password="domainUserPassword"
-setParam:name=HttpsBinding,value=10.0.0.21:443:
-setParam:name=HttpBinding,value=10.0.0.21:80:
-setParam:name=AppPoolUsername,value=MyDomain\AppPoolServiceAccount
-setParam:name=AppPoolPassword,value=MySecureAppPoolPassword
Note that the above commands are one-liners. I only structured them the way I did to make them readable.
Complex
Web Deploy was built for the purpose of deploying web applications, so at first it looked like the perfect solution. However, I soon realized I had to study it in great detail to make it do what I wanted. I’m talking days not hours. Time I was not eager to spend to replace something already working or just for the sake of this blog post (sorry guys ). The reason for not giving up on it entirely was because Web Deploy had the potential to simplify/replace my scripts, have fewer moving parts, and make the total solution easier to maintain.
Around the same time as I published Part 1 I tweeted my concern about Web Deploy’s complexity and the @wdeploy team contacted me. I sent them a long email describing my concerns and they promised to do “creative things in the future” to make it less complex. I’ve been in contact several times after that and they are very responsive and eager to get feedback on the product. I’m personally looking forward to see (and maybe help influence) how this product will evolve.
Web Deploy Command Options
Before diving into the inner workings of these commands, we need to know a bit more about the tool. Web Deploy have a lot of functionality and is extremely powerful. Here’s the command line syntax:
msdeploy.exe -verb:<verbName>
-source:<provider>[=<pathToProviderObject>
[,<providerSetting>=<providerSettingValue>]]
[-dest:<provider>[=<pathToProviderObject>
[,<providerSetting>=<providerSettingValue>]]
]
[-<MSDeployOperationSetting> ...]
Doesn’t look too scary right? There is more to it though…
Verbs
The following verbs exist:
- delete
- dump
- getDependencies
- getParameters
- getSystemInfo
- sync
Providers
Let’s look at which providers it has:
These are of course only the built-in providers, then you can create your own or use 3rd party ones if you like. A quick scan through this list shows that it does a lot more that just web stuff, like COM objects, registry settings, certificates, gac, databases.. the lot.
Provider Settings
The providers again have a set of common provider settings:
- authType
- computerName
- encryptPassword
- getCredentials
- ignoreErrors
- includeAcls
- password
- storeCredentials
- tempAgent
- userName
- wmsvc
MSDeployOperationSetting
From the documentation:
Web Deploy operation settings are non-provider specific command-line flags. They modify all of a Web Deploy operation.
- allowUntrusted
- declareParam
- declareParamFile
- dest
- disableLink
- disableRule
- disableSkipDirective
- enableLink
- enableRule
- enableSkipDirective
- postSync
- preSync
- removeParam
- replace
- retryAttempts
- retryInterval
- setParam
- setParamFile
- showSecure
- skip
- source
- useCheckSum
- verb
- verbose
- whatif
- xml
- xpath
Manifest Provider
We now have an overview of the command line syntax of the tool, but there are a few other important aspects. The first one being the manifest provider. Most likely you want to use more than one provider in your command, and that’s exactly what this provider does. Here’s an example from the documentation:
<sitemanifest>
<appHostConfig path="mySite" />
<gacAssembly path="System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<comObject path="Microsoft.ApplicationHost.AdminManager" />
<contentPath path="c:\source" />
<regKey path="HKLM\Software\ODBC" />
</sitemanifest>
I would actually preferred having these on the command line instead. When I trigger my commands from a build, I’m inserting variables into the command anyways and I would be better of with the ONE command and not have to maintain the xml files as well. Actually I would like to have both options. In the command I would suggest something like this (which would adhere to the existing conventions):
-source:appHostConfig=mySite,gacAssembly=System.Web…,[…]=[…]
Link Extensions
Another one is the concept of link extensions, which can be enabled/disabled by using the enableLink and disableLink operations. One example drawn from the documentation is:
…if you specify -disableLink:ContentExtension on the command line, you can prevent content from being included in a sync operation. This enables you to synchronize two Web servers without moving any content.
Web Deploy Rules
Web Deploy rules exists to disable or enable built-in or custom rules (using e.g. the enableRule and disableRule operations) for the sync verb. This is however (naturally) only true if the isDefault attribute is set to true in the rule definitions. See here to find the built-in rules. By creating the file Msdeploy.exe.configsettings in %program files%\IIS\Microsoft Web Deploy folder, you can add custom rules.
Packages and Archives
From the docs:
The Web Deploy package and archiveDir features let you create a snapshot backup of your Web site or Web server into a .zip file or archive directory. In addition, the parameterization and manifest features let you customize the archive or package that you create. You can then use your package files to deploy Web sites and Web servers to other computers or computer locations.
What’s wrong?
That’s a lot of stuff to consume! In order to effectively use this tool for deployment, you have to learn most of these verbs, providers and operations, figure out how they work and how you can take advantage of them.
This is (in my opinion) what Greg Young have been talking about and expressed in the NDC Magazine article Failure (well worth the read), where the intent is lost in the system and the user is forced to “reverse engineer” it to make sense of it all.
I’m fully aware of the endless amount of user scenarios that exists, and I don’t expect the Web Deploy team to cover them all, but the most common ones would be nice. Like the one I’m showing in this post I would think would be quite common for auto deployment scenarios. The advanced configuration could still be available for the not-so-common scenarios. Instead I’m “forced” to spend a lot of time learning the inner workings of a complicated tool, which in the end create a lot of value. How valuable wouldn’t it be if I didn’t have to invest so much time in learning the tool?
I’m also aware of the new TFS 2010 integration that exists, which simplifies many of these tasks, but that solution lacks documentation and the advanced options are hard to get at.
Setting up Web Deploy for remote access
To be able to access a server remotely, Web Deploy must be given access to the server. Several options are available, but I’ll focus on the Web Deployment Agent Service, which requires administrator privileges to use.
The Agent Service requires Web Deploy to be installed on the target server. You can find the detailed installation instructions here: http://technet.microsoft.com/en-us/library/dd569030(WS.10).aspx
Basic Usage
Let’s look at some vanilla examples for deploying web stuff remotely:
msdeploy
-verb:sync
-source:contentpath=c:\data,
-dest:contentpath=c:\data,
computerName=Server2,
username=admin,
password=pass
This copies your local C:\data directory to the server Server2, and provide a username and password to get access to the remote server. This is done by using the sync verb and the contentpath provider. So we can push files, which is nice cause we don’t have to use FTP, BITS or similar.
Deployment Requirements
We want to do a lot more than just copy files. Here’s a list extracted from my previous post of what I want to deploy to remote servers:
- File content
- Virtual Directories and Applications settings
- AppPools settings
- Certificates
- Bindings
- Log location settings
- Virtual Directory file location settings
Packaging structure
My commands can be used to produce one package per web site multiplied by the number of environments you have (e.g. Dev, Test and Prod). So if you have 4 web sites and 3 environments, you create 12 packages.
To better understand why this is, here’s a list of the settings that are specific for each environment and common across all servers in one specific environment:
- File content
- SSL Certificate password
- Certificate hash/thumbprint
- Web site log directory location
- Virtual directory root locations
For server specific differences we create the package so that it accepts parameters for:
- User and password for the service account under which the worker process of the Application Pools runs
- The https binding (if used)
- The http binding (if used)
If we did not define the last three parameters, we would have to multiply the packages with the amount of servers in the different environments as well. 4 web sites, 3 environments and 2 servers in each environment = 24 packages. You don’t want to go there…
Another option would be to define all possible changes as parameters, leaving you with only one package. I tried that. I could not figure out how to accomplish all of these using params, so I analyzed what I needed and used a little of both. It works, but could be better.
As an example of the above, a package for the web site blog.torresdal.net could be created for e.g. Dev with these settings:
- File content = E:\MyBuildOutput\blog.torresdal.net
- Certificate password = MySecureSSLPassword
- Certificate hash=08bf3e051bd10cd8d89ac1a3ac431887886ed343
- Web site log dir = E:\Logs\blog.torresdal.net
- Virtual Directory locations = E:\Web
…and used these parameters when deploying:
- Username for AppPool = MyDomain\AppPoolServiceAccount
- Password for AppPool = MySecureAppPoolPassword
- Https binding = 10.0.0.21:443:
- Http binding = 10.0.0.21:80:
Notes on Application Pool
Note on bindings: You have to use either http or https or both. If you want to use hostname you could do: *:80:blog.torresdal.net
Note that host names are not supported on SSL in IIS 7, even though it’s technically possible to do.
Note on the service account for the application pool: On Windows Server 2008, IIS support Application Pool Identities. These are Windows virtual accounts that are assigned to the application pool effectively isolating it from other services. If you want to use these, then you don’t have to declare the parameters for the app pool identities as long as your source is using App Pool Id’s.
Dissecting The Create Package Command
I believe you now have an idea of what the commands above do, but lets pull it apart and describe each piece by itself.
The package manifest file
First we’re going to look at the manifest file which contains all source providers used to create the package:
<sitemanifest>
<appHostConfig path="blog.torresdal.net" />
<cert path="my\08bf3e051bd10cd8d89ac1a3ac431887886ed343 " />
<dirPath path="E:\MyBuildDrop\LatestVersion\Dev\blog.torresdal.net" />
</sitemanifest>
This is the way that Web Deploy allows you to use more than one provider. Here’s a short description of each provider and what it does:
| appHostConfig |
Gets all IIS specific settings from a web site. |
| cert |
Gets the certificate with the given thumbprint/hash. |
| dirPath |
Gets the content from the given path. |
The create Package command
Now lets look at each section of the command:
| -verb:sync |
Tells Web Deploy to do a sync |
| -source:manifest=PackageManifest.xml |
Points to the manifest file showed above containing all providers to use as source. |
-dest:package=Package.zip,
encryptPassword="certificatePassword" |
Use the package provider as destination for creating a package (zip) containing all content and information needed to deploy a package to a server. Since we’re using the cert provider (in the manifest) we need to provide the password to get access to the certificate. |
| -enableLink:AppPoolExtension |
I want the application pool to be synced as well. |
| -disableLink:CertificateExtension |
The appHostConfig provider include certificate and content by default. I want to control which certificate and what content to include, so I use –disableLink to disable these extensions. That is why I’ve added the cert and dirPath providers in the manifest so that I can be explicit about these. |
| -disableLink:ContentExtension |
See previous… |
-replace:objectName=httpCert,
targetAttributeName=hash,
replace=08bf3e051bd10cd… |
The appHostProvider and the cert provider are unaware of each others actions, so the appHostProvider outputs the thumbprint from the certificate found in IIS. I need to replace the httpCert hash property with the same hash used in the manifest file or else the web site would be bounded to the wrong certificate. |
-replace:objectName=logFile,
targetAttributeName=directory,
replace=C:\Web\Logs |
I want to replace the IIS log directory to a different path than the IIS I’m exporting from. |
-replace:objectName=virtualDirectory,
targetAttributeName=physicalPath,
match="C:\\WebDeployMasterWebSites",
replace="C:\Web" |
The web site I’m exporting from reside in C:\WebDeployMasterWebSites\{webSiteName}, and all Virtual Directories are located below this path. I want to control the root path, so I replace it.
Note: This would be a natural candidate for a parameter, but with params you can only replace the complete value, not just part of it. |
Here’s a description of the parameter declarations allowing us to pass in params when deployment the package (these are also part of the same command):
-declareParam:name=HttpsBinding,
kind=DestinationBinding,
scope=webSiteName,
match=.*:443: |
I want to control the SSL binding for the web site. |
-declareParam:name=HttpBinding,
kind=DestinationBinding,
scope=webSiteName,
match=.*:80: |
Same as above only for HTTP. |
-declareParam:name=AppPoolUsername,
kind=DeploymentObjectAttribute,
scope=processModel,
match=processModel/@userName |
I want to set the user name of the account under which the worker process of the Application Pools runs |
-declareParam:name=AppPoolPassword,
kind=DeploymentObjectAttribute,
scope=processModel,
match=processModel/@password |
Same as above only for the password. |
To shorten the above command a tiny bit you can define the parameters in an xml file instead, like this:
<parameters>
<parameter name="HttpsBinding" description="Web Site Binding for SSL">
<parameterEntry kind="DestinationBinding" scope="sikker.frende.no" match=".*:443:" />
</parameter>
<parameter name="HttpBinding" description="Web Site Binding for http">
<parameterEntry kind="DestinationBinding" scope="sikker.frende.no" match=".*:443:" />
</parameter>
<parameter name="AppPoolUsername" description="Account username for this application pool">
<parameterEntry kind="DeploymentObjectAttribute" scope="processModel" match="processModel/@userName"/>
</parameter>
<parameter name="AppPoolPassword" description="Account password for this application pool">
<parameterEntry kind="DeploymentObjectAttribute" scope="processModel" match="processModel/@password"/>
</parameter>
</parameters>
You will then replace the –declareParam operation settings above with this:
-declareParamFile:MyParamFile.xml
However, if you’re going to execute this command from TFS or some other build tool, you’re better off leaving them inside the command. Less moving parts.
Dissecting The Deploy Package Command
We also need a manifest file when installing the package. This is ALMOST identical to the manifest we used when creating the package:
<sitemanifest>
<appHostConfig path="blog.torresdal.net" />
<cert path="my\08bf3e051bd10cd8d89ac1a3ac431887886ed343 " />
<dirPath path="E:\Web" />
</sitemanifest>
The only difference between the two is in the dirPath provider. For the package we used files from E:\MyBuildDrop\LatestVersion\Dev\blog.torresdal.net, but when deploying we PUT files to E:\Web.
The deployment package command
Each section in detail:
| -verb:sync |
Tells Web Deploy to do a sync |
-source:package=Package.zip,
encryptPassword="certificatePassword" |
Uses the earlier created package as source. Since this package contains a certificate, you need to provide the certificate password in order to get access to it. |
-dest:manifest=InstallManifest.xml,
computerName=FQCN,
username="domain\user",
password="domainUserPassword" |
Points to the manifest file to use for deployment, and to which server we are deploying to with the username/password. |
-setParam:name=HttpsBinding,
value=10.0.0.21:443: |
Set the SSL binding for the web site. Using IP 10.0.0.21 on port 443 (SSL). |
-setParam:name=HttpBinding,
value=10.0.0.21:80: |
Same as above only for HTTP. |
-setParam:name=AppPoolUsername,
value=MyDomain\AppPoolServiceAccount |
Set the user name for the account under which the worker process of the Application Pools runs |
-setParam:name=AppPoolPassword,
value=MySecureAppPoolPassword |
Same as above, only for the password |
The Build/Deploy Process Using Web Deploy
Here’s the exact same deployment process overview as in my previous post, only now with Web Deploy. As a result the process got two steps shorter 
What’s Next?
In my next post I’ll either show you how to control the load balancer during deployment or integration with TFS. Both will be covered in the end.
Thursday, August 05, 2010
Update: Part 2 is now available, covering Web Deploy (a.k.a. msdeploy) Getting code deployed should be as easy as open up a web site (only taking slightly longer ). Devs or IT people should not spend manual labor (with the possibility of mishaps) on getting files from one place to another, making changes to IIS (or whatever you’re using), restarting servers, copy/changing web.config files etc. That’s the job for scripts and automation tools. Not to mention the cost savings of not needing IT people to do deployment. I bet you there’s no one manual step in the process of deployment that cannot be automated. Saying that, you have to consider how many times you deploy per day/week/month or year before going for full automation. However, if you’re serious about being Agile/Lean, you can’t do without a auto deployment scheme. In the coming blog posts I’ll walk you through the steps I went through to automate our deployment, and hopefully you’ll find it interesting and even suggest improvements. Overview Below is an overview of the environments we’re deploying to: One Load Balancer (LB) in each environment, two web servers in Dev and Test, and 3 in Prod. The actual numbers might or might not be true , but that doesn’t really matter. In addition there’s SQL Servers, but I will not cover that here. Why have a LB in Dev? Reason number one is to catch any possible LB issues in Dev before going to Test and Prod, and have the exact same environment in Dev as in Prod. It’s also useful to try out new stuff, like having the LB do caching etc. Deployment Frequency For Dev we auto deploy every night (part of nightly build) and at will during day. For Test, 2-4 times per week and to Prod 1-2 times every 2nd week. That was yesterday! Today we can do it when the sun comes out of the clouds (not often in Bergen), every time I refill my coffee cup or whenever we feel like. The point being: we are no longer constrained by how often we can deploy. Why All These Environments? You can read about that here, but for us: - Dev is where we try out things without physically hurting users, but still being in a real server environment avoiding the “works on my machine” issue.
- Test is as close to Prod as we can get (at external hosting provider, different network, firewalls etc) and where we make sure things run smoothly before going to Prod.
- Prod is Prod
Tech Details Here’s the tech stuff we use which might be relevant: - All servers are running Windows Server 2008 R2
- Web servers are running on IIS 7.5 (since we’re on R2)
- Application Request Routing in IIS is used as Load Balancer and runs on 2008 R2 Server Core (if you like, check out my previous post about setting up and configuring ARR)
- TFS 2010 for builds
- Team City for CI
Also note that we have access to the actual subnet where Test and Prod lives. This does however not mean we have access to all servers and features in all environments, it just means we can be given access to certain things not recommended through external firewalls, like PowerShell Remoting. This is where your environments might be different from ours. Some General Advice Consider Using a LB Even If You Don’t Need One For Performance Reasons Load Balancers are useful for other things than load balancing. The biggest benefit (except from its core task), is that you can do upgrades and maintenance on servers without taking the whole site offline, by always leaving at least one server online. Consider Turning Off IIS Recycling
Do you know that IIS automatically recycle your applications every 1740 minute, effectively restarting them? Are your web sites free from memory leaks or do you want to know if you have memory leaks? Why not turn off recycling? This is too big of a topic to cover here, but go Google: IIS7 recycle. Consider Using Windows Server 2008 R2 Server CORE This should get you slightly better performance, but for me it’s more about scripting. Most of the things that needs to be done on server core, must be performed from command line, forcing you to create scripts. Why Is Deployment Difficult? First of all because every environment is different and there are no really good tools to automate the whole process. The challenge is to find the right tools to solve the problems your organization is facing, and have the tools work for you to get to the final goal. What’s The Challenges? For us it was about: - How can we safely move files from a build server to Dev, Test and Prod?
- How can we automate the process of taking a node out of an LB cluster?
- How can we safely execute an upgrade on a server in Dev, Test or Prod and get feedback of progress, errors, and abort and roll back on failure?
- How can we remotely make changes to IIS?
- How can we avoid all manual tasks? (like adding a virtual directory in IIS or copy a web.config file)
Safety and automation is two keywords that sticks out. Where safe means no-one else than the intended persons or services should be able to perform the specified tasks. Automation meaning no manual operations should ever be needed in either Dev, Test or Prod except from IT maintenance like hardware upgrades, windows update etc. What tool options have we? Copy files: - Secure FTP in IIS 7 on a non public/available IP
- or PowerShell with BITS
- or WebDeploy
Taking LB nodes offline/online: - Use PowerShell Remoting to execute PowerShell scripts on ARR server
- or the Web Farm Framework
Safely execute an upgrade: - Use PowerShell Remoting to execute PowerShell scripts on web servers
- or WebDeploy
Avoid manual tasks: - Script all tasks, so they can be repeated
The Build/Deploy Process
What About MSI’s? If you read my blog you know I’ve done quite a bit of MS Installer stuff and WiX in particular. MSI’s are perfect for deploying to multiple places where you have no control. The drawback is that most developers don’t know how to customize MSI’s and often end up with a versioning problem and leaving lots of old stuff behind on the server after upgrades. If you have people skilled in Windows Installer, please feel free to use MSI, but I personally find XCopy to be very easy and is what I recommend if you’re not an ISV. With MSI’s you still have to install them remotely, which could be done with WMI or PowerShell. Notes on WebDeploy I’m currently looking at using Web Deploy to simplify/reduce the amount of scripts needed. WebDeploy would replace the FTP and deploy steps, but first impression is that it’s too generic, making it really hard to do simple things without spending quite a bit of time learning the tool, it’s underlying package schema and IIS schemas. Hopefully one day Web Deploy will be the only tool I’ll need to execute the whole deployment process. What’s Coming? In future blog posts I’ll walk you through step-by-step how to accomplish the above solution. While I’m writing this I’m not 100% sure if it will be a solution using PowerShell (which I have in production) or a slightly modified version using Web Deploy. It all depends on which one is easiest and which has the potential of being maintained by other people than me in the long run. Hopefully this will give you the input you need to fully automate your deployment process as well.
Tuesday, January 19, 2010
I finally got a setup at work which I’m really satisfied with. The short version: - 3 24-inch monitors (HP LA2405wg with two Display Ports)
- Desktop computer (HP Z600) 2.26gHz with 6 GB RAM running Windows 7 x64 - using 2 of 3 screens
- Laptop (nothing exciting - HP Compaq 6910p with Win 7 x64 – for mobility) – using the 3rd screen
- Synergy to share a single mouse and keyboard between desktop computer and laptop
(the two screens on the left is the desktop computer, the one on the right is the laptop. Couldn’t take a picture further away because I have a wall just behind me ) What’s really nice about this setup is that I don’t really notice I have two computers running, because of the way Synergy “abstract” the other computer away. Setting up Synergy (the long version) - Install Synergy on both computers
- Setup the computer that’s connected to the mouse/keyboard as “server”
- Select “Share this computer’s keyboard and mouse (server)”
- Click Configure…
- Under Screens click + to add a new screen (actually it’s a computer you’re adding and not a screen)
- Set the Screen Name to the name of your computer (yes, it has to be the hostname of your computer in order for Synergy to communicate with other clients) and click OK
- Do the same for the other computers (the clients)
- Under links you set how the screens are in relation to each other (based on my screen setup above):
- Highlight your “server” under Screens
- Under Links ([New Link]) enter:
0 to 100 % of the left of YOUR_CLIENT goes to 0 to 100 % of YOUR_SERVER - Click +
- 0 to 100 % of the right of YOUR_SERVER goes to 0 to 100 % of YOUR_CLIENT
- Note: Synergy does not implicitly understand that if server is left of client, the client is right of server, so you need to define that explicitly, hence #4
- Click OK
- Click Start (consider setting up AutoStart)
On my server it looks like this:
- Setup the client
- On the client computer select “Use another computer’s shared keyboard and mouse (client)
- Enter the name of YOUR_SERVER
- Click Start (consider setting up AutoStart)
- That’s it. Test by moving your mouse from the left most monitor to the right most monitor! Cool!
Sunday, August 23, 2009
Even though I don’t develop software in SharePoint, this blog post by Lee Richardson reflect my thoughts and worries about SharePoint development. The essence of his post is in this paragraph: But the power given to end users makes rigor and good design extremely hard for developers because the production machine you deployed to last month may look completely different now that you’re ready to redeploy. And Microsoft makes good design even harder with an inflexible API. Critical classes like SPSite (think SqlConnection) contain no public constructor, rendering them completely unmockable (unless you’re willing to spend $450 per developer for some TypeMock Isolator magic). And vital classes like SPList (think DataSet) are marked final, crippling your ability to make nice strongly typed entities in your architectures. Lee proposes some techniques to use that you should read in his post, but it’s half baked and not good enough in my opinion. The things he suggests (which is usually taken for granted on any other project) is made really hard to do by MS. Should MS rethink the way SharePoint is architected for the sake of developers to ease maintenance, improve code quality and basically allow developers working with ShapePoint to be craftsmen? Or is the dynamics of the product given to the end user so good that it’s worth all the extra efforts?
Friday, January 09, 2009
If you read my previous article on Amazon Web Services compared to Azure Services Platform you might want to know that Amazon just release a web interface for managing/creating virtual images, manage security, IP’s, ESB etc. For a short demo check out this video: http://media.amazonwebservices.com/console/AwsConsole.html I also have a half finished blog post about how to get started with AWS which I hope to get published soon, so hopefully I’ll get time this weekend. I will then cover the AWS Management Console as well. I also finally got access to Windows Azure, so I plan to do something around that as well. A lot of promises here now, so hopefully that will help me get it done!  Until then, happy clouding!
Saturday, December 20, 2008
Back in April last year I configured Google Apps for my family domain. Email was goal #1, but I also had a plan to start using and sharing Google Calendar with my family. At the time however there was poor tooling support for syncing Outlook with Google Calendar. Since I’m using Outlook as my main source of event planning, it was natural for this to be my primary source with a 2 way sync to Google, so I could share this info with e.g. my wife. I actually started on a small dev project to get this done, but I soon got tired thinking Google or somebody else would create something for this soon. It turns out I was right, only I didn’t pay attention Long story short: in March this year Google released Google Calendar Sync which allow you to do 2-way synchronization between Outlook and Google Calendar. I know this is old news, but it slipped my radar and it might have slipped yours as well…
Tuesday, November 25, 2008
On the DDD mailing list a few days ago Richard Pawson posted that he and his team have created a DDD framework for .Net. Since I’ve had my head down in DDD for the last couple of months I thought I’d check it out. When posting this I’ve still not tried it, but I’ve watched some of the videos which you can find here: http://www.nakedobjects.net/demo/demo_intro.shtml Honestly I’m not sure what I think of DDD frameworks in general. By definition I’m skeptical , but I promise to try it out and come back with some sort of conclusion of my findings and impressions. Btw. I’ve not been approached by Naked Objects to review their product in case you were wondering :)
Sunday, October 26, 2008
Update: My link below was wrong, it's now updated.
A few days ago i published a rather long article on my blog about custom actions in WiX which didn’t show up in Google Reader. Are you using Google Reader to subscribe to my feed and are the WiX article above showing up in you reader? Are you using some other RSS reader and received my post (or not)? I appreciate any feedback you have on this. Thanks. Btw. I’ve tried several other readers and it works fine.
This is my fifth post in my WiX and DTF series. Here are some others I’ve written: After working quite a bit with Custom Actions (CA’s) in managed code I thought it was about time to show how we can debug CA’s. Before DTF it was almost impossible to step into your code written in C++, VB Script or Java Script and debug. With DTF this is simple, but still not 100% intuitive or straight forward. You have two options mentioned in the DTF documentation for debugging your code and a third which is not mentioned: - Use environment variable MMsiBreak (not to be confused with MsiBreak)
- Attach the debugger to the process via a message box
- Use System.Diagnostics.Debugger.Launch
Using MMsiBreak Here’s how to add MMsiBreak to your environment variables in Vista: - Start –> Right click Computer –> Properties (or navigate to Control Panel –> System)
- Select Advanced system settings
- Click Environment Variables…
- In the System variables section click New…
- Set Variable name = MMsiBreak
- Set Variable value = Name of your custom action method
On my computer it looks like this: In my example it will break for debugging when Windows Installer is executing the CA GetWebSites. When that happens you will get the following dialog: Select Yes and you will be prompted to select a debugger to use. If you already have your solution open in VS, you will get the option of using that. Note however that on Vista admin privileges is required, so you need to have your Visual Studio running as admin in order for it to bee listed in the below screen: When I select the running VS (as above I’ve done above) I get something in VS which I can’t quite explain. The first time this happened to me I thought it didn’t work. I get this message: The thing is that the source code is of course already displayed, but I thought there was some problems with loading the symbols. However, if you just click Ok and hit F5 (Start debugging) in VS, your breakpoint will hit. Just a thing to be aware of if you get this. Using Message Box By using a message box you can accomplish the same thing, but this requires changes to your code and a recompile of both your CA project and you WiX project. Personally I prefer the above method, but it’s always nice to have options In order to debug using message box you must: - Make sure you have a reference to System.Windows.Forms.dll.
- Somewhere in your code (where you want to break) add some code for displaying your message box. Something like this:
MessageBox.Show("Please attach a debugger.");
- Add a breakpoint somewhere in your code below your message box code
- Rebuild your CA project as well as you WiX project to get the new changes.
- Run your MSI.
- When the message box displays, go to Tools –> Attach to Process… (Ctrl + Alt + P)
- Find the process named rundll32.exe and attach.
- Click Ok on the message box in you installation.
- The breakpoint you set earlier should now be activated in VS
Using Debugger.Launch()
This is exactly the same as using MMsiBreak except you trigger it from code instead of a environment variable. Just add this line to your code where you want to debug:
System.Diagnostics.Debugger.Launch();
This will give you the same “Unhandled exception” dialog as before and the rest is the same.
The MSI log file
If you’ve been working with MSI’s you know this already, but I think this is something every developer/it-expert should know about and in my experience most people don’t. Sometimes when you run an MSI and get an error that maybe causes a rollback and you can’t get the installation to install, you’re stuck with a cryptic error message. If you’re lucky you can Google it and maybe find the problem (or solution), but often this is not the case. Then this little command might come in handy:
msiexec /i NameOfMSI.msi /l*v C:\Temp\install.log
The above command uses msiexec.exe which is what Windows uses when you double click on an msi. Actually Windows does exactly like the above except from the /l*v part and that’s where you tell msiexec to log to a file. Here’s what it means:
/l = Log
* = Everything
v = Verbose
You can skip the v and you will get slightly smaller log file. Personally I use v all the time.
Thursday, September 04, 2008
This is my first post in my WiX and DTF series for WiX 3.0. Here are some others I’ve written:
Windows Installer XML (WiX) The version of WiX I'm going to talk about is v.3.0, currently in beta. In essence WiX is an XML format for writing MSI deployment packages. Much like using InstallShield or Wise to write your installations, you can use WiX to do the same. So why do you want to use XML to author your msi's? At first I thought: "Ohhh no! Not another XML based authoring tool!" But after doing some more digging, this is one of the scenarios were XML makes sense... kind of. Here's the benefits I see with WiX compared to traditional MSI tools: - It's perfect for "code" generation, using Nant, TFS etc.
- WiX is very clean, so it gives you the possibility to author exactly what you need and not have all the general stuff that IS and Wise has pre added to your installation
Another thing to note is that WiX is open source and it comes from Microsoft (yea, Microsoft HAVE open source projects). Not only that, but this tool got so popular within Microsoft that most of their packages are now moving towards using WiX, and many of them, like Office, already use WiX. That says a lot! I'll get back to using WiX to author msi installations in a later post, but now I want to focus on DTF and how to use it without WiX. Deployment Tools Foundation (DTF) DTF is among other things a managed (.net) wrapper on top of msi.dll (the windows installer library). DTF makes it possible to write custom actions (CA's) for MSI installations in C#, VB.net or any other .Net language. If you're not used to working with MSI installations this might not be a big deal for you, but for me this is fantastic news! Not only that, debugging has now become much easier (or should i say possible). Before you only had three options for writing CA's: C++, VB Script and Java Script. CA's are custom code you write because there are currently no existing action supported by MS Installer that does what you're looking for. Examples of things you can do with Windows Installer out of the box are: - Install/delete/move files
- Create/delete/change folders
- Create/delete/change shortcuts
- Install/remove/start/stop Windows Services
- Reboots
- Install/remove ODBC drivers
- Register/un-register COM/COM+ applications
- Register/un-register fonts
- Write/change registry
- ...and so on...
Check this out for a more complete list. However, Windows Installer can't cover all scenarios, so then you turn to CA's. Here are some examples I've used CA's for: - List SQL Servers
- List IIS Web Sites
- Create Web Sites and Virtual Directories
- Change XML files
You should however know this; writing good CA's is difficult and there is a lot of things to take into account. For instance, what happens if your installation fails and starts rolling back? Then you need to make sure that any changes you've done to the system with your CA also needs to roll back, meaning you have to have two CA's, one for adding stuff and one for removing stuff. Why not just stick to VB/Java script? Using VB and Java scripts has become more and more difficult because of security restrictions, virus programs etc. Many virus programs will not allow you to use Windows Scripting Host (WSH) at all. About 2 months ago I did some work on our existing msi packages related to a Microsoft certification program. The requirements for this certification forced me to adopt the best practices that I should have done a long time ago. To avoid the problem with scripting I had two options. Rewrite my CA's in C++, or in C# using DTF. After digging around it was an easy choice. I went for managed code. However, this might not be the right solution for you. Managed code require the .Net framework, so if you don't know if .Net is present on the computer running your software, you might want to stick to "traditional" CA's. For me this was not a problem, since all computers (clients and servers) we install on already have .Net pre-installed. Next Next time I'll show you how to create a CA for listing available IIS Web Sites on IIS7. This will allow you to choose which web site to install your application under. Until then I suggest you check out WiX/DTF and start thinking if this is something for you.
Tuesday, June 03, 2008
Don't want to download and install all the tools from Sysinternals? Want to have access from anywhere on any computer? Just hook up to the UNC path: \\live.sysinternals.com\tools and you can run them directly. Thanks to John St. Clair for letting me know. Is that cool or what? For more information about the different tools go to http://technet.microsoft.com/sysinternals.
Tuesday, May 27, 2008
Brian Harry over at the TFS team has a great post about the new features that will be available in the coming SP1 for TFS 2008.
Saturday, May 24, 2008
Earlier this month Fredrik Normén wrote a post about argument validation. Yesterday Rune Grothaug from MS Norway posted a link to a new tool MS has developed in their research lab called Pex (Program EXploration). Combining these two (argument validation and Pex) have to be a perfect match.
Thursday, February 21, 2008
Before installing SP1 I could right click anywhere in Windows Explorer and select search to do searches in that folder. After SP1 it's gone! Why? Blame "us" (the Europeans or actually EU). They (I say they, because Norway is not part of EU ) found a "new" game to play with MS. It's called Antitrust and it's about Suits meeting up in in European courts to talk about software. Browsers are especially popular, but sometimes they talk about other types of software as well. The looser of the Game (usually MS) have to become agile and change their software so the Europeans can get their price. This time MS didn't want to play, so they just gave the EU the price. What's the price you might ask? A pluggable search architecture. If you are a provider of a desktop search engine, users can now set your search engine as default search in Windows. So what if I want to have the contextual search like it was? Then you can change a registry key as described here or just use Windows key + F as I do.
Sunday, December 23, 2007
Soon Windows Vista SP1 will be available for download. Or actually, it might even decide to automatically update itself, even though you specifically told it not to! However, not all of us want this to happen without our knowledge (or want to wait until some unexpected behaviors has been discovered), so Microsoft has release a service pack blocker. This blocker will also work for Windows XP and Windows Server 2003. The blocker only work for a set period of time. Mary Jo Foley has more details in her blog.
Wednesday, November 21, 2007
 You probably know allready, but Visual Studio 2008 is now available on MSDN Subscriptions for download. If you don't have an MSDN Subsription I'm afraid you'll have to wait until February 2008...
Monday, November 05, 2007
Sunday, November 04, 2007
Today
I got tired of using my mouse when navigating in Google search results, so I
started to search for Google keyboard shortcuts. I found some tools that added
this to Firefox, but I just couldn't believe there weren’t existing in Google already.
And then I found something at Google Experimental Labs. By clicking  you
convert your Google search to be keyboard sensitive. Nice! Here's how it looks after I've "Joined the experiment":
Here are
the available shortcuts:
| Key | Action |
| J | Selects the next result. |
| K | Selects the previous result. |
| O | Opens the selected result. |
| <Enter> | Opens the selected result. |
| / | Puts the cursor in the search box. |
| <Esc> | Removes the cursor from the search box. |
Saturday, November 03, 2007
On
Wednesday NNUG Bergen was
lucky enough to get Einar
Ingebrigtsen to speak for us. He held a great session about XNA and some
game dev history. Einar did game development for about 8 years and
then jumped to business development. His background was perfect to highlight
some of the similarities between the two. Especially interesting was the similarities
around layering.
Einar is
involved in many things and one of his latest projects is Game Camp. On November 23rd Game
Camp will kick off with a great agenda in Oslo. Go here to check out the agenda and
registration.
Another thing Einar has been doing lately is
creating a 3D engine for Silverlight called Balder. As you may know Silverlight
is a subset of WPF and one of the things they removed was the 3D
stuff. But that didn’t stop him. Check out his 3D project over at CodePlex. To see
the engine in action, check out this
demo.
Wednesday, October 17, 2007
 Are you an estimating guru? Have you never missed an estimate in your life? Can you even do estimates for others? Then this is not for you. However, if you don’t recognize yourself in the previous description this still might be something for you. When I introduced Scrum to my organization, we quickly started to use planning poker. So what’s planning poker? Here’s what planningpoker.com says: "Individual stories are presented for estimation. After a period of discussion, each participant chooses from his own deck the numbered card that represents his estimate of how much work is involved in the story under discussion. All estimates are kept private until each participant has chosen a card. At that time, all estimates are revealed and discussion can begin again."
How we use planning poker in ContikiAt Contiki we use planning poker to estimate all our user stories, or features if you want. When the backlog starts filling up with un-estimated backlog items, we gather the team for a round of poker. We also have a team in Ukraine, so using planningpoker.com works great for us. Here’s what we do step by step: - The product owner reads the user story and adds any additional information he think is necessary. No comments or input is allowed from the others at this time (our experience is that starting the table discussion before the first estimate takes a lot longer and will not make the estimate any better).
- Everyone vote for an estimate.
- When all estimates are in, all estimates are revealed. When we see that the estimates vary (which usually is the case), we ask the person with the lowest and the person with the highest estimate to discuss why they differ. This usually results in highlighting the different perceptions of the user story and helps clarify other aspect previously unknown to the story. The person with the lowest estimate might know something that will make implementation easier or the person with the highest estimate might know some other implications that the other person didn't.
- At this time other people might jump in to add extra knowledge to the story if they think this will help.
- After a short discussion a new voting is started, if not the estimates are very close to each other that is.
- If the estimates are still not the same, pick an average.
- In rare cases we allow a third vote if the team agrees.
Using a team to do the estimates has several advantages: - If one person is doing the estimate, it’s not definite that he’s the person to implementing the functionality, making his estimate less valid. I’ve never understood people doing estimate for others.
- If only one person does the estimate, he estimate is based on his background and his knowledge.
- Having several people with different experience, knowledge and perception to agree on an estimate, usually results in a better result. It will usually help people visualize aspects of a functionality that was previously unknown the one person.
- It’s more fun!
Later I'm thinking of talking about: - The anchoring effect
- Story points vs. days
- Why does planning poker work?
Sunday, September 30, 2007
 I've been waiting a long time for this. I remember this was one of the things with Google Reader I found annoying. A Google product accessing a lot of data and no search support? Anyway, now it's here, and it works as expected :) First thing I noticed was a search that found 500 items, only showed the first 60. Hmmmm..., that was no fun. No paging or anything. But then I noticed it automatically loaded new items when I scrolled to the bottom. Nice!  Another not so new feature is the increased unread counter. Previously, if you had more than 100 unread items it displayed 100+, now it's increased to 1000 and if exceeded will show 1000+.
Monday, August 20, 2007
I've been
using both Install Shield and Wise (Wise Installation Studio) for some time
now and have mixed experience with both, but one thing puzzles me about Wise;
there's no support for Application Pools! The IIS dialog in Wise only has
support for IIS 5 features. I just can't fathom how they can keep releasing new
versions of Wise without supporting IIS 6/7. Are no one using Wise for
deploying web apps, web services etc? Are Install Shield the only choice for
(advanced) plain Msi's?
Back in December 2006 I requested this feature from Wise on their forum and I
got this answer:
“I've run it past the product manager, and
there is no specific timescale for adding application pool support. I know it's
come up once or twice before, but I think the overall demand is not significant
enough to priorities this feature ahead of others.”
On their
website they list key features and one of them is:
“Supports the latest
technologies, including virtual applications and Microsoft Windows Vista.”
Fantastic! But no app pools! Later someone else
requested this feature on my thread and Wise finally added a
link where you can subscribe to this feature request. The more subscribers, the
more attention it gets. Want to help me Wise out? Visit: https://kb.altiris.com/display/1n/articleDirect/index.asp?aid=3066&r=0.7956964 and click subscribe/unsubscribe on the right
side, and hopefully this feature request will get Altiris Symantec's
attention.
Tuesday, July 10, 2007
Update: At TechEd Barcelona Microsoft announced today (2007-11-05) that Visual Studio 2008 and .Net Framework 3.5 will release in late November. See the official press release here: http://www.microsoft.com/presspass/press/2007/nov07/11-05TechEdDevelopersPR.mspx
I’m at the Microsoft Partner Conference in Devner where
Microsoft just announced the release date for Visual Studio 2008, SQL Server
2008 and Windows Server 2008. Look forward to February 27!
Sunday, April 29, 2007
Did you know about this? Have you heard about it before? I
didn’t have a clue before I saw Roy
Osherove blog post. It turns out that this was the perfect solution for me
and my family. I have now integrated my domain (torresdal.net) with Google
email and other nice features of Google Apps. Before I always redirected my domain
email to my work email. Now I can manage my private emails in a separate location,
which is what I really want.
In addition to email there were a couple of other features I
found interesting. My fiancée and I found the Google Calendar really useful.
Finally we had a common calendar which was easy to use and easily accessible.
In addition to those I’ve already mentioned a Start Page, Chat, Web Pages and Docs and Spreadsheets was also included in the service.
So if you have your own custom domain and want
to use Gmail/Chat with yourname@yourdomain.com, Google App’s should be a nice
solution. Not that I’ve tried or looked for anything else, I just tried this service
and found it very useful.
Saturday, March 24, 2007
If
you’ve installed Office 2007 yet, you’re probably aware of the new preview
feature in Outlook. By default all Office attachments can be previewed inside
Outlook. Thanks to Ryan Gregg you can now preview PDF documents as well. Go
check it out!
|
| |
|
|
|
|
| |
| August, 2010 (2) |
| June, 2010 (3) |
| April, 2010 (2) |
| March, 2010 (2) |
| February, 2010 (3) |
| January, 2010 (4) |
| December, 2009 (1) |
| August, 2009 (4) |
| July, 2009 (4) |
| June, 2009 (2) |
| May, 2009 (4) |
| April, 2009 (7) |
| March, 2009 (7) |
| February, 2009 (4) |
| January, 2009 (4) |
| December, 2008 (7) |
| November, 2008 (1) |
| October, 2008 (6) |
| September, 2008 (7) |
| August, 2008 (4) |
| July, 2008 (3) |
| June, 2008 (7) |
| May, 2008 (7) |
| April, 2008 (5) |
| March, 2008 (3) |
| February, 2008 (9) |
| January, 2008 (3) |
| December, 2007 (4) |
| November, 2007 (10) |
| October, 2007 (10) |
| September, 2007 (2) |
| August, 2007 (6) |
| July, 2007 (6) |
| June, 2007 (3) |
| May, 2007 (2) |
| April, 2007 (8) |
| March, 2007 (6) |
| February, 2007 (5) |
| January, 2007 (10) |
| December, 2006 (9) |
| November, 2006 (5) |
| October, 2006 (8) |
| September, 2006 (5) |
|
|
 |
 |
|
|