Sunday, April 13, 2008

Windows Installer, I will defeat you: How to remove files on application uninstall

One man's quest to understand Windows Installer.

As I mentioned in my last post, I am working on a small project that I plan on releasing to the public in 2-3 months. I originally planned on deploying this project using ClickOnce, but that turned out to have a large set of challenges and is a topic for another post. I then changed my deployment strategy to make use of Visual Studio 2008's nice little deployment project builder. While even more challenging than ClickOnce, this strategy was far more flexible, so I've stuck with it. But I quickly found that Windows Installer is one serious beast.

I'll be the first to admit that I knew very little about application deployment before I started playing around with Windows Installer. I had used an older version of InstallShield back when I was a co-op at the company I'm currently employed at, but my experience with that was pretty limited.

But anyway - enough background. This post is entirely about one challenge with Windows Installer - removing files in your application's install directory when your app is uninstalled. I figured this would be pretty easy - and it *sort of* is, but just because something in the end is easy doesn't mean that the road to the end is easy as well. There is no way to configure this behavior from within VS2008's deployment project editor, so what was I to do?

Here is how I ended up solving the problem. First, install Orca. Orca is a small utility that Microsoft distributes with each platform SDK, and the setup can be found under the following path:

(typically Program Files)\Microsoft SDKs\Windows\v6.0A\bin\Orca.msi

Now, build your deployment solution (if you already haven't) from within VS2008. Run Orca. Open your built .msi file. On the left side of the Orca interface you'll see a list view labeled "Tables". Scroll down to 'Remove File'. Click on that, and on the right side of the interface, you'll see a dataview with the following column headers:

FileKey, Component, FileName, DirProperty, InstallMode

Your project most likely already has one entry. We'll use that entry as a mock-up for our file removal entries. This part is tricky - the MSDN documentation on RemoveFile is not particularly clear on how to do this, so I'll show you what I ended up doing.

To remove files in your application's directory, add an entry to the table with a unique name in the FileKey column. I called mine 'RemoveAppFiles'. For the Component column, copy and paste the original entry in the RemoveFile table's Component, since you can be pretty sure that component will be removed on uninstall. The trick to remember here is that an entry in the RemoveFile table will only be executed when the Component ID you use in the Component column is installed or uninstalled (more on this in the next paragraph).

For the FileName column, add a wildcard for the type of files you want removed - say, *.dll. The MSND documentation says any wildcard will work, but in practice, I've found that *.* or * do nothing, so you may end up needing several entries in the RemoveFile table for each file type you want removed. Under the DirProperty column, enter "TARGETDIR" if the files are in the application's directory - most people say to use "INSTALLDIR", but I've found that doesn't work either. And finally, for the InstallMode column, you can enter 3 possible numbers:

1 indicates that Windows Installer should remove this entry's files on component install.
2 indicates that Windows Installer should remove this entry's files on component uninstall.
3 indicates that Windows Installer should do both #1 and #2.

And one final note - if you want to remove the application directory, add yet another entry, but leave the FileName column empty. That tells Windows Installer to delete the directory.

So while this post didn't have anything to do with .NET, this was something that took me awhile to figure out, and if it helps anyone else out there, I'm glad. Good luck!

Saturday, April 12, 2008

An interesting observation

I know Steve has been bugging me to start posting ;-) so I thought I'd start of small with a quick introduction and a small post for tonight. I'm Rob. I am a coworker of Steve.

Moving on - I'm sure everyone has heard a great deal of complaints regarding Windows Vista, so I thought I'd post an observation I made recently regarding memory usage of .NET applications. As you all know, managed applications tend to take up a bit more memory on average than unmanaged, and while the garbage collector does it's job admirably, a smaller memory footprint is always desirable.

So out of curiosity, I ran a small WPF application I've been developing for the past few months on both Windows XP SP2 and Windows Vista SP1. I wasn't all that surprised to see that immediately after startup on XP SP2, my application was taking up ~28MB. Sounded reasonable for what I was doing.

What I was surprised by was the memory usage I saw when running it under Vista SP1 - it was under half as large - only ~13MB. Remember, this is the exact same code as under XP. As far as I know, other than the obvious interaction between WPF and Vista's DWM, WPF in .NET 3.5 is the 'same' WPF under both Vista and XP.

While we've known all along that Vista was meant to be the preferred platform for WPF applications, it was nice to see Vista running my application better than XP can run it.

Wednesday, April 9, 2008

Linq to SQL Setup Problems

I wanted to post this finding that took us a while to figure out and resolve. We are starting to use Linq to SQL in a new project and adding it to an existing Visual Studio setup solution. When this project was added to the setup solution, the project built but it reported a build error in the end. There was no information as to what failed. There was nothing that was reported when we used verbose build option. The setup project just failed. For this project, many things were changed so just removing the new things was not an option. We had other Linq to SQL projects in the solution without a problem and could not understand why this one would make the build fail.

So we turned to the programmer's best friend - Google. Searching for this we found a few cases that were similar.

The only option that seemed to make sense was that there was an issue with the installer project. People have seen this with installer projects that were built in VS2005 and then upgraded to VS2008. One person that had success fixing this rebuilt the installer project using VS2008. The time was taken to rebuild the installer project and it still had problems.

I kept digging into this issue and finally found something to try. All of the other Linq to SQL projects that worked in the setup project were generated using the Linq to SQL template in CodeSmith. This one was just a standard Linq to SQL just generated from the VS2008 IDE. So I converted this project to be generated from the template and things worked. Right after I did this I found this...

It turns out that you can edit the project file for the Linq to SQL and get the setup project to build correctly. This will work until you go back into the designer. Well with new things there are bound to be hiccups. At least if I can share this with others it might be faster to solve their problem.

Friday, April 4, 2008

Unit Testing with Silverlight

Many developers use unit testing to test thru their code, but testing a web based technology like Silverlight is abit trickier. Jeff Wilcox has posted an article on performing unit testing on Silverlight 2.

Tuesday, April 1, 2008

Beta Certification Exams

Microsoft will put out beta exams for new technologies to test out the certification exams and the questions. They do this to see what types of questions to ask in the certification exams. I have taken quite a few beta exams and want to share some ideas around them with others. First, I want to say that the beta exams are hard. There are no books or training courses on the beta exams. You have to be confident in your ability for the exam.

Beta exams are open to anyone that wants to pay the $125 fee. Microsoft does also give out free codes to people so they do not have to pay. Typically the free codes are given to people that have certifications already since they have "proven" themselves to have knowledge in an area. There are also times when Microsoft will email or send out codes to people that have subscribed to the certification email lists.

Ok, on to the questions...

One thing to remember is that there are alot of questions. There are actually more questions on the beta version of an exam then the normal version. This is because the nature of beta exams is to test out the various questions. This means that there are questions that are going to be thrown out. The challenge is that you never know which questions are getting thrown out. You could get all of the questions right that are thrown out, but you could still could fail the beta. The time for the exam is also longer. The last one that I took was scheduled for 4 hours. It did not take me that long to answer the questions, but there is also time to review and comment on the questions as well.

The number for the exam is 71-xxx instead of the normal exam numbers of 70-xxx. Not all testing facilities actually give beta exams. Check your local testing site to see what exams are available. Another thing is that the betas are time limited. There is usually about a month of time to take the exam.

Another big difference with beta exams is that you will not get your results back for 8-10 weeks instead of right away. This is tough when you are used to getting immediate feedback and results. It's a waiting game.

Beta exams are a mixed bag. You don't know exactly what is going to be tested, you will not get the results immediately, and you will spend a long time taking this exam. Good luck on taking beta exams if you want to try them out. I have both passed and failed some. They are tough, but rewarding.

Microsoft Certifications

I have been asked by many people about Microsoft certifications. After I moved back to the city where I went to college, my boss asked me if I wanted to go back to school to get a pHd, or to go for certifications. I picked certifications since they seemed more relevent to my job and where I wanted to go with my career. The first choice that I had was on electives for the certification. I was goingg to pick FrontPage as an elective, but my boss wanted me to go for a SQL Server exam instead. This changed alot of how I viewed databases and how I continued my career.

Enough of my past. Right now I have six Microsoft Certifications. This are both .NET and non-.NET based. Here is the list of the certifications that I have earned in the order that I earned them.

  • MCP

  • MCSD (VC6)

  • MCAD

  • MCTS: SQL Server 2005

  • MCSD (.NET)

  • MCITP: Database Developer

Getting an MCP is pretty easy since you get it automatically when you pass a single exam. Other certifications that I have are not offered anymore. The older VC6 and .NET 1.1 based exams are no longer offered. They have been retired in favor of the newer .NET 2.0 based exams. And Microsoft is now testing newer .NET 3.5 exams (more on this in a later post).

One of the best things that I suggest when getting ready for an exam is to get a couple training books for the exam that you are about to take. I have found that a single book usually does not go over everything that is needed for the exams. That is why I typically use 2 books. Then USE the technology. Make small sample programs, make installers, test things, catch exceptions, USE the technology. There is no good shortcut to this. Microsoft wants to see how well you know the information in the test. Using it helps alot. Did I mention that you should USE the technology?

Now I also have a few suggestions while you take the exams. There are a few formats that the test are in. The first is a typical multiple choice with 4-5 questions and you have to pick one. The second type is a multiple choice where you have to pick 2 or 3 answers. Another type of question is a drag-and-drop type where you organize the answers in the order that you would use them. One last type of question that I have encountered is the case study. This has a large case study to read and then a few questions based on that case study.

For the simple question with 1 or more answers to pick you can usually pull out a few answers that are wrong. For many of these questions you will see that out of the 4 answers they are all similar. Two will have one part of the answer the same and the other answers will have a different answer for them. Then the second part of the answers will be 2 or more other options that are split up a different way. Here is an example of what I mean.

The item is red, and a fruit.
The item is red and a vegetable.
The item is orange and a fruit.
The item is green and a vegetable.

Each of these answers might be valid for something, but if we are looking for an apple, or a bell pepper, then the answer should be obvious. This is just an example on how some answers can be organized. There are no fruit and/or vegetable questions on the exams ;-)

For the questions where you have to organize things in a certain order you might not have to use all of the possible answers. Make sure to read the question to make sure that you know what is being asked. If asked how to create a blog post, some of the possible answers for this type of question could be like this.

Spell-check your post
Pick a topic
Publish the post
Log onto your blog
Write the post
Submit your post to Google to get indexed

For this question, submitting the post to Google to get indexed, might be a good thing, but it is not needed for creating a blog post.

One last tip for the case study questions to round out this long post. The case study is divided into multiple tabs and one tab that includes all of the information. Then for each case study you can get from 1 to 5 questions for the case study. When you finish the questions for the case study you cannot go back to any previous case study. When you are finished with a case study you are finished with it. First and foremost, skip reading the case study. Read the questions first and write down what the questions are on the paper/erase board that they give you. Then go back and read the case study (the tab with everything) with the questions in front of you. This way you can see the question and the info at the same time. This makes doing case study questions alot easier.

Ok, I lied. I have a couple more tips. As you are going, you have the chance to mark the questions for review. Ones that are hard for you, mark them to go over it later. I also tend to write down on the supplied paper, what the question is about for each question. So if you know that question 10 was about apples and then later on question 23 you get another question you can always go back to question 10 to see if it helps. It does sometimes. I have also gone back over every question before and reviewed what I thought was the right answer. If you have time, I suggest this.

Take your time, relax, and did I suggest to make sure that you USE the technology?