2

Our code-signing certificate expired recently, so I renewed it and just published our first version that uses the new certificate. Unfortunately, any customer who installs the upgrade loses the user-scoped application settings, and they get reset to the default values. I'm pretty sure that other upgrades always copied the user settings from the previous version, so I'd guess that there's some problem related to the new certificate. We're using a purchased certificate, not a test certificate. Our application is a WinForms application that targets .NET 3.5. The certificate authority seems to have changed hands in the three years since we bought the first certificate, so the issuer fields are different.

Is there any way to avoid losing the user settings when you renew a code-signing certificate?

Don Kirkby
  • 53,582
  • 27
  • 205
  • 286

2 Answers2

4

Thanks to some hints from Jirka's answer, it turned out to be a pretty easy fix. It looks like the user settings framework can see the previous version, but they just didn't get upgraded for some reason. I used Mitch's technique for upgrading user settings to manually call Upgrade() the first time I run a new version. A useful trick for testing this upgrade process several times was Jason's suggestion of copying old versions of the application manifest over the current version.

It looks like I was fairly lucky. In some scenarios, customers have to completely uninstall and reinstall whenever you renew your certificate.

RobinDotNet wrote a comprehensive article on certificate expiration and ClickOnce. I found that there is a bug report, but it doesn't sound very likely to get fixed. It sounds like targeting .NET 4.0 would make this problem go away, but the transition from 3.5 to 4.0 can be a bit tricky.

One thing that can make the expiry process a bit smoother is to timestamp the signing. That way, you don't have to renew your certificate and publish a new version before the old certificate expires. The only timestamp server URL I've seen mentioned is this:

http://timestamp.verisign.com/scripts/timstamp.dll

Community
  • 1
  • 1
Don Kirkby
  • 53,582
  • 27
  • 205
  • 286
1

Let us go through some gotchas related to application settings upgrade first and get to user settings specifics last.

The article that you link to is saying that you are OK (wrt bare upgradability) as long as you are not a VSTO 2010 application. If you are, retargetting to .NET 4.0 is still a pretty trivial exercise on one assumption: you need to have .NET 4.0 available on your customers' systems. If this is not the case, dig up the email that you sent to them the day you introduced your application (with the URL to install from) and circulate it again. This method will equip them with .NET 4 (but simply launching the application as usual is not).

ClickOnce additionally requires your identity (Subject - CN part) to the the same on both certificates, old and new to recognize that it is still the same application. Is that the case? Dig closely into the Subject detail.

Failing everything, your last chance regarding application settings is to manipulate app.exe.config which stores your app's settings programmatically from your app. If you have the access rights to do that on your customers' systems, that is.

User settings upgrade is slightly more complicated by design. The reason is that ClickOnce is attempting a merge of new version's defaults with particular user's settings under the old version. It is however possible to customize this logic by overriding ApplicationSettingsBase.Upgrade.

Jirka Hanika
  • 13,301
  • 3
  • 46
  • 75
  • Thanks for the suggestions. I am talking about user-scoped application settings, so I clarified that in the question. I checked the Subject field in the old and new certificates, and there's no change. However, the Subject Key Identifier field does not match. The two certificates came from different authorities, so maybe they generate the identifiers differently. – Don Kirkby Mar 28 '12 at 21:01
  • Changed Subject Key ID is not a problem. This is expected to change. You do have some control over user settings upgrade. Create an application settings class, override `ApplicationSettingsBase.Upgrade` and call `ApplicationSettingsBase.GetPreviousVersion` from it. Do you see the old user settings this way? If so, you are not hit by any of the bugs you currently fear (.NET considers this to be the same application, lucky for you). – Jirka Hanika Mar 28 '12 at 21:43
  • Lucky for me, indeed. As you suggested, I could see settings from the previous version when I called `GetPreviousVersion()`. I didn't even have to override `Upgrade()`, it works if I explicitly call it. I wonder why the ClickOnce deployment isn't properly calling `Upgrade()`. – Don Kirkby Mar 28 '12 at 23:19
  • @DonKirkby - I'm glad it helped. I updated the answer to better match the updated question. See also the link I added. I also corrected myself on certificate matching, or at least I hope I did. – Jirka Hanika Mar 29 '12 at 07:10