インストール・プロジェクト

19 posts

WiX Toolset – CustomAction

インストールの途中でプロダクトキーの入力を求め、正当なインストールかどうか調べるプログラムを作成します。

ソフトメーカーがどのようなプロダクトキー作成アルゴリズムを使っているのか、日本語の情報を見つけることができませんでしたが、Code Projectのサイトにそれらしいものがあります(私自身内容を確認していません)。

今はプロダクトキーの作成方法が論点ではないので、こちらは簡単にして、WiXでCustomActionをどのように作成して、どのように組み込むかをご説明します。

CustomActionは様々な方法で作成できます。PACKT本に詳しく書かれていますが、今回はVBでDllを作成します。

アプリケーションの注文が来たら、ユーザ名を使ったプロダクトキーを作成・返送し、ユーザがソフトをインストールするときに、名前とキーを使ってインストールが正規かどうかチェックします。

入力用のダイアログ画面ではユーザ名、会社名、プロダクトキーの入力用TextBoxがあって、ユーザが入力した値が、USERNAME、COMPANYNAME、PIDKEYグローバル・プロパティにセットされます。

これをチェックする簡単なアクションプログラムを下に示します。セットアップ本体とCustomActionとは、sessionを使って簡単にデータの授受ができます。

プロダクトキーはにユーザ名を16桁のHexで表示したものです。Hexアレイの順番を入れ替えるとか、ダミーの文字を入れるとかするともう少しもっともらしくなります。

VBのプロジェクトを以下のように作成します。Visual Studio 2013で「新しいプロジェクト」をクリック、Windows Installer XMLタブから、VB Custom Action Projectをクリックします。

自動生成されたメインのファイル(CustomAction.vb)を以下のように変更し、ビルドするとCheckPID.CA.dllファイルが作成されます

Imports System.IO
Imports System.Text
Imports Microsoft.Deployment.WindowsInstaller
Public Class CustomActions2
    <CustomAction()> _
    Public Shared Function CheckPID(ByVal session As Session) As ActionResult
        Dim strName As String = session("USERNAME")
        Dim strPid As String = session("PIDKEY")
        Dim O_CheckID = New clsProductKey2("Shift_JIS")
        session("PIDACCEPTED") = O_CheckID.CheckKey(strName, strPid)
        Return ActionResult.Success
    End Function
End Class
Public Class clsProductKey2
    Private enc As Encoding
    Private Const strPpack As String = "m6bk9UoUXzgTvmwv"
    Public Sub New(ByVal encStr As String)
        enc = Encoding.GetEncoding(encStr)
    End Sub
    Public Function CheckKey(P_Name As String, P_ProductKey As String) As String
        Dim strFromName As String = MakeKey(P_Name)
        If strFromName.Equals(DelDelimiter(P_ProductKey, " ")) _
            Or strFromName.Equals(DelDelimiter(P_ProductKey, "-")) Then
            Return "1"
        Else
            Return "0"
        End If
    End Function
    Public Function DelDelimiter(p_strHyphen As String, p_strDelimiter As String) As String
        Dim strArray() As String = p_strHyphen.Split(p_strDelimiter)
        Dim strHex As String = ""
        For Each strOneChar As String In strArray
            strHex &= strOneChar
        Next
        Return strHex
    End Function
    Public Function MakeKey(p_Name As String) As String
        Dim strPackedName As String = p_Name & strPpack
        Dim nameBytes() As Byte = enc.GetBytes(strPackedName)
        Dim str As String = ""
        Dim i As Integer
        For i = 0 To nameBytes.Length - 1
            If i < 8 Then
                str &= String.Format("{0:X2}", nameBytes(i))
            Else
                Exit For
            End If
        Next
        Return str
    End Function
End Class

次回は、プロダクトキー入力ダイアログと、これらをどのようにセットアッププログラムに組み込むか、ご説明いたします。

WiX Toolset – インストール・シーケンス

インストールの途中でユーザにメッセージを出したり、プロダクトキーの入力を促し、キーの正当性を検査したりするには、独自のカスタムアクションを作成し、ユーザインターフェースをカスタマイズしなければいけません。

しかし、解説書の説明は的確ではなく、実際の動作がどうなっているのかよく分からないのですが、ともかく、解説書に書いていることと、実際にやって確認したことをご説明いたします。

参考にした解説は、WiX3.6: A Developer’s Guide to Windows Install XML   (PACKT 2012)と、[WiX Toolset チュートリアル](日本語訳)です。

Windows Installerは、インストールの途中で以下のステップ(アクション)を実行します。この他にも必要であれば、ユーザは独自にアクションを作成し、実行することができます。

FindRelatedProducts
AppSearch
LaunchConditions
ValidateProductID
CostInitialize
FileCost
CostFinalize
MigrateFeatureStates
ExecuteAction
InstallValidate
InstallInitialize
ProcessComponents
UnpublishFeatures
RemoveShortcuts
RemoveFiles
InstallFiles
CreateShortcuts
RegisterUser
RegisterProduct
PublishFeatures
PublishProduct
InstallFinalize
RemoveExistingProducts

実行の順番を変更したり、ユーザのカスタムアクションを挿入することができますが、おおむね上から下に向かって実行されます。

実はこのSequenceは機能的に二つに分けて管理されます。

インストールプログラム(msiファイル)を起動すると、Welcome画面が出たり、ライセンス確認画面が出たり、インストール先のフォルダーを指定したりしますが、「インストールの準備完了」画面まではInstallerはユーザコンピュータに何の変更も加えていません。

「インストールの準備完了」画面でユーザが[インストール]ボタンをクリックすると、
上のExecuteActionが実行され、ここで初めて、インストーラはアプリケーションソフトをユーザ・コンピュータにインストールしていきます。

ExecuteActionから前のSequenceをInstallUISequenceといい、以降をInstallExecuteSequenceといいます。

InstallUISequenceでは上のアクションの最初からExecuteActionまで実行し、InstallExecuteSequenceでもまた最初から最後まで実行します(ExecuteActionを除いて)。

解説では今一つ分からないので、練習プログラムを実行しログをとってみました。
ログからアクション部分だけを抽出したものを下に示します。

 —–InstallUISequence
INSTALL 開始
FindRelatedProducts
PrepareDlg
AppSearch
LaunchConditions
ValidateProductID
CostInitialize
FileCost
CostFinalize
MigrateFeatureStates
WelcomeDlg。Dialog created
LicenseAgreementDlg。Dialog created
UserRegistrationDlg。Dialog created
CheckingPID。
SetupTypeDlg。Dialog created
VerifyReadyDlg。Dialog created
WelcomeDlg。 Dialog created
ProgressDlg。 Dialog created

ExecuteAction 開始
—–InstallExecuteSequence
INSTALL 開始
FindRelatedProducts
LaunchConditions
ValidateProductID
CostInitialize
FileCost
CostFinalize
MigrateFeatureStates
InstallValidate
RemoveExistingProducts
InstallInitialize
ProcessComponents
GenerateScript
ProcessComponents
UnpublishFeatures
UnpublishFeatures
RemoveRegistryValues
RemoveShortcuts
RemoveFiles
RemoveFolders
CreateFolders
InstallFiles
CreateShortcuts
WriteRegistryValues
RegisterUser
RegisterProduct
PublishFeatures
PublishProduct
InstallFinalize
INSTALL。 終了

ExecuteAction。 終了
ExitDialog
INSTALL。 終了

上でUserRegistrationDlgは標準Sequenceに追加したダイアログです。この画面でプロダクトキーを入力し、[次へ]をクリックするとカスタムアクションCheckingPIDがキーの正当性を検査します。

プロダクトキー入力待ち画面では、InstallUISequenceのWelcomeDlg作成アクションまで実行されています。

プロダクトキーが正しければ、下に示す[セットアップの種類の選択]画面が表示されますが、この段階で、InstallUISequenceのCheckingPIDアクションが終了しています。CheckingPIDはInstallExecuteSequenceでも実行されていますが、実際にはどうなっているのか分かりません。

ValidateProductIDアクションは解説書では、プロダクトキーの検査をするとなっていますが、プロダクトキー入力画面が表示される前に実行されていますし、実際になにをしているのかわかりません。

WiX Toolset – ユーザインターフェース

前回ご紹介したコードは、テキストファイルをターゲットコンピュータにインストールし、ショートカットを使って当該ファイルを開くものでした。

しかし、通常このように単純なインストールプログラムはありません。開発者が提供するソフトがユーザコンピュータで動くようにするには、開発ソフトや取扱い説明書や、当該ソフトを支援するさまざまなライブラリーをインストールしなければいけません。

自分で作成したソフトやドキュメントは当然わかっていますが、どれが必要なライブラリーかも的確に知らなければいけません。

VSを使っている場合は「参照設定」画面でライブラリーを確認できます。ここに列挙されるライブラリーをComponent-File要素として追加すればいいと思います。

ただし、Nick RamirezはWiX Tool の heatを使うように推奨しています。試しにHeatを使ってみると沢山のRegistry登録の指示が出てきます。GACのRegistry登録は慎重でなければいけません。私自身、もっとHeatの研究をしなければいけません。

ライブラリー・GACはターゲットコンピュータの所定の場所にインストールしなければいけませんが、対象ディレクトリーを[MyProgramDir]としておけば、WIndows Installerが正しくインストールしてくれるようです。

さて、先の例ではパッケージのインストールが始まると、ライセンスの確認やプロダクトキーの入力画面もなく、一気にインストールが実行されます。

ユーザインターフェースはどのように実現すればいいのか。WiXには、標準の5種類のユーザインターフェースが用意されています。名前は以下の通りで、下になるほどにシンプルな機能になります。

WiXUI_Mondo     すべてのインターフェース機能を備えています
WiXUI_FeaTureTree  セットアップタイプに画面がありません
WiXUI_InstallDir
WiXUI_Minimal
WiXUI_Advanced

使い方はいたって簡単です。
次のように、Product 要素の直下に標準UIへの参照要素を追加するだけです。

<UIRef Id=”WixUI_Mondo” />

ただし、お約束で下の文も追加します。

<UIRef Id=”WixUI_ErrorProgressText” />
<UI />

以下に[WiX チュウトリアル(日本語版)]のサンプルコードを転載します。

<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Product Name="ほげ 1.0" Id="655078FA-567E-4954-9A79-C6612F79FD07" 
	UpgradeCode="B8F470F7-E70B-43CD-A1C2-2FDC274D032E" Language="1041" Codepage="932" 
	Version="1.0.0" Manufacturer="ぴよソフト">
        <Package Id="*" Keywords="インストーラ" Description="ぴよソフト's ほげ 1.0 インストーラ" 
		Comments="ほげはぴよソフトの登録商標です。" Manufacturer="ぴよソフト" InstallerVersion="100" 
		Languages="1041" Compressed="yes" SummaryCodepage="932" />
        <Media Id="1" Cabinet="Sample.cab" EmbedCab="yes" DiskPrompt="CD-ROM 1枚目" />
        <Property Id="DiskPrompt" Value="ぴよソフト's ほげ 1.0 インストーラ [1]" />
        <Directory Id="TARGETDIR" Name="SourceDir">
            <Directory Id="ProgramFilesFolder" Name="PFiles">
                <Directory Id="Piyo" Name="Piyo">
                    <Directory Id="INSTALLDIR" Name="Hoge 1.0">
                        <Component Id="MainExecutable" Guid="DDFC76D3-2E52-4EB2-B4EC-2011E6D0B0F9">
                            <File Id="HogeEXE" Name="HogeAppl10.exe" DiskId="1" Source="HogeAppl10.exe" KeyPath="yes">
                                <Shortcut Id="startmenuHoge10" Directory="ProgramMenuDir" Name="ほげ 1.0" WorkingDirectory="INSTALLDIR" Icon="Hoge10.exe" 
				IconIndex="0" Advertise="yes" />
                                <Shortcut Id="desktopHoge10" Directory="DesktopFolder" Name="ほげ 1.0" WorkingDirectory="INSTALLDIR" Icon="Hoge10.exe" 
				IconIndex="0" Advertise="yes" />
                            </File>
                        </Component>
                        <Component Id="HelperLibrary" Guid="A48F72E2-9ECA-48A0-8CF9-777310CC42D8">
                            <File Id="HelperDLL" Name="HogeHelper.dll" DiskId="1" Source="HogeHelper.dll" KeyPath="yes" />
                        </Component>
                        <Component Id="Manual" Guid="CFB432C9-A032-473A-91B2-03C3CFF2D1D2">
                            <File Id="Manual" Name="Manual.pdf" DiskId="1" Source="Manual.pdf" KeyPath="yes">
                                <Shortcut Id="startmenuManual" Directory="ProgramMenuDir" Name="取扱説明書" Advertise="yes" />
                            </File>
                        </Component>
                    </Directory>
                </Directory>
            </Directory>
            <Directory Id="ProgramMenuFolder" Name="Programs">
                <Directory Id="ProgramMenuDir" Name="ほげ 1.0">
                    <Component Id="ProgramMenuDir" Guid="DD544A7D-1A22-46F9-B491-587B7A0A9D87">
                        <RemoveFolder Id="ProgramMenuDir" On="uninstall" />
                        <RegistryValue Root="HKCU" Key="Software[Manufacturer][ProductName]" 
				Type="string" Value="" KeyPath="yes" />
                    </Component>
                </Directory>
            </Directory>
            <Directory Id="DesktopFolder" Name="Desktop" />
        </Directory>
        <Feature Id="Complete" Title="ほげ 1.0" Description="完全パッケージ。" 
		Display="expand" Level="1" ConfigurableDirectory="INSTALLDIR">
            <Feature Id="MainProgram" Title="プログラム" Description="メインの実行ファイル。" Level="1">
                <ComponentRef Id="MainExecutable" />
                <ComponentRef Id="HelperLibrary" />
                <ComponentRef Id="ProgramMenuDir" />
            </Feature>
            <Feature Id="Documentation" Title="説明書" Description="取扱説明書。" Level="1000">
                <ComponentRef Id="Manual" />
            </Feature>
        </Feature>
        <UIRef Id="WixUI_Mondo" />
        <UIRef Id="WixUI_ErrorProgressText" />
        <Icon Id="Hoge10.exe" SourceFile="HogeAppl10.exe" />
        <UI />
    </Product>
</Wix>

これだけで「ようこそ」画面や「使用許諾契約書」画面が表示されますが、
自分用の「使用許諾契約書」を表示したり、
自分用のプロダクトキーの検証アルゴリズムを追加するには、
少し、修正が必要になります。

WiX Toolset – Directory と Component

前回も書きましたが、インストールとは要するに、アプリケーションソフトをユーザコンピュータの所定の位置に配置して、それを起動するためのショートカットを作ることです。

最初に理解しなければいけないのは、ユーザコンピュータでのフォルダー構造の作成方法と、そのフォルダーに配置するソフトの設定方法です。

フォルダーの構造は、WiXではDirectory 要素を使って定義します。Directoryの定義は特に難しいことはありません。Product 要素の直下、MediaTemplate 要素の次にディレクトリー(Directory)要素を記述します。この要素の必須属性はIdです。

Id属性はDirectory要素に限らず殆どの要素に必須属性で、wxsファイルの中でユニークでなくてはいけません。Name属性はターゲットコンピュータにつけるフォルダー名です。Nameが省略されると、Idがターゲットコンピュータのフォルダー名になります。

システム予約のフォルダー名があります。例を上げます。DesktopFolder、FavoritesFolder、ProgramsFileFolder、ProgramMenuFolder。

Directory 要素はネストすることができます。ネストの深さに制限はありません。

次のXMLはターゲットコンピュータの[ProgramFilesFolder]の下に、[Awesome Software]という名のフォルダーを作り、またメニュー[ProgramMenuFolder]の下に、[ProgramMenuFolder]という名のメニューフォルダーを作っています。

        <!--Directory structure-->
        <Directory Id="TARGETDIR" Name="SourceDir">
            <Directory Id="ProgramFilesFolder">
                <Directory Id="MyProgramDir" Name="Awesome Software" />
            </Directory>
            <Directory Id="ProgramMenuFolder">
                <Directory Id="MyShortcutsDir" Name="Awesome Software" />
            </Directory>
        </Directory>

コンポーネントは、当該ディレクトリーに入れるファイルやショートカットを定義します。コンポーネントはDirectory要素の中に直接記述できますが、Directory構造を見やすくするために、別の場所にDirectoryRef 要素を使ってにコンポーネントを定義します。DirectoryRef 要素のId属性は、参照するDirectory 要素のIdです。これでどのDirectory を参照しているかが分かります。

コンポーネントはユニークなGuidが必要です。

コンポーネントの一つはファイルの定義です。下のコードは[InstallMe.txt]ファイルを[MyProgramDir]ディレクトリーに入れています。コンポーネント要素のの中にFile要素を作成して、この中にファイル情報を書きます。一つのコンポーネントの中に複数のファイルを入れることもできますが、アンインストールで削除されない恐れがあるので、基本的にコンポーネントの中には一つだけのファイルを入れ、[KeyPath=”yes”]を宣言しなければいけません。

        <!--Components-->
        <DirectoryRef Id="MyProgramDir">
            <Component Id="CMP_InstallMeTXT" Guid="E8A58B7B-F031-4548-9BDD-7A6796C8460D">
                <File Id="FILE_InstallMeTXT" Source="InstallMe.txt" KeyPath="yes" />
            </Component>
        </DirectoryRef>

下に、ショートカットの定義を示します。一つのコンポーネントの中に二つのショートカットと[RemoveFolder]、[RegistryValue]を宣言しています。最初のショートカットは[MyProgramDir]にインストールする[InstallMe.txt]にリンクしていますし、二つ目のショートカットは、アンインストールを定義しています。コンポーネントに複数の下位要素がある場合は、どれか一つ最重要な要素に[KeyPath=”yes”]を宣言しなければいけません。

[RemoveFolder]、[RegistryValue]は実はまだよく理解していないのですが、取り敢えずお約束です。

ここで使われている角カッコ[MyProgramDir][ProductCode]等は、[プロパティ値]でこの値は、どこかで定義されています。

        
        <!--Start Menu Shortcuts-->
        <DirectoryRef Id="MyShortcutsDir">
            <Component Id="CMP_DocumentationShortcut" Guid="33741C82-30BF-41AF-8246-44A5DCFCF953">
                <Shortcut Id="DocumentationStartMenuShortcut" Name="Awesome Software Documentation" 
			Description="Read Awesome Software Documentation" 
			Target="[MyProgramDir]InstallMe.txt" />
                <Shortcut Id="UninstallShortcut" Name="Uninstall InstallPractice" 
			Description="Uninstalls Awesome Software" Target="[System64Folder]msiexec.exe" 
			Arguments="/x [ProductCode]" />
                <RemoveFolder Id="RemoveMyShortcutsDir" On="uninstall" />
                <RegistryValue Root="HKCU" Key="SoftwareMicrosoftAwesomeSoftware" 
			Name="installed" Type="integer" Value="1" KeyPath="yes" />
            </Component>
        </DirectoryRef>

下のコードでは[Feature]は一つだけですが、大きなソフトでは、例えばサンプル集やドキュメント等を別扱いにしたいとき、メインのFeature要素の他に、サンプル集Featureを定義します。Featureの下位要素はComponentRef でここでどのコンポーネントを入れるかを定義しています。

        <!--Features-->
        <Feature Id="ProductFeature" Title="Main Product" Level="1">
            <ComponentRef Id="CMP_InstallMeTXT" />
            <ComponentRef Id="CMP_DocumentationShortcut" />
        </Feature>
        <UI />
        <UIRef Id="WixUI_Minimal" />
    </Product>
</Wix>

WiX Toolset – 最初のプロジェクト

私は、自分自身のためにWiXを勉強していて、人様にお教えするような力も立場でもありません。

ただ、[WiX Toolset]を習得すれば、InstallShieldやInstallAwareのようなセットアップ用ソフトを購入しなくても、大抵のことはできそうだし、それにしては、WiXについて特に日本語の解説が非常に少ないので、自分が勉強の途中で引っかかり、解決したことを報告させてもらえば、多少とも誰かのお役に立つかなと思って、勉強進行形をご報告させていただきたいと思います。

現状では、まとまったWiXの解説書としてはNick Ramirezの本が唯一ですが、多分これで十分だろうと考えています。記述は平易ですので、本格的にWiXを勉強したい人は、是非じっくりをお読みになることをお勧めします。

WiX3.6: A Developer’s Guide to Windows Install XML   (PACKT 2012 以下Guideといいます)
WiX Cookbook  (PACKT 2015 以下CookBookといいます)

PACKTのサイトにアクセスしユーザ登録すれば、これらの本のサンプルコードが入手できます。

以下にGuideで最初に取り上げられているコードをご紹介しまします。このプログラムは次の仕事をします。

ターゲットコンピュータの[Program Files]フォルダーの下に、[Awesome Software]というフォルダーを作り、この中に[InstallMe.txt]というファイルをインストールする

また、スタート・メニューに同じく[Awesome Software]フォルダーを作り、この中に上の[InstallMe.txt]ファイルへのショートカットと、アンインストールのショートカットを作り、レジストリー登録の仕組みを設定する

アンインストールでは、インストールしたソフトを少しも残さないで完全に削除する

このプログラムをすべて説明することはできません。WiXに興味ある人は、ご自身で開発環境を作って実行してみてください。ポイントだけを説明します。

まず、[Product][Package]はお約束です。[Product]の[Id]および[UpdateCode]は必須で、全世界でユニークなGUIDをつけなければいけません。

GUIDは[WiX Edit]の中でもVSの中でも簡単に生成できますので、自分の開発環境で再設定しなくてはいけません。

また出荷時に設定したこれらの値をその後変更してはいけません。アンインストールやインストールの変更で支障が出てきます。

[CodePage]=932は、文字コードとしてShfit_JISを使うこと、[Language]=1041は、インストール途中の案内に日本語を使うことを宣言しています。

インストールでは、「何を」「どこへ」が主要な作業です。「何を」はコンポーネントの定義であり、「どこへ」はディレクトリの定義です。

下の画像は、[WiX Edit]の[Files]メニューを開いたところです。

左ペインの上の方に文書ファイルの形をしたアイコンがTree状に配置されています。これはターゲットコンピュータのディレクトリ構造を表示しています。

左ペインの一番上に[SourceDir]があります。右のペインで見るとIdは[TARGETDIR]でNameは[SourceDir]です。

[TARGETDIR]は予約語で、少しわかりにくい概念ですが、要は「ターゲットコンピュータのディレクトリだ」と理解すればいいと思います。Nameは左ペインのアイコンの名前になっています。

SourceDirの下に[ProgramFilesFolder]があります。これも予約語でWindowsに必ず存在する[Program Files]フォルダーです。この下に[Awasome Software]がありますが、[Program FIles]フォルダーの下に[Awasome Software]を作ることを意味しています。
この[Awasome Software]のIdは[MyProgramDir]で、Nameは[Awesome Software]です。

[SourceDir]の直下にもうひとつ[ProgramMenuFolder]があります。これはWindowsが管理しているメニューフォルダーで、Windows7では、[スタート]から見ることができ、
Windows8では、[アプリ]画面でみることができます。

[ProgramMenuFolder]の下に[Awesome Software]というディレクトリを作ります。Idが[MyShortcutsDir]、Nameが[Awesome Software]です。一般にNameはターゲットコンピュータで使われる名前で、IdはWixで使われる一意の名前です。

さてその下に、ファイルの形だが矢印のついたアイコンがあります。これはReferrence(参照)を表現しています。

[MyProgramDir]Referrenceは、どこかで宣言された[MyProgramDir]を参照するという意味です。[MyProgramDir]は[ProgramFilesFolder]直下の[Awasome Software]のIdです。

[MyProgramDir Referrence]の中には[CMP_InstallMeTXT]コンポーネントが定義されています。この中には、[Source]=InstallMe.txtが宣言されていますので、インストールではこのファイルを[MyProgramDir]にコピーすることを意味します。

同様に、[MyShortcutsDir Reference]では、[ProgramMenuFolder]のに入れるべきショートカットを宣言しています。

下にこのプログラムのコードを転記します。WiX Editで編集すれば、下のコードが得られますし、VS等でこのコードを編集すれば、WiX Editのグラフィカル画面が変更されます。

<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" RequiredVersion="3.6.3303.0">
    <Product Id="3E786878-358D-43AD-82D1-1435ADF9F6EA" Name="Awesome Software" 
	Language="1041" Version="1.0.0.0" Manufacturer="Awesome Company" 
	UpgradeCode="B414C827-8D81-4B4A-B3B6-338C06DE3A11" Codepage="932">

        <Package InstallerVersion="301" Compressed="yes" InstallScope="perMachine" Manufacturer="Awesome Company" 
		Description="Installs Awesome Software" Keywords="Practice,Installer,MSI" 
		Comments="(c) 2012 Awesome Company" />
        <MediaTemplate EmbedCab="yes" />
        <!--Directory structure-->
        <Directory Id="TARGETDIR" Name="SourceDir">
            <Directory Id="ProgramFilesFolder">
                <Directory Id="MyProgramDir" Name="Awesome Software" />
            </Directory>
            <Directory Id="ProgramMenuFolder">
                <Directory Id="MyShortcutsDir" Name="Awesome Software" />
            </Directory>
        </Directory>
        <!--Components-->
        <DirectoryRef Id="MyProgramDir">
            <Component Id="CMP_InstallMeTXT" Guid="E8A58B7B-F031-4548-9BDD-7A6796C8460D">
                <File Id="FILE_InstallMeTXT" Source="InstallMe.txt" KeyPath="yes" />
            </Component>
        </DirectoryRef>
        <!--Start Menu Shortcuts-->
        <DirectoryRef Id="MyShortcutsDir">
            <Component Id="CMP_DocumentationShortcut" Guid="33741C82-30BF-41AF-8246-44A5DCFCF953">
                <Shortcut Id="DocumentationStartMenuShortcut" Name="Awesome Software Documentation" 
			Description="Read Awesome Software Documentation" Target="[MyProgramDir]InstallMe.txt" />
                <Shortcut Id="UninstallShortcut" Name="Uninstall InstallPractice" 
			Description="Uninstalls Awesome Software" Target="[System64Folder]msiexec.exe" 
			Arguments="/x [ProductCode]" />
                <RemoveFolder Id="RemoveMyShortcutsDir" On="uninstall" />
                <RegistryValue Root="HKCU" Key="SoftwareMicrosoftAwesomeSoftware" 
			Name="installed" Type="integer" Value="1" KeyPath="yes" />
            </Component>
        </DirectoryRef>
        <!--Features-->
        <Feature Id="ProductFeature" Title="Main Product" Level="1">
            <ComponentRef Id="CMP_InstallMeTXT" />
            <ComponentRef Id="CMP_DocumentationShortcut" />
        </Feature>
        <UI />
        <UIRef Id="WixUI_Minimal" />
    </Product>
</Wix>