HAVIT Knowledge Base

Vývoj webových aplikací, .NET, SQL, návrh
Welcome to HAVIT Knowledge Base Sign in | Join | Help
-
Home Články Forums Obrázky Soubory

.NET Framework

Microsoft .NET Framework, Base Class Library

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.

 

Published 2. února 2010 23:28 by Robert Haken
Filed under: ,

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

 

lukas said:

Díky moc za skvělej článek. Právě se přesně nad timhle rozčiluju, tak mi to móóóc pomohlo :-)

Jinak dá se použít My.Application.Info.CompanyName místo publisherName a My.Application.Info.ProductName místo productName - tim se dá předejít třeba překlepům apod., ale to je drobnost.

února 10, 2010 10:13
 

Robert Haken said:

to lukas: CompanyName ani ProductName z Application se bohužel obecně použít nedají, protože ty to čtou z assembly, zatímco v tomto scénáři je potřeba vzít hodnoty z ClickOnce Publish nastavení (které může být stejné, ale nemusí).

února 10, 2010 10:15
 

Robert Haken said:

Jinak tu mám Visty, kde ani ta nejširší verze (link ve Startup, který spouští .appref-ms prostřednictvím volání vlastní aplikace s přepínačem) nefunguje. Pustí to tu aplikaci, ale volání z ní (volání toho .appref-ms) už při startu Windows neprojde (nejhorší je, že při ručním kliknutí na toho zástupce ve složce Startup to projde!)

února 10, 2010 10:18

What do you think?

(required) 
(optional)
(required) 
Enter the code you see below

Submit