Comparison of Microsoft Visual Studio unit tests (MSTest) vs NUnit, mentioning PartCover and
Tag Archives: .net
MSBuild don’ts
15-Apr-08MSBuild tips: some things you shouldn’t do, and what to do instead.
Another problem with MSBuild bootstrappers that can screw all your installation…
If scheduling reboot after installing .NET or other prerequisites, bootstrapper copies itself to run from TEMP on boot. Why not staying where it is - who knows. And definitely, all the other MSIs are not copied, so it won’t find them. Reproduced for me.
Now give up and go write own bootstrapper. I’m setiously considering going for InnoSetup deployment.
For now, I’m trying a crazy ting, to copy MSI to TEMP for Setup.exe to find it after reincarnation… It’s the way to use given tools.
Can’t run .NET bootstrapper from an MSI
02-Apr-08Now I know it.
It’s Windows Installer error 1618 that I didn’t see somewhy when attempting to fix .NET bootstrapper. Either I was inattentive or it wasn’t there: “Another copy of msiexec is running”. You can’t have two Windows Installers running, at least if one of them installs .NET. Information is from this maillist post.
Why? Implementation limitations, I believe. No sane reasons for such a contract, no article mentioned this. Surely, who’s going to declare own “features” of that kind - just a gentle hints that “you should better use bootstrapper”. Another reason to long for a systems where setup is just a copy.
So go pack a MSI, then make a MSBuild bootstrapper.
Oh wait, do I have to have 2 files in my installation? And my customers can’t download one file?
Yes. Or go for WinZip Self-Extractor, or WinRar, or whatever else.
What about build scripts? For WinRar, here’s a nice sample. For WinZip sfx, there’s also a command-line interface. Do a
wzipse32 %ARC_NAME% -setup -auto -runasuser -le -i ../icon.ico -wait msiexec -c ".\setup.exe"
WinZip will do the thing, though displaying some dialogs we don’t need at all.
Oh, WinRar won’t work, because it erases temporary files upon setup.exe completion. And we need to wait for msiexec, because setup.exe exits earlier. What a pity.
After Microsoft didn’t include .NET 3.5 in any current release of Windows (read “Vista service pack 1″), some of us developers who believed in long-ago C# 3.0 ads, had to roll back to .NET 3.0 and C# 2.0.
Including me.
Not mentioning pain of rolling back all LINQ tasties in code and debugging our replacements (do you know why you can’t implement Where() just with yield-style function?), it means installing .NET 3.0.
It seemed to be not a problem, having a MSBuild code snippet that worked for 3.5 - just replace 3.5 with 3.0:
<ItemGroup> <BootstrapperFile Include="Microsoft.Net.Framework.3.0"> <ProductName>.NET Framework 3.0</ProductName> </BootstrapperFile> <BootstrapperFile Include="Microsoft.Windows.Installer.3.1"> <ProductName>Windows Installer 3.1</ProductName> </BootstrapperFile> <Target Name="Bootstrapper"> <GenerateBootstrapper ApplicationName="blah blah blah blah" BootstrapperItems="@(BootstrapperFile)" BootstrapperKeyFile="" OutputPath="obj" ComponentsLocation="HomeSite" CopyComponents="false" SupportUrl="http://www.microsoft.com/downloads/details.aspx?familyid=10CC340B-F857-4A14-83F5-25634C3BF043" Culture="en" Path="$(BootstrapperPath)"/> </Target>
Won’t work.
Hell why? Who knows. Logs in temp don’t give proper diagnostics, nor system events do. WPF fails to install at some point onto every XP installations we have, including clean special test XP SP2 VMWare images downloaded from Microsoft.
Update: Here’s the answer.
Now I rolled back to dotnetfx3setup.exe redistributable. It’s 2.8M compared to 300K bootstrapper generated by MSBuild, and it’s a pain to see installer grow…And if .NET 3.0 is already installed it starts to uninstall it… and there is no key to make it just “check or install”, need to trick it via WiX.
But we have to pay it. Oh my.
All over the Web I see no evidence that any man walked this path before. For.NET 2.0 - a lot of mentions and code samples. And completely empty for .NET 3.0.
Some pages that somewhy didn’t appear at top of Google searches for WiX help.
- WiXWiki.com - pretty useful and contains some snippets you won’t find in WiX manual or tutorial. Many of rare code snippets
- WiX development releases; some broken (last two broken in VS 2008), some contain the very things you’ll need;
- Justin Rockwood’s blog entry with Votive (Visual Studio addon) preprocessor variables. The blog itself is also thing to read;
- Alex Shevcuk’s blog entry on checking pre- and postconditions in WiX. His whole cycle on WiX - I also highly recommend it;
- Separately, .NET: WixWiki pages about checking for .NET runtime and deploying it with a bootstrapper generated with MSBuild;
- Another WiX wiki on mindcapers.net, I particularily needed ICE38 error explanation;
- John Robbins’ blog entry on patching patching with WiX. You don’t want number of auto-update patches to grow quadratically?
- Last but not the least, MSI properties reference on MSDN.
NAnt vs MSBuild funnies
20-Mar-08All the software is equally bad…
Well, I know some pieces of software that are good, but I won’t mention them today.
One of our msbuild vs nant choice criteria isĀ a product versioning support.
Sad or funny things are:
- both don’t include sane tool out of box;
- both need installing NAntContrib or MSBuild Community Tasks;
- even then both can’t sanely write AssemblyInfo.cs in order to leave other properties intact; if you had InternalsVisibleTo satellite unit test assembly - it won’t build then;
NAntContrib Version task is way more functional.
Additionally, MSDN page design where MSBuild reference manual lives, is awful.
I wonder if it’s the reason to choose a build tool, while they are approximately equal.
OTOH, MSBuild has a great GenerateBootstrapper task to install .NET framework from MSI (WiX sample included in the referenced wiki).
Auto-update with WiX
12-Mar-08Windows Installer on itself is a pain. WiX saves you from it, mostly wrapping the complexity into XML constructs understandable to non-gurus.
Well, not completely - you still have to know:
- why the heck shortcut didn’t appear in start menu;
- how to create a web site shortcut;
- why to create RegistryValue for a program directory you create, and that’s the simplest things. Still better then MFC…
But a very good tutorial exists, maillist is very active and it’s easy to get support.
Maybe it’s another reason to love Unix-es, where “install IS just a copy”.
Though, one has to admit that installing Windows application involves somewhat more desktop integration.
I was looking for an auto-update, so that:
- application could say “New version available, download? Restart now?“;
- would use MSI;
- download should preferably use BITS.
Simple automatic updaters like this on Codeproject won’t do, because you can’t just download necessary files: Windows Installer will revert them back. Or you would have to “disable WI’s Resiliency“, which is also a bad idea.
Solution of my choice
ClickThrough subproject of WiX promises that, but it’s still beta and crashes. Still you can easily compare two MSI files, generate a MSP patch, and a RSS feed that client can check, download and even read by eye, so simple it is - a pretty tasty feature.
There is no .NET client code. For now, there is only a separate update.exe that will find, download and install new version. Still, you cannot ask user whether to download now or not, cannot tell what’s new, when to restart, etc.
But you can painlessly add a Start menu shortcut that will update your application.
Come later, I’m going to create a C# code that will check for updates, and probably publish it.
Other solutions
You can use Updater ApplicationBlock, or more exactly, latest version now lives at CodePlex. But Enterprise Library wasn’t updated for .NET 3.5, and I believe it’s abandoned.
You can use NSIS. Though, it’s not Windows Installer MSI packager, it creates own files and scripts.
For ClickOnce application, you can use Application.Deployment.
Choosing MSBuild/TeamBuild vs NAnt
11-Mar-08We’re choosing a build tool for VS 2008 project.
I’m not expert in any, only had put together a couple of NAnt scripts. So I give no objective technical information in this post, just impressions.
- First discussion of this choice, back in 2005, is almost strictly in favor of NAnt. Though, read it to know about MSBuild differences and advantages.
- Recent blog post by Oren Eini and int comments are also generally for NAnt. Additionally, you can use <msbuild> task in NAnt.
- The latter mentions Yahoo! ALT.NET group discussion. Newsgroup fan can read a lot there, I also had some. There are reasonable votes there for MSBuild because it’s just deployed with .NET, ant it’s nearly functionally equivalent to NAnt.
Though, I can’t forget first discussion that mentioned lack of tasks like editing files or grabbing text output, or incrementing build number - (you know, devil is in details!) - it seems to me that NAnt wins.
Here’s the most useful message there, as for me.
You see, I didn’t go too deep down simple Google search. That was enough for me, you’re welcome to research deeper and to correct me… especially until I started creating build procedure <grin>
And I trust mature and popular opensource products.
Multithreading in WPF: getting started
12-Feb-08Couple of things to know when starting a new thread in WPF application
- Why FindAll() is not in IList? IDictionary or at least Dictionary? Are you pushing me to code for implementation?
- Why WeakReference, but no WeakDictionary (get a nice one from Nick Guerrera)? WeakList? More?
- Why ReadonlyCollection<T>, but no ReadonlyDictionary<K, V>?
- (I can live with this one) Why Array.Length, but anyCollection.Count (thank Nick Guerrera again)?
…more to follow as I recall them…
gdi bug in System.Drawing.Drawing2D?
21-Jan-08Am I the only one who ran into .NET (or GDI?) bug with Pen (or Matrix) .ScaleTransform()?
When I scale a pen to certain width, and it has an anchor, anchor draws at inverse scale.
I might be missing something, but here’s my test. Pen scales proportionally to form width, for simplicity.
Here’s how it looks:

You see, the thinner the line, the bigger is the cap. Uh-oh.
My workaround should be here after some time.
Source code for interested ones:
