Bartek Szafko

all of the bits and pieces

Archive for the ‘WiX’ Category

Windows Installer 4.5 i 5.0 – ciekawa funkcjonalność

without comments

W Windows Vista(Installer 4.5) i Windows 7(installer 5.0) jest całkiem ciekawa funkcjonalność – buforowanie instalatorów msi. Rzecz całkiem przydatna, gdy niespecjalnie lubimy komunikaty w stylu “Nie można znaleźć pliku (ulubiony soft).msi”.

Read the rest of this entry »

Written by Bartłomiej Szafko

Listopad 19th, 2009 at 7:59 pm

WiX: Merge modules

without comments

image

Merge modules to plik z rozszerzniem .msm, który możemy dołączyć do naszego pliku .msi. Zaletą jest to, że na wyjściu dostajemy jeden plik Windows Installera, którego zawartość jest połączona(stąd nazwa merge module) z modułem.

Read the rest of this entry »

Written by Bartłomiej Szafko

Listopad 14th, 2009 at 8:17 pm

Posted in WiX

Tagged with ,

WiX 3.0 jest, 3.5 nadchodzi

without comments

image Jak już pewnie wiecie wersja 3.0 Windows Installer Xml  jako stabilna. Oznacza to, że nie będzie już żadnych rewolucyjnych zmian w drzewie 3.0 poza poprawkami krytycznych błędów. Numer builda to 3.0.5419.0. Więcej można przeczytać na blogu Roba.

Wersja 3.5

Teraz rozpoczęły się pracę nad wersją 3.5 WiX, głównym dodatkiem będzie Burn, czyli bootstrapper(chainer) dla msi. Z tego co pisał Rob na swoim blogu wynika, że będzie można zupełnie ukryć windows installera pod swoim własnym wyglądem. Będzie można też prosto instalować pakiety zależne, a nawet je ściągnąć z sieci. Będzie wreszcie elegancki sposób na zastąpienie własnych bootstrapperów – tak jak to opisałem w jednym z poprzednich wpisów. Więcej o burn można znowu poczytać na blogu Roba.

Jako mały test zainstalowałem już wersję 3.5,  działa zupełnie poprawanie, oglądałem też sposób generowania bootstrappera za pomocą manifestów xmlowych i spróbuje go użyć jak tylko wyjdzie jakaś w miarę stabilna wersja burna. Przy okazji stworzyłem instalator dla BlipFace (wpfowego klienta dla blipa), jest do znalezienia na githubie. Tak na marginesie to było moje pierwsze użycie gita muszę przyznać że filozofia odrobinę inna niż w svn, ale udało mi się szybko dostosować.

Written by Bartłomiej Szafko

Lipiec 19th, 2009 at 3:37 pm

Posted in WiX

Instalowanie komponentów zależnych

with 6 comments

image O tym, że można wykryć czy .NET albo dowolny inny pakiet  jest zainstalowany pisałem w jednym z poprzednich wpisów. Pisałem również, że z poziomu MSI nie można odpalać instalacji innych pakietów.

Dzisiaj pokaże jak szybko stworzyć bootstrappera do plików MSI. W tym celu będę używał bootstrappera znanego z ClickOnce.

Pierwszym krokiem jest wyedytowanie pliku .wixproj i dodanie następującego kawałka kodu:

<ItemGroup>
  <BootstrapperFile Include="Microsoft.Net.Framework.3.5">
    <Visible>False</Visible>
    <ProductName>.NET Framework 3.5</ProductName>
    <Install>true</Install>
  </BootstrapperFile>
</ItemGroup>
<Target Name="AfterBuild">
  <GenerateBootstrapper
ApplicationFile="WixProject3.msi"
ApplicationName="WixProject3"
BootstrapperItems="@(BootstrapperFile)"
OutputPath=".\bin\Debug"
ComponentsLocation="Relative"
Culture="en"
Path="C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bootstrapper"
  />
</Target>

I to właściwie wszystko! Po uruchomieniu budowania projektu WiX w folderze bin\Debug znajdziemy setup.exe, który po uruchomieniu sprawdzi i ewentualnie zainstaluje .NET 3.5, a później odpali plik WixProject3.msi.

Zawartość folderu bin\Debug wygląda mniejwięcej tak:

image

zwróćcie uwagę, że wszystkie pakiety od .neta też wylądowały w tym folderze. Stało się tak ponieważ użyłem ComponentsLocation=”Relative”, ale można również ustawić żeby pobierał się z sieci (więcej o GenerateBootstrapperTask).

Teraz całość (oprócz .wixpdb) możemy zapakować,  najlepiej jakiś selfextractorem ( ja lubie iexpress ) i ustawić wywołanie setup.exe po rozpakowaniu. Trzeba tylko uważać na rozmiar, gdy jeszcze dorzucimy crystala i sql może być już całkiem spory.

Przedstawione przezemnie rozwiązanie ma pewne niedogodności:

Miłej zabawy!

PS. Zastanawiam się, czy by nie opowiedzieć o WiX w ramach Speaker Idola na MTS 2009 – jak myślicie warto ? czy temat zainteresuje publikę ? Na pewno warto zwrócić na niego uwagę szerszej publiczności, bo przez sam Microsoft jest traktowany po macoszemu, pewnie dlatego że jest open source :P

Written by Bartłomiej Szafko

Czerwiec 22nd, 2009 at 8:58 pm

Posted in WiX

Mój artykuł o WiX w SDJournal

with 5 comments

Miła dla mnie wiadomość na początek czerwca – w numerze 06\2009 Software Developer’s Journal ukazał się artykuł o WiX mojego autorstwa:

image image


Przy okazji małe sprostowanie w momencie pisania artykułu WiX miał być częścią VS 2010 później to się zmieniło.

Jeśli chodzi o zawartość artykułu – to jeśli czytasz regularnie mojego bloga nie będzie w nim dla Ciebie żadnych niespodzianek.

Written by Bartłomiej Szafko

Czerwiec 2nd, 2009 at 6:21 pm

Posted in Personal, WiX

WIX – Wykrywanie zainstalowanych MSI

without comments

imageCzasami przy instalacji trzeba stwierdzić czy zainstalowano już jakiś inny MSI. Może to być .NET, serwer SQL, czy może jakiś zupełnie inny produkt.

.NET

Z samym .NETem sprawa jest dosyć prosta. Wystarczy, że użyjemy biblioteki WixNetFxExtension.dll, która realizuje potrzebną nam funkcjonalność:

<PropertyRef Id="NETFRAMEWORK35"/>
<Condition Message=".NET Framework w wersji 3.5 musi być zainstalowany ([NETFRAMEWORK35])">
  NETFRAMEWORK35
</Condition>

Użycie PropertyRef jest konieczne, aby zastała zaimportowana odpowiednia wartości Property z WixNetFxExtension.dll. Dalej już jest prosto definiujemy element Condtion w  InnerText wpisujemy warunek, który musi być ustawiony na TRUE, aby mogła rozpocząć się instalacja – całość ląduje w tabeli LaunchCondition. Własność NETFRAMEWORK35 jest ustawiona na #1 jeśli jest zainstalowany .NET Framework 3.5 . W NetFxExtension jest ustawianych bardzo dużo własności, które mogą nas poinformować o wersji SP, a nawet czy zainstalowano Client Profile. Pełny opis w c:\program files\Windows Installer Xml v3\doc\Wix.chm – hasło “WixNetfxExtension”.

Inne pakiety

Żeby wykryć inne zainstalowane pakiety można użyć np.: RegistrySearch:

<Property Id="NETFRAMEWORK20">
  <RegistrySearch Id="NetFramework20" Root="HKLM" Key="Software\Microsoft\NET Framework Setup\NDP\v2.0.50727" Name="Install" Type="raw" />
</Property>

Co ustawi, własność NETFRAMEWORK20 na wynik wyszukiwania wartości klucza w rejestrze – tak naprawdę taką metodą posługuje się NetFxExtension.

Innną metodą jest wyszukiwanie konkretnego zainstalowanego komponentu za pomocą ComponentSearch:

<Property Id="VS2005PROJECTAGGREGATOR2">
  <ComponentSearch Id="VS2005ProjectAggregator2Search" Guid="B0BB80E0-5CCC-474E-A75E-05DC1AE073BC" />
</Property>

Musimy w takiej sytuacji znać Guid komponentu.

Inne możliwości to:

Instalacja zależnych pakietów

W samym pakiecie MSI nie możemy wywoływać instalacji innych pakietów MSI, jest to zabronione. Możemy do naszego instalatora dołączyć tzw. Merge Module, czyli plik z rozszerzeniem .msm, ale takie pliki rzadko są dostarczane przez producentów.

Jedyną skuteczną metodą na zainstalowanie np. .NETa przed instalacją naszej aplikacji jest użycie tzw. MSI chainera, który instaluje pliki .MSI jeden po drugim. Można też posłużyć się czymś bardziej zaawansowanym – bootstrapperem od clickonce. Temat chainera i bootstrappera to sprawa na osobny wpis, a właściwie całą serię.

Written by Bartłomiej Szafko

Maj 27th, 2009 at 10:42 pm

Posted in WiX

Wix – wyświetlanie kopiowanych plików

without comments

imageNie wiem czy zauważyliście, ale przy domyślnie stworzony instalatorach w WiX okno postępu instalacji nigdy nie wyświetla dokładnie jakie pliki, klucze rejestru są zakładane i kopiowane, wyświetla się tylko dosyć ogólna informacja “Kopiowanie nowych plików”:

image

Na przykład instalator od resharpera wyświetla bardzo sczegółowe info o tym co się dzieje:

image

Żeby dodać podobny efekt, musimy zmodyfikować interfejs użytkownika dodać nową kontrolkę i zasubskrybować jej zawartość do zdarzenia ActionData:

<Control Id="ActionData" Type="Text" X="59" Y="165" Width="273" Height="41" Transparent="yes" TabSkip="no">
  <Subscribe Event="ActionData" Attribute="Text" />
</Control>

Niby prosta modyfikacja, ale wymaga albo zbudowania WiXa od nowa(chociaż UIExtension) albo dodania całego UI do swojego projektu instalatora – co ma niewątpliwe zalety na przyszłość, będzie można trochę poszaleć i np stworzyć coś podobnego do resharpera. BTW instalator resharpera jest dobrym miejscem do podejrzenia jak zrobić parę ciekawych rzeczy w wix – więc orca w dłoń i do roboty.

Written by Bartłomiej Szafko

Maj 18th, 2009 at 10:45 pm

Posted in WiX

Tagged with , ,

Wix w Visual Studio Express

without comments

image

Bartek zadał pytanie:

Od pewnego czasu szukam narzędzia do robienia instalek (lepszego niż z VS) testowałem już advanced installer i instalshield teraz znalazlem twoj opis WIX ale żedne z tych narzędzi nie integruje się z VS2008 express. Moje pytanie "Czy jest na to jakiś sposób" czy też muszę przejść na wyższą pułkę?

Wtyczka Votive, która dodaje nowy typ projektu – WixProj i pozwala na uruchomienie Candle i Light z poziomu Visual Studio niestety nie działa w wersji Express. Wersja ta ma wogóle wyłączoną możliwość instalacji dodatków( poza chlubnym wyjątkiem jakim jest TestDriven.net). Brak Votive jednak nie uniemożliwia użycia Wixa.

Wtyczka votive uruchamia aplikacje Candle i Light. Możemy zrobić to samo posługując się “Post build event” we właściwościach projektu:

image

A plik buildmsi.bat może mieć postać zbliżoną do:

"%wix%bin\candle.exe" -out obj\Debug\Product.wixobj -arch x86 -ext "%wix%bin\WixUIExtension.dll" Product.wxs
"%wix%bin\Light.exe" -cultures:pl-PL -ext "%wix%WixUIExtension.dll" -out bin\Debug\WixProject2.msi -pdbout bin\Debug\WixProject2.wixpdb obj\Debug\Product.wixobj

W zależności od tego w jaki sposób zbudowaliśmy Product.wxs do candle może trzeba będzie podać dodakowe komendy -Dnazwaparametru=wartosc. Zmienna %Wix% jest ustawiana przez instalator podczas konfigurowania Wixa.

Written by Bartłomiej Szafko

Maj 10th, 2009 at 2:10 pm

Posted in WiX

Tagged with ,

Instalator w pliku msi część 7 – generowanie listy plików do instalacji

without comments

W poprzednich częściach o WiX:

Jakiś czas temu Szymon Kobalczyk i Marcin Książek pytali o możliwość automatycznego tworzenia skryptów WxS w oparciu o stworzone przez projekt. Taki mechanizm byłby szczególnie przydatny dla projektów, w których często zmieniają się pliki, które muszą być zainstalowane np: dla aplikacji webowych. Gdy zajrzałem do jednego ze starych projektów stwierdziłem, że używałem do tego dosyć rozbudowanego skryptu Wsh.

W wix3 istnieje całkiem przydatny program narzędziowy, który pozwala właśnie na stworzenie pliku wxs. Aplikacja nazwya się heat. Przy wywoływaniu heat-a ważny jest tzw. harvester, czy zbieracz plików. Przykładowymi harvesterami jest directory, który zbiera wszystkie pliki z folderu oraz project, który tworzy wxs na podstawie wyniku projektu z VS.

Przykładowe wywołanie może wyglądać tak:

heat.exe project myproj.csproj -sfrag -srd -gg -suid -pog:Binaries -pog:Content -out Files.wxs

Omówie po kolei wszystkie parametry:

Plik Files.wxs będzie miał taką postać:

<?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="{0CCD4E1F-0AD8-40F3-B741-7A11E3E70D99}">
                <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>
    <Fragment>
        <DirectoryRef Id="c2csi.Content">
            <Component Id="c2csi.Content.XMLFile1.xml" Guid="{41E641F5-C0CA-470B-A7F2-73EF37B49A5F}">
                <File Id="c2csi.Content.XMLFile1.xml" Source="$(var.c2csi.ProjectDir)\XMLFile1.xml" />
            </Component>
        </DirectoryRef>
    </Fragment>
    <Fragment>
        <ComponentGroup Id="c2csi.Content">
            <ComponentRef Id="c2csi.Content.XMLFile1.xml" />
        </ComponentGroup>
    </Fragment>
</Wix>

Dodatkowo do tego główny skrypt:

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Product Id="00225fb3-42b1-4404-a595-f9a1c9ad5d16" Name="WixProject2" Language="1045" Version="1.0.0.0" Manufacturer="WixProject2" UpgradeCode="4dd7c3bd-1d88-4d2b-8da9-fd39b11b2653" Codepage="1250">
        <Package InstallerVersion="200" Compressed="yes" />

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

        <Directory Id="TARGETDIR" Name="SourceDir">
            <Directory Id="ProgramFilesFolder">
                <Directory Id="c2csi.Binaries" Name="WixProject2">
                </Directory>
            </Directory>
        </Directory>

        <Feature Id="ProductFeature" Title="WixProject2" Level="1">
      <ComponentGroupRef Id="c2csi.Binaries"/>
        </Feature>
    </Product>
</Wix>

Trzymanie plików w osobnym skrypcie WxS jest dobrą praktyką, natomiast z automatycznym generowaniem należy być ostrożnym może to spowodować nieprzewidziane problemy.

Uruchamianie heat warto wrzucić do before build action do projektu wix.

Written by Bartłomiej Szafko

Kwiecień 30th, 2009 at 8:26 pm

Posted in WiX

Tagged with ,

[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

Kwiecień 24th, 2009 at 7:46 pm

Posted in WiX

Tagged with , , ,