Archive for August, 2007

Troubleshooting ClickOnce deployment issues

August 25, 2007 9:18 pm

Over the last few days I ran into several puzzling ClickOnce deployment problems. I want to document and share these so that I’ll remember them better, and so others might find help with similar issues.

The first issue:
I uploaded new versions of my files several times, but every time I attempted to download the refreshed versions, no matter which computer I tried it on, all I got were old files. Ctrl+F5 in IE didn’t make a difference. Clearing the Internet Explorer history, cookies, temporary files didn’t make a difference. I even contacted my web host to see if they have any caching issues on the server side. In the end I stumbled across my installation of Fiddler, the HTTP debugging proxy. I looked at the raw HTTP dumps, and then I saw the issue: I’m behind an active caching proxy on my home network. The proxy was giving me old files all the time.
First issue solution:
Clean out the cache files on my proxy server. It happens to be squid, so this did it:

service squid stop
echo “” > /var/spool/squid/swap.state
service squid start

The second issue:
During the troubleshooting of the first issue I had started suspecting the ClickOnce caching system to be at fault. So I used “mage -cc” and “rundll32 dfshim CleanOnlineAppCache” to clean out the cache. No change. Then I started manually deleting files from the cache location on the hard drive. Bad mistake. Now I got weird deployment errors, talking about COM objects not being available, and “interesting” HRESULT errors: The referenced assembly is not installed on your system. (Exception from HRESULT: 0×800736B3). I uninstalled the .NET Framework 2.0 and 3.0 and reinstalled them. No change. Luckily I found an article on the MSDN forums that pointed me to a registry location to check out: HKCU\ Software\ Classes\ Software\ Microsoft\ Windows\ CurrentVersion\ Deployment. I checked it out and found a bunch of registry keys that I remembered seeing when I cleaned out the cache files before. So what would happen if I deleted all those keys? Maybe it would “reset” ClickOnce completely? Luckily it did.
Second issue solution:
Clean out both the ClickOnce cache files [C:\Documents and Settings\(User)\Local Settings\Apps\2.0] by hand (completely), and also clean out the registry keys under Components, Marks, PackageMetadata, StateManager\ Applications, StateManager\ Families and Visibility underneath HKEY_CURRENT_USER\ Software\ Classes\ Software\ Microsoft\ Windows\ CurrentVersion\ Deployment\ SideBySide\ 2.0

Caution! Your Mileage May Vary. Deleting registry stuff is dangerous! Make a backup first.

Thanks for reading! It looks like you're new here. Welcome! If you like what you see, I encourage you to subscribe to my RSS feed. If you're worried about adding another RSS feed that will add to your information overload, don't! I'm not a prolific poster. Thanks for visiting!

Getting Vista UAC elevation to work for web deployed ClickOnce applications

12:06 am

Normally you can’t have ClickOnce applications that are deployed over the web run with Vista UAC elevation prompts. It’s not something Microsoft supports. Not sure why. I guess it’s once-bitten twice-shy, coming from the whole ActiveX mess. So I guess I do kind of understand why.

There is a workaround, if you really need UAC elevation, which you shouldn’t. But at a high level, it works like this. You create your ClickOnce app like you would normally. To go with it, you create a helper app that you equip with an embedded elevation manifest. You then add a test to your ClickOnce app to see if it’s running elevated. If it isn’t you make it call the helper app. It will cause a UAC elevation prompt and in turn launch the ClickOnce app anew. Since the helper got elevated, the ClickOnce app now runs elevated too. Of course, by doing this you might end up with users not accepting the elevation request. But from what I’ve seen real users do with those elevation prompts, it won’t matter much. Anyway.

The trick is getting the helper app included in the regular ClickOnce app. There may be better ways, but here’s one I’ve spent quite some time on to work out. Maybe it will help someone out there save time, like I’ve saved time by reading posts on elevation checks using managed code. So here are the steps I’ve followed to make this work:

  1. Modify your ClickOnce app’s entry point to include elevation checks as described at http://www.itwriting.com/blog/?p=198. If the app is not running elevated, make it run the helper application and exit. The launch looks something like this:

    ProcessStartInfo

    psi = new ProcessStartInfo(“Helper.exe”);
    psi.UseShellExecute = true;
    Process.Start(psi);

    The UseShellExecute flag makes sure the UAC prompt will happen.

  2. Create your helper application with an elevation manifest (the process for that is at Catherine Heller’s blog) and have it launch your app with something like this:

    string
    appExe = Environment.GetFolderPath(Environment.SpecialFolder.Programs) + @”\YourClickOnceApp\ClickOnceApp.appref-ms”;
    Process.Start(appExe);

    As you can see the whole scenario only works if you let the ClickOnce app create a Start Menu entry.

  3. Build and publish both applications, making sure they use the option to rename the published files to .deploy extensions. This helps tremendously with web deployment.

  4. Find the published helper .deploy files and copy them to the folder that contains the ClickOnce application’s .deploy files.

  5. Open the ClickOnce application’s .exe.manifest file using MageUI. Go to the Files section and click the Populate button to include the helper app and its manifest in the fileset for the ClickOnce app. Save and sign the manifest. I used a stored certificate for the signing.

  6. Open the ClickOnce application’s .application deployment manifest using MageUI. This is probably in the directory above the .deploy files. Open the Application Reference section. Click the Select Manifest… button and browse down to the manifest you modified in step 5. Save and sign the manifest. I used the stored certificate from step 5.

  7. Now you have all the needed files packaged for uploading to your web server.

This is what will happen when the user downloads the app for the first time: A verification window shows briefly, followed by a download warning, followed by a download progress window. Now the UAC prompt will come, and if accepted, another verification window. Then the app will show.

On subsequent launches of the app the user will see the verification window, followed by the UAC prompt, followed by another verification window. Then the app will show.

It’s not pretty, but at least it works.

If you try these steps out and they don’t work, I’d appreciate an opportunity to correct them.

————————————————-

P.S.: The manifest generation step looks like this for C# projects:

“$(DevEnvDir)..\..\VC\bin\mt.exe” -manifest “$(ProjectDir)$(TargetName).exe.manifest”  ?outputresource:”$(TargetDir)$(TargetFileName)”;#1

The .exe.manifest for the helper needs to look something like this (you can leave out the commented parts):

<?

xml version=1.0 encoding=utf-8 ?>

<assembly xmlns=urn:schemas-microsoft-com:asm.v1 manifestVersion=1.0>

<assemblyIdentity version=1.0.0.0 processorArchitecture=msil name=Helper type=win32 />

<description>Helper</description>

<trustInfo xmlns=urn:schemas-microsoft-com:asm.v3>

<security>

<requestedPrivileges>

<requestedExecutionLevel level=requireAdministrator />

<!–<requestedExecutionLevel level=”asInvoker” />–>

<!– <requestedExecutionLevel level=”highestAvailable” /> –>

</requestedPrivileges>

</security>

</trustInfo>

</assembly>

I hate Windows Update right now. Or Windows Live writer. Take your pick.

August 24, 2007 10:58 pm

I spent 45 minutes or so writing up a post in Windows Live Writer this evening. All the while I repeatedly dismissed a Windows Update countdown dialog that was asking for a restart. “Not now, dammit. I’m writing something.”

Then the phone rang. Someone wanted to talk to my wife. She was in the process of reading a good-night story to my older daughter. The caller couldn’t wait. So I volunteered to read another chapter of the story.

When I got back, Windows was at the logon screen. Dammit, the Windows Update had gone through with the restart, with me not there to dismiss the countdown dialog.

And Windows Live Writer hadn’t saved a draft.

Both programs violated two cardinal rules for software: Don’t ever do something the user didn’t ask for, and don’t ever, ever, ever lose the user’s data. It’s worse than what Jeff Atwood talked about recently, since there were no crashes involved.

I’m so mad I’m not even sure I’ll want to re-write that other post. It has the potential to help out a fellow developer. Maybe I’ll do it. But right now I hate Windows Update. Or Windows Live Writer. Take your pick.

Apple’s new iMacs

August 7, 2007 11:49 pm

It’s almost a sacrilege to admit it for someone working with traditional PCs for a living, but I’m just blown away by the new stuff Apple announced today. Their marriage of sleek, elegant hardware, fabulous software and web services just screams and screams “smart” at me. Now that I think about it, I’ve been blown away at almost every single announcement within the last three or four years.

But.

Aluminum?

Yes, it’s recyclable. And it’s highly desired by recyclers.

You know why?

Because it’s one of the most energy-wasting metals to extract from the ore. The more recycled aluminum you can get your hands on, the more money you can make.

And now they make the entire iMac shell out of the stuff? Ugh.

So Steve touts the recycling aspect in his presentation, making everyone think “Wow, Apple is doing a great thing. Great for the environment.”

They’re not doing a great thing. And it’s not great for the environment.

But of course they don’t tell you that.

See my previous post for more details on how much energy goes into making aluminum, illustrated by soda cans.

Now, this is about the only bad thing I have to say about the new stuff that came out of the buildings down the street today. Everything else sounds and looks fantastic. One of these days I’ll have to break down and get one of these JesusMachines.

New website launched on the topic of Simple Living

10:34 pm

This is pretty exciting to me. I just got an email from Carol Holst, editor of the forthcoming book “Get Satisfied: How Twenty People Like You Found The Satisfaction Of Enough”, about the companion website that just launched.

This is a great resource for people who are finding themselves dissatisfied with the life they lead and who wonder if there is more to life that living paycheck to paycheck and chasing after the latest new shiny object. Without resorting to religion, that is.

If that resonates just a tiny bit with you, head over to www.getsatisfied.org and look around. I think you’ll like what you find.

Observations on making live music and writing code

August 4, 2007 3:27 pm

A long time ago my daughter performed a piece of harp music at a recital held at her teacher’s studio. She wasn’t playing on her own harp, and she hadn’t really learned to read the music as she was playing her song. Her teacher asked her to play a duet with her, and she reluctantly agreed.

They started playing, and at some point one of the strings on the harp made a strange noise that threw her off. She stopped playing and her teacher said, no problem, let’s pick it up again at such and such measure. Well, since she hadn’t learned the music, she couldn’t find the place and they had to start from the beginning again. This happened a couple more times. My daughter said afterwards: “That’s why I don’t like playing duets.”

This got me thinking about how making music together is a lot like writing code together.

It’s usually not too difficult play a piece of music by yourself. You’re going at your own pace and can stop and make corrections as you go. But as soon as you have another person involved, things get more complicated. You have to stay in sync somehow. One way you can do this is by following the beat of the music, and practicing until you can play together without mistakes. Another way is to improvise together in the style of great blues and jazz musicians, but it takes years and years of experience playing together to get to that level. When you have more than two people, things get even more complicated. At some point you usually need a conductor to keep it all together.

Here’s how that works when writing code:

You can write a piece of code by yourself pretty easily. You know what you want to do, and you can correct mistakes you make as you go along. But as soon as you have another person involved, things get more complicated. Now you have to agree on all kinds of stuff, and you don’t have a musical beat to help you. Who works on what? How do things interface? How do you keep the code in sync? You can’t really practice this, since most code-writing is coming up with new stuff. You can agree on a common language (patterns or idioms) to communicate, but that takes time to learn. When you have more than two people, things get even more complicated. Now you need to agree on source control procedures, more frequent synchronization and communication. At some point you usually need a technical lead to keep it all together.

How you go about doing all this when the people writing the code are not in the same physical location is quite astonishing to me.

Imagine trying to make music together when half the people are 12 hours away from you.

I bet that wouldn’t sound very good.

A truly brilliant description of cloud formation

2:59 pm

Eric Lippert paints such vivid pictures of cloud formation, I just had to link to his two part miniseries:

Talking About The Weather, Part One

Talking About The Weather, Part Two

I’ll have to go back and read these one more time. Fascinating.