Bartek Szafko

all of the bits and pieces

Archive for the ‘WiX’ Category

[EN] Windows Installer XML – Heat bug?

with 2 comments

I was trying to write a post on generating wxs scripts with heat. But i think I found a bug. Below more info – maybe someone can verify.

I’ve got a following directory contents:

image

And I run heat with following parameters:

heat dir . -dr D_INSTALLLOCATION -sfrag -srd -gg -suid -cg test -out test.wxs

I get following wxs:

<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Fragment>
        <ComponentGroup Id="test">
            <ComponentRef Id="" />
            <ComponentRef Id="" />
            <ComponentRef Id="" />
            <ComponentRef Id="" />
        </ComponentGroup>
    </Fragment>
    <Fragment>
        <DirectoryRef Id="D_INSTALLLOCATION">
            <Component Id="c2csi.exe" Guid="{43B03251-B0EE-4273-8E3C-DE54EAD0A263}">
                <File Id="c2csi.exe" KeyPath="yes" Source="SourceDir\c2csi.exe" />
            </Component>
            <Component Id="c2csi.pdb" Guid="{5B925509-EB62-461F-BEB8-FC4C8C99C290}">
                <File Id="c2csi.pdb" KeyPath="yes" Source="SourceDir\c2csi.pdb" />
            </Component>
            <Component Id="c2csi.vshost.exe" Guid="{048CE65A-FCD9-4A05-B482-45F326F40199}">
                <File Id="c2csi.vshost.exe" KeyPath="yes" Source="SourceDir\c2csi.vshost.exe" />
            </Component>
            <Component Id="test.wxs" Guid="{90927E13-B1AD-48D2-AADA-0C227CD2DC36}">
                <File Id="test.wxs" KeyPath="yes" Source="SourceDir\test.wxs" />
            </Component>
        </DirectoryRef>
    </Fragment>
</Wix>

Notice the ComponentGroup – it has empty Ids in ComponentRef.

Why would I want to generate non unique File Ids and put them in ComponentGroup?

The answer is: I would put ComponentGroupRef in Feature and use references to File element to create for example a shortcut in start menu.

Now when I removed –suid when calling heat it generated wxs with unique component and file ids which are impossible to reference in the main script.

Is it a bug or should I take a completly different approach?

UPDATE: when used project harvester with the same paramaters .wxs was ok:

<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Fragment>
        <DirectoryRef Id="c2csi.Binaries">
            <Component Id="c2csi.Binaries.c2csi.exe" Guid="{22D0EAD2-B33C-4D1D-B5F2-FA046CF79649}">
                <File Id="c2csi.Binaries.c2csi.exe" Source="$(var.c2csi.TargetDir)\c2csi.exe" />
            </Component>
        </DirectoryRef>
    </Fragment>
    <Fragment>
        <ComponentGroup Id="c2csi.Binaries">
            <ComponentRef Id="c2csi.Binaries.c2csi.exe" />
        </ComponentGroup>
    </Fragment>
</Wix>

Written by Bartłomiej Szafko

April 24th, 2009 at 7:46 pm

Posted in WiX

Tagged with , , ,

Instalator w pliku msi część 6 – upgrade

without comments

W poprzednich częściach o WiX:

Bardzo ważnym zagadnieniem jest aktualizowanie już zainstalowanej aplikacji. Przy pomocy WiX można budować patch, hotfix oraz major upgrade. W tym poście pokaże jak zbudować aktualizację typu major upgrade, która polega na odinstalowaniu pakietu i zainstalowaniu nowego.

<Upgrade Id="$(var.UpgradeCode)">
   <UpgradeVersion Minimum="$(var.ProductVersion)"
      IncludeMinimum="no"
      OnlyDetect="yes"
      Language="1045"
      Property="NEWPRODUCTFOUND" />
   <UpgradeVersion Minimum="0.0.1.0"
      IncludeMinimum="yes"
      Maximum="$(var.ProductVersion)"
      IncludeMaximum="no"
      Language="1045"
      Property="UPGRADEFOUND" />
</Upgrade>
<CustomAction Id="PreventDowngrading" Error="Najnowsza wersja jest już zainstalowana." />
<InstallExecuteSequence>
   <Custom Action="PreventDowngrading"
      After="FindRelatedProducts">NEWPRODUCTFOUND</Custom>
   <RemoveExistingProducts After="InstallFinalize" />
</InstallExecuteSequence>
<InstallUISequence>
   <Custom Action="PreventDowngrading"
      After="FindRelatedProducts">NEWPRODUCTFOUND</Custom>
</InstallUISequence>

Element UpgradeVersion, służy do sprawdzenia czy w systemie nie jest już zainstalowany pakiet o takiej wersji jak aktualnie uruchomiony, w takim wypadku zostanie ustawiona właściwość NEWPRODUCTFOUND. Drugi element UpgradeVersion odpowiada za znalezienie poprzednich wersji aplikacji i ustawienie właściwości UPGRADEFOUND. Ważne jest ustawienie atrybutu Language, gdyż będziemy wyszukiwać instalatorów w odpowiednim języku.

Akcja o Id PreventDowngrading, odpowiada za wyświetlenie komunikatu błędu w przypadku, gdy zainstalowana już jest najnowsza wersja aplikacji. Do przebiegu procesu instalacji dodałem wyświetlenie informacji w przypadku gdy jest zainstalowana najnowsze wersja poprzez osadzenie elementu Custom w elemencie InstallExecuteSequence. Drugim osadzonym elementem jest RemoveExistingProducts, który odpowiada za usunięcie starszej wersji aplikacji. Dodatkowo zdefiniowany atrybut After, z wartością InstallFinalize zapewnia, że stara wersja zostanie usunięta dopiero po zainstalowaniu nowej. Dodałem wywołanie akcji PreventDowngrading zabraniającej instalacji starszej wersji w wypadku gdy zostanie uruchomiona instalacja z interfejsem użytkownika.

Pliki konfiguracyjne

Powyższe rozwiązanie spowoduje również utratę wszystkich informacji zawartych w plikach konfiguracyjnych. Pliki .config zostaną usunięte i zapisane wersje z instalatora.

Istnieje sposób na obejście tego problemu, tylko trzeba się o to zatroszczyć już przy tworzeniu pierwotnego instalatora, który później będzie aktualizowany. Każdy plik .config musi zostać umieszczony w osobnym komponencie a atrybut KeyPath musi być ustawiony na wartość True. Spowoduje to, że windows Installer będzie używał daty ostatniej modyfikacji w nowym i starym instalatorze, jeśli się będą różnić nie będzie nadpisywał pliku.

Ostatnim krokiem jest zmiana miejsca, w którym wykonuje się akcja RemoveExistingProducts, należy zmienić wartość atrybutu After na InstallFiles. Po tej zmianie wpierw zostaną zainstalowane wszystkie nowe pliki zanim zostaną usunięte stare. Ponieważ ustawiłem KeyPath na true, liczba referencji do plików .config po zainstalowaniu nowej wersji będzie ustawiona na 2. Po odinstalowaniu starej wersji zostanie zmniejszona do 1, a nie do 0, więc plik nie zostanie usunięty. I o to chodziło.

Gdy nie przewidziałeś aktualizacji plików .config na samym początku trzeba się nieźle nakombinować żeby później dokonać aktualizacji, o czym przekonałem się na własnej skórze.

Sama aplikacja też musi być przygotowana do obsługi starego pliku konfiguracyjnego – np.: inny format sekcji czy nawet brak całych sekcji(wstawianie wartości domyślnych).

Więcej na ten temat w poście Aarona Stebnera, z którego skorzystałem podczas pisania akapitu o plikach konfiguracyjnych.

Written by Bartłomiej Szafko

April 10th, 2009 at 8:48 pm

Posted in WiX

Wixa nie będzie w Visual Studio 2010

without comments

image

Normalnie tragedia, niestety Windows Installer Toolkit nie wejdzie do do puedłka z Visual Studio 2010. Napisał o tym Rob Mensching na swoim blogu.

O WiX w VS 2010 pisałem w moich poprzednich postach:

Przypadkowo termin wpisu był 1 kwietnia, z początku myślałem, że jest to prima aprilisowy żart, ale niestety okazało się że tak nie jest.

Oczywiście WiX nadal będzie dostępny jako dodatek i nic nie będzie stało na przeszkodzie, żeby go używać. Dla mnie osobiście taka decyzja jest niezrozumiała – standardowe setupy z VS są bardzo często niewystarczające i środowisko będzie miało sporą dziure w procesie tworzenia oprogramowania. Zresztą Rob na swoim blogu też nie podaje powodu. Może stoi za tym InstallShield ?? ;)

Written by Bartłomiej Szafko

April 3rd, 2009 at 10:46 pm

Posted in WiX

WixEdit – łatwe edytowanie WxS

with one comment

image

Podczas moich prezentacji o WiX często pada pytanie: xml jest fajny, ale nie chce od niego zaczynać  – czy nie ma czegoś wizualnego? Okazuje się, że istnieje conajmniej jeden produkt komercyjny, który jest obiektem flamewara ze strony Roba Menschinga. Ja postanowiłem poszukać trochę głębiej. Okazuje się, że na sourceforge jest projekt o nazwie WiXEdit. Do tej pory nie miałem doświadczenia z żadnymi narzędziami graficznymi do WiX, więc postanowiłem spróbować.

image

Całość działa bardzo sprawnie, pozwala modyfikować główną strukturę, dodawać foldery pliki, itp. Jedna poważna wada to, gdy dodamy element UIRef i dodamy referencje do dialogów zdefiniowancyh w wixuiextension.dll w zakładce Dialogs nie można podglądać tych okienek. Dopiero gdy mamy źródła .wxs odpowiednich dialogów można je przeglądać. Fajna funkcjonalność to, że pokazuje się też jak będzie ostatecznie wyglądać okno.

image 

Jak dla mnie oczywistą wadą jest brak obsługi zmiennych z Votiva, bo działa poza środowiskiem Visual studio. Trzeba więc samemu ustawić odpowiednie wartości zmiennych np: $(var.SolutionDir) w Build Settings.

works-on-my-machine-starburst

Myślę, że WixEdit w pełny zasłużył na znak “Works on my machine” i mogę zdecydowanie polecić do używania szczególnie początkującym z WiX.

Inne ciekawe linki do projektów związanych z WiX, które ostatnio znalazłem:

  • WiX FileVersion Preprocessor Extension – extension, który pozwala na wyciągnięcie właściwości z assembly(ProductName, CompanyName, ProductVersion) i użycie ich do ustawienie odpowiednich wartości instalatora
  • WixTrim – inny edytor graficzny do skryptów WxS, wygląda ok ale jakoś rzadko był pobierany, ma bardzo podobny układ ekrany do visual studio – ktoś chętny żeby spróbować ? PLZ dajcie znać jakie mieliście wrażenia

Written by Bartłomiej Szafko

March 20th, 2009 at 8:09 pm

Posted in WiX

Instalator w pliku msi część 5 – skróty

with 13 comments

W poprzednich częściach o WiX:

 

W tej części omówie możliwości WiX jeśli chodzi o tworzenie skrótów do naszej aplikacji z menu start oraz pulpitu.

W instalatorach możemy tworzyć dwa rodzaje skrótów advertised i unadvertised.

Advertised

Skróty tego typu mogą się odwoływać tylko do plików, które są częścią instalatora. Za to podlegają np.: procesowi naprawy. Mogą być osadzone bezpośrednio w komponencie, który zawiera plik do którego mają wskazywać.

Przy okazji – jako best practice mogę polecić trzymanie struktury folderów i komponentów osobno – dzięki temu łatwiej będzie zmieniać lokalizację komponentów.

Poniżej przykład stworzonych skrótów typu Advertised(kluczowy jest element Shortcut oraz atrybut Advertise):

<Directory Id="TARGETDIR" Name="SourceDir">
  <Directory Id="ProgramFilesFolder">
    <Directory Id="D_INSTALLLOCATION" Name="$(var.Manufacturer) $(var.ProductName)"/>
  </Directory>
  <Directory Id="DesktopFolder"/>
  <Directory Id="ProgramMenuFolder">
    <Directory Id="D_MenuStartManufacturer" Name="$(var.Manufacturer)">
      <Directory Id="D_MenuStartProduct" Name="$(var.ProductName)"/>
    </Directory>
  </Directory>
</Directory>

<DirectoryRef Id="D_INSTALLLOCATION">
  <Component Id="C_ProductComponent" Guid="0c8acba5-46b2-472a-ab89-771dda833ab7">
    <File Id="F_c2csiexe" Source="$(var.SolutionDir)c2csi\bin\$(var.Configuration)\c2csi.exe" KeyPath="yes">
      <Shortcut Id="S_MenuStartShortcut" Name="C2C" Advertise="yes" Directory="D_MenuStartProduct" Icon="I_c2csi.exe"/>
      <Shortcut Id="S_DesktopShortcut" Name="C2C" Advertise="yes" Directory="DesktopFolder" Icon="I_c2csi.exe"/>
    </File>
  </Component>
</DirectoryRef>
<Icon Id="I_c2csi.exe" SourceFile="$(var.SolutionDir)c2csi\bin\$(var.Configuration)\c2csi.exe"/>

Przy okazji mała ciekawostka – okazało się że nazwa Id zdefiniowanej ikony musi kończyć się .exe tak jak plik do którego wskazuje skrót. Z innych ciekawostek – na Viście miałem problem z usuwaniem folderów z menu start, musiałem dodać fake komponent, który zadziałał przy usuwaniu:

<DirectoryRef Id="D_MenuStartProduct">
  <Component Id="C_FakeMenuStart" Guid="92476C56-1D38-4b5e-97E7-E83F5E9917C9">
    <RegistryKey Root="HKCU" Key="Software\$(var.Manufacturer)\$(var.ProductName)\Uninstall">
      <RegistryValue Value="Fake" Type="string" KeyPath="yes"/>
    </RegistryKey>
    <RemoveFolder Id="R_MenuStartManufacturer" Directory="D_MenuStartManufacturer" On="uninstall"/>
    <RemoveFolder Id="R_MenuStartProduct" Directory="D_MenuStartProduct" On="uninstall"/>
  </Component>
</DirectoryRef>

Powyższe przykłady dodadzą, skróty dla aktualnie zalogowanego użytkownika, natomiast jeśli chcemy dodać je dla wszystkich użytkowników ( do profilu All Users) wystarczy tylko dodać:

<Property Id="ALLUSERS"><![CDATA[2]]></Property>

Unadvertised

Skróty tego typu mogą sie odwoływać do dowolnego pliku  w systemie, z tym że nie podlegają już mechanizmowi naprawy instalacji. Trzeba też tworzyć osobny komponent dla tych skrótów i stworzyć element keypath,  po których silnik instalacji sprawdzi czy dany komponent jest zainstalowany – musi to być  to wpis w rejestrze systemowym, a nie plik tak ja w poprzednim przykładzie.

<DirectoryRef Id="D_MenuStartProduct">
  <Component Id="C_UnadvertisedShortcuts" Guid="2CBF2F3D-1B06-4102-A8A4-963E49FEADF3">
    <RegistryKey Root="HKCU" Key="Software\$(var.Manufacturer)\$(var.ProductName)\Uninstall">
      <RegistryValue Value="UnadvertisedShortcuts" Type="string" KeyPath="yes"/>
    </RegistryKey>
    <Shortcut Id="S_MenuStartUnadvertisedShortcut" Name="C2C" Advertise="no" Target="[#F_c2csiexe]" Directory="D_MenuStartProduct" Icon="I_c2csi.exe"/>
  </Component>
</DirectoryRef>

Metodę unadvertised zastosujemy np.: w sytuacji gdy chcielibyśmy dodać skrót do odinstalowania aplikacji w menu start.

Pomysły

Tak się zastanawiam, czy może na lato nie byłoby warto przgotować warsztatów z WiX – czy wogóle byliby jacyś chętni, jak myślicie?

Written by Bartłomiej Szafko

February 16th, 2009 at 9:10 pm

Posted in WiX

WiX w Visual Studio 2010 w praktyce

without comments

O Windows Installer Xml w Visual Studio 2010 pisałem już jakiś czas temu, ale tylko w teorii. Teraz zdecydowałem się zobaczyć jak wygląda w praktyce.

Wpierw należy pobrać maszynę wirtualną z windows server 2008 oraz ctp visual studio 2010. Zaraz po pobraniu i rozpakowaniu maszyny wirtualnej trzeba wyłączyć synchronizację czasu z maszyną hostującą, ponieważ vs2010 ma bombę czasową i przestaje działać po 1 stycznia 2009. Opisał to Ben Armstrong na swoim blogu.

Po tych zabiegach możemy odpalić maszynę i VS 2010, już na pierwszy rzut oka na splash screenie pojawia się WiX, tak jak np w VS2008 z zainstalowaną wtyczką Votive:

01 

Zajrzałem też do C:\Program FIles, zamiast “Windows Installer XML” jest folder “Visual Studio 2010 Windows Installer XML Toolkit CTP””

04

Są też tylko wtyczki WixIISExtension, WixNetFxExtension, WixSqlExtension, WixUIExtension, WixUtilExtension, WixVSExtension. Reszta ma podobno znaleźć się w wersji BETA. Postanowiłem też sprawdzić jaka wersja WiX jest zawarta w CTP – okazuje się, że jest to 3.0.4325.0 – w chwili pisania najnowsza dostępna jest 3.0.4909.0. Z tego co czytałem na blogach RTM VS2010 ma już zawierać najnowszą wersję dostępną w momencie tworzenia release.

05

Dalej już po staremu w VS dostępna jest znana grupa projektów Wix, co ciekawe nadal jest dostępna grupa ze starymi typami projektów seupowych – pewnie raczej w celach zachowania zgodności wstecz.

02

03

Dalej już wszystko po staremu np budując prosty instalator z UI, o którym już kiedyś pisałem. Co cieszy dostępna jest Polska lokalizacja odrazu z paczki.

06 

Konkurs na blog roku

Jeśli spodobał Ci się ten wpis, chciałbyś okazać mi wsparcie i zachęcić do dalszego pisania proszę zagłosuj na mnie w konkursie na blog roku organizowanym przez Onet byłbym bardzo wdzięczny. Wystarczy wysłać smsa B00023( to są zera ) na numer  7144, koszt smsa to 1,22 zł a cały zysk przekazywany jest na organizowanie turnusów rehabilitacyjnych dla dzieci z porażeniem mózgowym – zrobisz 2 dobre uczynki.

image

C2C

Spróbuje również przygotować webcasta o WiX na konkurs speaker idol na konferencję C2C własnie przy pomocy 2010 – żeby być na bleeding edge. Zobaczymy jak wyjdzie nagrywanie ekranu w maszynie wirtualnej – oby dało radę i obym został wybrany – trzymajcie kciuki.

Written by Bartłomiej Szafko

January 15th, 2009 at 11:47 pm

Posted in WiX

Instalator w pliku msi część 4

with 3 comments

W poprzedniej części stworzyłem instalator z interfejsem użytkownika. W tej części zbrandujemy instalator. Po pierwsze wymienię standardowe tło dla okna startowego:

image

W tym celu należ stworzyć własną bitmapę( niestety obsługiwany jest tylko format .bmp) koniecznie o rozmiarze 493 na 312, można również zmodyfikować istniejącą. Nowa bitmapa będzie stanowiła tło całego okna, poza paskiem przycisków.

Aby powiedzieć WiX, żeby podmienić tło należy zmodyfikować wartość zmiennej WixUIDialogBmp:

<WixVariable Id="WixUIDialogBmp" Value="WixUI_Bmp_Dialog.bmp" /> 

Następnie dodam własną licencję użytkownika i wymienię nagłówek okna (biały pasek z brązową płytką cd):

image

W tym celu stworzę bitmapę o rozmiarze 493 na 58 oraz plik Rich Text Format z tekstem mojej licencji. Podobnie jak w poprzednim przypadku muszę tylko ustawić odpowiednie zmienne:

<WixVariable Id="WixUILicenseRtf" Value="license.rtf" />
<WixVariable Id="WixUIBannerBmp" Value="WixUI_Bmp_Banner.bmp" />

Po skompilowaniu okna mogą wyglądać np tak:

image

image

Jak dodatkowy bonus dodam możliwość uruchomienia instalowanej aplikacji na samym końcu:

image

W tym celu trzeba po pierwsze dodać odpowiedni checkbox na ostatnim oknie:

<Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOXTEXT" Value="Skonfiguruj i uruchom aplikację"/>
<Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOX" Value="1"/>

Stworzę również akcję odpowidzialną za uruchomienie aplikacji:

<CustomAction Id="Uruchom" Directory="INSTALLLOCATION"
ExeCommand="[INSTALLLOCATION]WindowsFormsApplication1.exe"
Return="asyncNoWait"/>

Ważne jest pole Return i wartość asyncNoWait, która oznacza że instalator nie musi czekać na wynik działania aplikacji i może kontynuować normalne działanie..

Na koniec podepnę zdarzenie do przycisku “Zakończ” na ostanim oknie polegające na uruchomieniu akcji, ale tylko gdy zaznaczony jest checkbox:

<UI>
  <Publish Dialog="ExitDialog" Control="Finish" Order="2" Event="DoAction" Value="Uruchom">
    WIXUI_EXITDIALOGOPTIONALCHECKBOX
  </Publish>
</UI>

Wszystko jeszcze raz można zobaczyć na filmie

Written by Bartłomiej Szafko

December 21st, 2008 at 12:59 pm

Posted in WiX

WIX w Visual Studio 2010

with 2 comments

image

Po PDC 2008 pojawiło się bardzo dużo informacji o nowym Visual Studio określanym mianem 2010.

Ja chciałbym się skupić tylko na jednej funkcjonalności, mianowicie VS będzie zawierać WiX. Dla mnie to jest super informacja, bo w IDE do tej pory brakowało dobrego narzędzia do budowania setupów.

Wersja, która zostala udostępniana to z VS CTP to 3.0.4325. Do WiXa nie zostały co prawda dołączone wszystkie rozszerzenia, dodano tylko:

  • WixIIsExtension – konfigurowanie IIS
  • WixNetFxExtension – custom actions dla .NET np NGEN
  • WixSqlExtension – wykonwanie SQLi na MS SQL
  • WixUIExtension – dialogi, interfejs użytkownika, pisałem o tym w jednym z postów o WiX
  • WixUtilExtension – pozwala np na tworzenie linków internetowych
  • WixVSExtension  – pozwala na sprawdzanie zainstalowanej wersji VS oraz dodawanie VSPackages

Mam nadzieję, że w wersji RTM znajdą się już wszystkie rozszerzenia.

Włączanie projektów open source od samego visual studio ( tak jak np.: jQuery) to świetna informacja dla nas developerów. Gwarantuje nam, że dostajemy przetestowane projekty, które już się sprawdziły. Ciekaw jestem jak to wygląda od strony prawnej…

Źródło: blog Boba Arnsona – Joy Of Setup

Written by Bartłomiej Szafko

November 6th, 2008 at 12:04 am

Posted in WiX

Instalator w pliku msi część 3

without comments

W poprzednim artykule zbudowałem podstawowy instalator w MSI za pomocą Windows Installer Xml. Jego wygląd pozostawiał bardzo wiele od życzenia – nie wyświetlał nic oprócz nudnego progress bara, a użytkownik nie miał możliwości np wyboru folderu docelowego.

W tym poście dodam interfejs użytkownika pozwalający na wybór typu instalacji, ustawienie folderu docelowego oraz wybór feature. Dodatkowo przy ponownym uruchomieniu zainstalowanego już produktu pojawi się okienko dające nam możliwość usunięcia, naprawienia albo zmiany parametrów instalacji.

WiX domyślnie zawiera mechanizmy pozwalające na szybkie dodanie interefejsu użytkownika. Biblioteka WiXUiExtension.dll  zawiera skompilowane skrypty wxs definiujące okna dialogowe. Nawiasem mówiąc podczas mojej prezentacji w Krakowie wywiązała się ciekawa dyskusja na temat czy jest to natywna biblioteka czy nie. Okazuje się że jest to assembly .netowe i w resourcach umieszczona jest skompilowana biblioteka wixlib, która jest dołączana do wynikowego instalatora.

Żeby wzbogacić instalatora z poprzedniego artykułu należy najpierw dodać referencje do WixUiExtension.dll:

wixcz0301

wixcz0302

Jedyne, co tak naprawdę musimy dodać to element UIRef:

<UIRef Id="WixUI_Mondo"/>

Wix wspiera parę rodzajow interfejsów użytkownika:

  • WixUI_Mondo – pełny interfejs z możliwością określenia rodzaju instalacji(pełna, domyślna, użytkownika), określeniem foldru docelowego(jeśli na to zezwoliśmy)
  • WixUI_FeatureTree – pozwala na wybór feature
  • WixUI_InstallDir – pozwalający tylko na wybór docelowego folderu
  • WixUI_Minimal – tylko zgoda na licencje oprogramowania

Ostatecznie zmodyfkownay skrypt jest poniżej zwróć uwagę na ustawienia codepage oraz language:

<?xml version="1.0" encoding="windows-1250"?>
  <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">

    <Product Id="5c899cab-095c-4f4e-a57e-9b03dc4cd322" Name="WixDemo2" Language="1045" Codepage="1250" Version="1.0.0.0" 

           Manufacturer="WixDemo2" UpgradeCode="994dbe73-b654-482d-8dfd-3dcdc54d0f30">

        <Package InstallerVersion="200" Compressed="yes" />

        <Media Id="1" Cabinet="WixDemo2.cab" EmbedCab="yes" />

        <Directory Id="TARGETDIR" Name="SourceDir">

            <Directory Id="ProgramFilesFolder">

                <Directory Id="INSTALLLOCATION" Name="WixDemo2">                                        <Component Id="ProductComponent" Guid="53f6485a-8034-4022-9386-ca83dbe3cc07">

            <File Id="Exe" Source="..\WindowsFormsApplication1\bin\Debug\WindowsFormsApplication1.exe"/>

                    </Component>

                </Directory>

            </Directory>

        </Directory>

        <Feature Id="ProductFeature" Title="WixDemo2" Level="1" ConfigurableDirectory="INSTALLLOCATION">

            <ComponentRef Id="ProductComponent" />

        </Feature>

    <UIRef Id="WixUI_Mondo"/>

    </Product>

</Wix>

Warto też skorzystać z ustawień projektu i zmienić domyślny język na pl-PL będziemy wtedy mieli instalator po polsku. Na szczęście WiX zawiera domyślnie polskie lokalizacje więc nie  musimy się martwić o tłumaczenie:

wixcz0303

Po tych operacjach instalator będzie miał interfejs i polskie teksty, jak to wygląda można zobaczyć na filmie:


wix część 3 – user interface from bartek szafko on Vimeo.

Written by Bartłomiej Szafko

November 1st, 2008 at 1:18 am

Posted in WiX

Instalator w pliku msi część 2

with one comment

Po krótkim wstępie teoretycznym w poprzednim artykule w tej części pokażę jak stworzyć swój pierwszy(prosty;)) instalator za pomocą Windows Installer XML.

Po zainstalowaniu Wixa np stąd w Visual Studio pojawi się nowy typ projektu(jeśli używasz jeszcze wersji 2005 nie zapomnij o ProjectAgregator.msi, a najlepiej przerzuć się na 2008):


W tym momencie posłużę się typem Wix Project.

Domyślnie projekt zawiera tylko jeden plik WixProject.wxs:

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
        <Product Id="b9351b34-7683-4640-8fdf-dc34c12c3fa1"
             Name="PUT-PRODUCT-NAME-HERE"
             Language="1033"
             Version="1.0.0.0"
             Manufacturer="PUT-COMPANY-NAME-HERE"
             UpgradeCode="077c926e-d3f7-40dd-a6cf-5c5cc82893f2">
        <Package InstallerVersion="200" Compressed="yes" />

        <Media Id="1" Cabinet="WixProject.cab" EmbedCab="yes" />

        <Directory Id="TARGETDIR" Name="SourceDir">
            <Directory Id="ProgramFilesFolder">
                <Directory Id="INSTALLLOCATION" Name="PUT-APPLICATION-DIRECTORY-HERE">

                    <Component Id="ProductComponent" Guid="ee728cb7-f2b3-41d0-9ea5-59ebf659f8d2">
                        <!-- TODO: Insert your files, registry keys, and other resources here. -->
                    </Component>

                </Directory>
            </Directory>
        </Directory>

        <Feature Id="ProductFeature" Title="PUT-FEATURE-TITLE-HERE" Level="1">
            <ComponentRef Id="ProductComponent" />
        </Feature>
    </Product>
</Wix>

XmlNs

Warto zwrócić uwagę na namespace, ponieważ pozwala szybko określić czy skrypt został utworzony dla wersji 3.0 (http://schemas.microsoft.com/wix/2006/wi), czy 2.0 (http://schemas.microsoft.com/wix/2003/01/wi).

Element Product

Atrybuty wpisane w tym elemencie zapisywane są w tabeli Property i służą do identyfikowania instalatorów. Niektóre są wymagane:

  • Id – unikalny identyfikator instalatora, dla każdej wersji powinien być inny; odpowiada wartości o nazwie ProductCode z tabeli Property
  • Name – nazwa produktu, po prostu jakiś string opisujący Twoją aplikację odpowiada ProductName
  • Language – język, w którym zbudowany jest instalator; jest to kod LCID języka, domyślna wartość to 1033 czyli język angielski; to pole ma znaczenie przy tworzeniu lokalizowanych instalatorów (o tym później); odpowiada ProductLanguage
  • Version – znany z .net symbol wersji w formacie major.minor.build.revision, ciekawostką, jest że .revision jest pomijane; odpowiada ProductVersion
  • Manufacturer – producent oprogramowania, albo twoje imię i nazwisko; odpowiada Manufacturer(tak samo)
  • UpgradeCode – po tym guidzie wyszukiwane są produkty do podniesienia wersji; jeśli tworzysz wiele instalatorów dla różnych wersji i chcesz żeby bezproblemowo można było dokonać upgradu to trzeba pamiętać, że ten GUID powinien pozostać stały. Zapobiega to wielokrotnemu pojawianiu się elementów w Dodaj/Usuń programy w panelu sterowania

Element Package

Wymagane są tylko 2 pola:

  • InstallerVersion – określa wersje wymaganego WindowsInstallera zgodnie z wzorem: major*100 + minor
  • Compressed – określa czy pliki zawarte w instalatorze mają podlegać kompresji

Reszta pól jest dziedziczona z elementu Product. Cała zawartość elementu Package ląduje w strumieniu Summary Information, który może być odczytywany bezpośrednie z windows explorera.

Element Media

Pozwala na podanie zbioru zawierającego instalowane pliki(atrybut Cabinet) i podania czy wejdzie w skład instalatora(EmbedCab). Jeśli nie podamy żadnego z tych elementów instalator nie będzie zawierał plików źródłowych, trzeba je będzie normalnie skopiować do lokalizacji pliku .msi, ale tego byśmy raczej nie chcieli ;)

Element(y) Directory

Służą do określenia struktury folderów, w której ma zostać zainstalowana aplikacja. Poszczególne zagnieżdżenia pokazują jak foldery są tworzone w głąb. Pierwszy wpis( TARGETDIR, SourceDir) jest wirtualny i służy do definiowania korzenia struktury folderów.

W atrybucie ID podaje się nazwę właściwości (pisana w WiX dużymi literami), która może być później używana w innych miejscach w instalatorze. Istnieją predefiniowane wartości parametru ID pozwalające na odwołanie się do standardowych lokalizacji:ProgramFilesFolder, ProgramMenuFolder, DesktopFolder. Pełna lista znajduje się tutaj. Atrybut Id często jest używany do odwołań w innych miejscach, więc należy zadbać żeby był unikalny.

Warto stosować spójny system wartości ID w całym skrypcie np.: wszystkie katalogi nazywać D_NAZWAFOLDERU.

Zalecana struktura folderów to “/Program Files/Firma/Produkt”, chociaż w praktyce spotyka się “/Program Files/Firma Produkt”.

Element(y) Component

Zagnieżdżony w elemencie Directory. To kluczowy element skryptu Wix i najczęstsze źródło błędów podczas instalacji. Komponent jest najmniejszym zestawem “rzeczy”, które mogą zostać zainstalowane: plików, skrótów, rejestrów. W skrypcie może istnieć wiele komponentów, najważniejsze żeby były niezależne:

  • w 2 komponentach nie mogą być zawarte te same pliki w tych samych lokalizacjach
  • odinstalowanie komponentu, nie powinno zostawiać żadnych śmieci,
  • odinstalowanie komponentu nie może mieć wpływu na inne komponenty

Komponenty to klocki z których składami konkretne funkcjonalności, czyli działającą aplikację. Jeden komponent powinien zawierać elementy, które tworzą wspólną całość. Komponenty mogą być współdzielone przez funkcjonalności np.: gdy mamy 2 aplikacje, które obie korzystają z narzędzia do raportowania (np CrystalReports) i wymagają odpowiednich zarejestrowanych bibliotek.

Oczywiście należy zwrócić uwagę na nazewnictwo – pole Id musi być unikalne, ale w miarę proste do użycia w innych miejscach. Ja stosuję nazewnictwo typy C_NazwaKomponentu. Pole Guid musi być unikalne.

Przykładowa zawartość komponentu może wyglądać tak:

<Component Id="C_GlownaAplikacja" Guid="ac45b2d6-7e95-487f-a2e2-f56877f16076">
  <File Id="DetalExe" Name="Detal.exe" Source="$(var.Sln.Path)\Detal\bin\$(var.Conf)\Detal.exe" />
  <File Id="DetalExeConfig" Name="Detal.exe.config" Source="$(var.Sln.Path)\Detal\bin\$(var.Conf)\Detal.exe.config" />
</Component>

Spowoduje to zainstalowanie 2 plików, przy okazji użyłem zmiennych preprocesora, ale w celach testowych można spokojnie hardcodować ścieżki.

Element Feature

Pozwala operować na wyższym poziomie i spiąć komponenty w funkcjonalności(feature). Funkcjonalność to jest to co użytkownik będzie miał dostępne do wyboru podczas instalacji ( o ile będziemy mieli wogóle UI;) ) W atrybucie Title wpisujemy przyjazną nazwę jak np.: aplikacja Detal.

Jako dzieci używamy elementów ComponentRef, które zainstalują odpowiednie komponenty.

Instalator

Omówione elementy to podstawy WiXa z ich pomocą można stworzyć podstawowy instalator Na przykład taki:

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
	<Product Id="bda85c5c-a6bb-4212-a213-9fe00ba2d7c4"
           Name="Moja aplikacja" Language="1033" Version="1.0.0.0"
           Manufacturer="bartekszafko.pl" UpgradeCode="6f2d912a-9409-433b-bd5f-bf82ad362291">
		<Package InstallerVersion="200" Compressed="yes" />

		<Media Id="1" Cabinet="WixProject1.cab" EmbedCab="yes" />

		<Directory Id="TARGETDIR" Name="SourceDir">
			<Directory Id="ProgramFilesFolder">
				<Directory Id="INSTALLLOCATION" Name="Moja aplikacja">
					<Component Id="C_MojaAplikacja" Guid="45eee2b7-829c-457b-ab37-ce957f56d1a6">
            <File Id="F_WindowsFormsApplication1" Name="WindowsFormsApplication1.exe"
                  Source="..\WindowsFormsApplication1\bin\Debug\WindowsFormsApplication1.exe" />
          </Component>
				</Directory>
			</Directory>
		</Directory>

		<Feature Id="ProductFeature" Title="Moja aplikacja" Level="1">
			<ComponentRef Id="C_MojaAplikacja" />
		</Feature>
	</Product>
</Wix>

Jako tip: warto dodać do projektu WiX właściwą aplikację jako referencje lub ustawić odpowiedni build order, wtedy zawsze będzie pakować się najnowsza wersja aplikacji.

Po uruchomieniu tak przygotownego pliku .msi będdziemy mogli zobaczyć znajome okienko:

A po wejściu do “Dodaj/usun programy” będzie można usunąć aplikację.

Written by Bartłomiej Szafko

September 15th, 2008 at 8:30 pm

Posted in WiX