ClickOnce – spouštění při startu Windows, dvojí konfigurace a podobné záludnosti

Trochu nedobrovolně jsem byl dnes donucen šťourat se podrobněji v ClickOnce útrobách, přestože to není moje oblast zájmu.

Symptomy problému byly zajímavé – aplikace instalovaná pomocí ClickOnce, která v sobě měla volbu „Automaticky spouštět při startu Windows“, se chovala divně. Zprvu se zdálo, že nastavení provedená v aplikaci (.NET Settings mechanizmus), se restartem počítače ztratí. Nakonec jsem diagnostikoval, že ve skutečnosti aplikace používá dvoje nastavení – jedna nastavení používaná po instalaci a při spuštění aplikace automaticky vytvořenou položkou z menu Start, druhá nastavení používaná při automatickém spuštění po startu Windows. Zároveň jsem v C:\Users\… našel v profilu uživatele dva různé user.config soubory, které se používaly pro tyto dva scénáře spuštění aplikace.

Chyba byla ve skutečnosti v nekoretním spouštění aplikace po startu Windows. ClickOnce totiž sám automatické spouštění po startu Windows nepodporuje a při vlastní implementaci nebyl na rozdíl od zástupce v menu Start totiž použit link typu .asppref-ms (link soubor pro spouštění ClickOnce apliace, který zajišťuje i aktualizace a další ClickOnce věci), ale nekorektně aplikace pro spuštění po startu Windows používala přímo odkaz na svůj .exe soubor. To způsobilo nejen použití jiného user.config souboru, ale i nefunkčnost automatických aktualizací a dalších vlastností ClickOnce.

Poučení tedy zní: Pokud chcete korektně spouštět ClickOnce aplikaci, je potřeba volat vytvořený soubor .appref-ms (vytvořený ClickOnce instalátorem do menu Start) a nikoliv se odkazovat na .exe soubor aplikace.

Chybný kód tak může vypadat:

Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true)
.SetValue("InformTrayReader", Application.ExecutablePath);

Zatímco „správně“ (při dalších omezeních) by to mohlo vypadat nějak takto:

Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true)
.SetValue("InformTrayReader", GetApplicationStartupLink());

private object GetApplicationStartupLink()
{
    const string productName = "název dle ClickOnce Publish nastavení";
    const string publisherName = "nastavení dle ClickOnce Publish nastavení";

    string allProgramsPath = Environment.GetFolderPath(Environment.SpecialFolder.Programs);
    string shortcutPath = Path.Combine(allProgramsPath, publisherName);

    return Path.Combine(shortcutPath, productName) + ".appref-ms";
}

Viz též související info:

UPDATE pro Windows Vista

Pokud nedejbože potřebujete, aby to fungovalo pro nějakého nebožáka používajícího alfa-verzi od Windows7 zvanou Windows Vista (dodnes nechápu, jak mohl Microsoft něco takového vydat), potom je nutný ještě jeden workaround.

Visty totiž nepustí .appref-ms přímo, a to ani z registrů, ani kdybyste odkaz dopravili do Start/Startup. Funguje v nich ale spouštění .exe a kupodivu lze .appref-ms zavolat z našeho exe a spustí se. Stačí tedy našemu programu přidat přepínač příkazové řádky -LaunchClickOnce a při jeho zjištění v Main() místo aplikace samotné odstartovat jen .appref-ms a sám se ukončit.

Podrobnější popis s ukázkou konkrétního kódu najdete na stránce http://www.brokenwire.net/bw/Programming/116/run-clickonce-app-on-startup.

Napsat komentář

Vyplňte detaily níže nebo klikněte na ikonu pro přihlášení:

WordPress.com Logo

Komentujete pomocí vašeho WordPress.com účtu. Log Out / Změnit )

Twitter picture

Komentujete pomocí vašeho Twitter účtu. Log Out / Změnit )

Facebook photo

Komentujete pomocí vašeho Facebook účtu. Log Out / Změnit )

Google+ photo

Komentujete pomocí vašeho Google+ účtu. Log Out / Změnit )

Připojování k %s