Visual Studio Installer
使用Windows Installer 4.0作为安装程序包
InstallShield
探索InstallShield——制作一个完整的应用程序安装实例
从Visual Studio 2012开始,微软就把自家原来的安装与部署工具彻底废掉了,转而让大家去安装使用第三方的打包工具“InstallShield Limited Edition for Visual Studio”,注意这个版本是免费的,只需要邮件注册下,就会有要注册码。
Inno
帮助文档:http://www.jrsoftware.org/ishelp
https://github.com/jrsoftware/issrc
官网上下载的不能新建中文项目,所以还是到网上找汉化版的吧。
"ISCC.exe" "%~dp0..\Inno Setup\PeriodicalEditor.iss"
语言包列表
http://www.jrsoftware.org/files/istrans/
自定义安装目录:
读取注册表时区分操作系统64或32位
[Code]
function GetHKLM:Integer;
begin
if IsWin64 then
Result:=HKLM64
else
Result:=HKLM32
end;
DefaultDirName={code:GetPath}
//获取安装路径
function GetPath(Param: String): String;
var
strPath: String;
begin
strPath := ExpandConstant('{pf}\{#MyAppName}');
if
RegQueryStringValue(GetHKLM,'Software\Microsoft\Windows\CurrentVersion\App Paths\XSX.exe', 'Path', strPath)
then
begin
//MsgBox('安装路径为: ' + strPath, mbInformation, MB_OK)
strPath:=strPath+'\Plugins\PeriodicalEditor\'
//strPath := ExtractFilePath(strPath);
end;
Result := strPath;
end;
创建自定义向导页
https://blog.csdn.net/bingqingsuimeng/article/details/78424275
自定义向导页需要在InitializeWizard事件函数中创建,通过使用CreateCustomPage函数创建一个空的页面,或者使用CreateInput…Page和CreateOutput…Page等函数创建预建的页面,例如CreateInputDirPage、CreateInputFilePage、CreateOutputProgressPage等函数。当创建好了页面之后,就可以在页面上添加控件了,可以手动创建控件,也可以使用预建页面的特殊函数。大部分的Create…Page函数的第一个参数通常都是Page ID,该参数指定了新创建的页面被放在哪个已存在的页面后面。
单选对话框
[INI]
Filename: "{app}\TaskMan.INI"; Section: "System"; Key: "UseHtmlPanel"; String: "{code:GetLanguage}";
[Code]
var
Page: TInputOptionWizardPage;
sLanguage: String;
procedure InitializeWizard;
begin
// Create the page
Page := CreateInputOptionPage(wpSelectDir,'选择语言版本', '', '选择程序语言版本', True, False);
// Add items
Page.Add('汉文、藏文及朝文');
Page.Add('蒙文');
// Set initial values (optional)
Page.Values[0] := True;
Page.Values[1] := False;
end;
function GetLanguage(Param: String): String;
begin
case Page.SelectedValueIndex of
0: sLanguage := '1';
1: sLanguage := '2';
end;
Result := sLanguage ;
end;
一个比较完整的Inno Setup 安装脚本
[Setup]
; 注: AppId的值为单独标识该应用程序。
; 不要为其他安装程序使用相同的AppId值。
; (生成新的GUID,点击 工具|在IDE中生成GUID。)
AppId={{A9861883-31C5-4324-BD9A-DC3271EEB675}
;程序名
AppName=ISsample
;版本号
AppVerName=ISsample 1.0.0.0
;发布者名
AppPublisher=Hkiss
;相关连接
AppPublisherURL=http://zwkufo.blog.163.com
AppSupportURL=http://zwkufo.blog.163.com
AppUpdatesURL=http://zwkufo.blog.163.com
;默认安装目录
DefaultDirName={pf}\ISsample
;默认开始菜单名
DefaultGroupName=ISsample
;是否打开->可选安装开始菜单项
;AllowNoIcons=yes
;安装协议
;LicenseFile=C:\Example\原始文件\agreement.txt
;安装前查看的文本文件
;InfoBeforeFile=C:\Example\原始文件\Setup_New.txt
;安装后查看文本文件
;InfoAfterFile=C:\Example\原始文件\Setup_Old.txt
;输出文件夹
OutputDir=C:\Example\InnoSetup\out
;输出文件名
OutputBaseFilename=setup
;安装图标
SetupIconFile=C:\Example\原始文件\title.ico
;安装需要输入密码
;Password=123
;Encryption=yes
;压缩相关
Compression=lzma
SolidCompression=yes
;可以让用户忽略选择语言相关
ShowLanguageDialog = yes
;备注版本信息
VersionInfoCompany=HTTP://www.Hkiss.COM
VersionInfoDescription=ISsample 汉化增强版
VersionInfoVersion=1.0.0.0
VersionInfoCopyright=Copyright (C) 2007-2008 Hkiss
;制作选择语言
[Languages]
Name: "chs"; MessagesFile: "compiler:Default.isl" ;LicenSeFile :"C:\Example\原始文件\chs\agreement.txt"
Name: "en"; MessagesFile: "compiler:Languages\English.isl";LicenSeFile :"C:\Example\原始文件\en\agreement.txt"
;用户定制任务
[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
Name: "Tasks_1" ; Description:"用户自定义任务1"; Flags: unchecked
Name: "Tasks_2" ; Description:"用户自定义任务2"; Flags: unchecked
;选择了组件才会出现的定制任务
Name: "Tasks_3" ; Description:"用户自定义任务3";Components: c1 ; Flags: unchecked
;文件安装
[Files]
;多语言安装环境设置 公共参数Languages 来设置
Source: "C:\Example\原始文件\enfile.txt"; DestDir: "{app}"; Languages: en ; Flags: ignoreversion
Source: "C:\Example\原始文件\chsfile.txt"; DestDir: "{app}"; Languages: chs ; Flags: ignoreversion
;用户自定义任务 Tasks
Source: "C:\Example\原始文件\Tasks\tasks_1.txt"; DestDir: "{app}\Tasks"; Flags: ignoreversion ;Tasks : Tasks_1
Source: "C:\Example\原始文件\Tasks\tasks_2.txt"; DestDir: "{app}\Tasks"; Flags: ignoreversion ;Tasks :Tasks_2
Source: "C:\Example\原始文件\Tasks\tasks_Components.txt"; DestDir: "{app}\Tasks"; Flags: ignoreversion ;Tasks :Tasks_2
;用户定义组件安装
Source: "C:\Example\原始文件\Components\Components_1.txt"; DestDir: "{app}\Components"; Flags: ignoreversion ; Components: a1;
Source: "C:\Example\原始文件\Components\Components_2.txt"; DestDir: "{app}\Components"; Flags: ignoreversion ; Components: a2;
Source: "C:\Example\原始文件\Components\Components_3.txt"; DestDir: "{app}\Components"; Flags: ignoreversion ; Components: a3;
Source: "C:\Example\原始文件\Components\Components_4.txt"; DestDir: "{app}\Components"; Flags: ignoreversion ; Components: a1 a2 a3;
;用户注册自定义Dll文件 regserver 注册 noregerror 不显示错误信息
Source: "C:\Example\原始文件\jmail.dll"; DestDir: "{app}"; Flags: ignoreversion regserver
;添加自述文件
Source: "C:\Example\原始文件\ISsample.txt"; DestDir: "{app}"; Flags: ignoreversion
;添加一个文件到缓存文件夹{Tmp} deleteafterinstall 安装后删除
Source: "C:\Example\原始文件\test.exe"; DestDir: "{tmp}"; Flags: ignoreversion deleteafterinstall
Source: "C:\Example\原始文件\ISsample.chm"; DestDir: "{app}"; Flags: ignoreversion
Source: "C:\Example\原始文件\ISsample.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "C:\Example\原始文件\ISsample.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "C:\Example\原始文件\ISsample.ini"; DestDir: "{app}"; Flags: ignoreversion
Source: "C:\Example\原始文件\ISsample.rar"; DestDir: "{app}"; Flags: ignoreversion
Source: "C:\Example\原始文件\ISsample_sys.dll"; DestDir: "{win}\System32"; Flags: ignoreversion
Source: "C:\Example\原始文件\log\*"; DestDir: "{app}\log"; Flags: ignoreversion recursesubdirs createallsubdirs
; 注意: 不要在任何共享系统文件上使用“Flags: ignoreversion”
;安装类型设置
[Types]
Name: Full ;Description:"完全安装"; Flags: iscustom
Name: Compact ;Description:"简洁安装";
Name: Custom; Description:"自定义安装";
;组件安装
[Components]
Name: c1; Description: "自定义任务3" ; Types: Full
Name: a1; Description: "安装Components_1"; Types: Full Compact Custom ;
Name: a2; Description: "安装Components_2"; Types : Full Compact
Name: a3; Description: "安装Components_3"; Types : Full
;开始菜单,桌面快捷方式
[Icons]
Name: "{group}\ISsample"; Filename: "{app}\ISsample.exe"
Name: "{group}\{cm:ProgramOnTheWeb,ISsample}"; Filename: "http://zwkufo.blog.163.com"
Name: "{group}\{cm:UninstallProgram,ISsample}"; Filename: "{uninstallexe}"
Name: "{commondesktop}\ISsample"; Filename: "{app}\ISsample.exe"; Tasks: desktopicon
Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\ISsample"; Filename: "{app}\ISsample.exe"; Tasks: quicklaunchicon
;添加一个帮助文挡
Name: {group}\ISsample 1.0.0.0 帮助文档;Filename: {app}\ISsample.chm
;用来在程序安装完成后 在安装程序显示最终对话框之前执行程序 常用与运行主程序 显示自述文件 删除临时文件
[Run]
Filename: "{app}\ISsample.exe"; Description: "{cm:LaunchProgram,ISsample}"; Flags: nowait postinstall skipifsilent
Filename: "{app}\ISsample.txt"; Description: "查看显示自述文件"; Flags: postinstall skipifsilent shellexec
;更改显示在程序中显示的消息文本
[Messages]
BeveledLabel=HKiss科技
;卸载对话框说明
ConfirmUninstall=您真的想要从电脑中卸载ISsample吗?%n%n按 [是] 则完全删除 %1 以及它的所有组件;%n按 [否]则让软件继续留在您的电脑上.
;定义解压说明
;StatusExtractFiles=解压并复制主程序文件及相关库文件...
;用于在用户系统中创建,修改或删除ini文件健值
[INI]
Filename: "{app}\cfg.ini"; Section: "Startup Options"; Flags: uninsdeletesection
Filename: "{app}\cfg.ini"; Section: "Startup Options"; Key: "server ip"; String: "127.0.0.1"
Filename: "{app}\cfg.ini"; Section: "Startup Options"; Key: "server port"; String: "8080"
;用于在用户系统中创建,修改或删除注册表健值
[Registry]
Root: HKLM ;SubKey:"Software\ISsample";ValueType:dword;ValueName:config;ValueData:10 ;Flags:uninsdeletevalue
;在执行脚本
[code]
//全局变量
var MyProgChecked: Boolean;
//判断程序是否存在
//初始华程序事件
function InitializeSetup(): boolean;
var Isbl: boolean; //声明变量
var Isstr: string;
begin //开始
Isbl := true; //变量赋值
Isstr := '欢迎';
if RegValueExists(HKEY_LOCAL_MACHINE, 'SOFTWARE\ISsample', 'config') then
begin
MsgBox('已安装过,请先卸载在安装',mbConfirmation, MB_OK);
isbl := false;
end else
begin
//MsgBox('无值',mbConfirmation, MB_OK);
isbl := true;
end;
//下面是个麻烦的 条件语句 end else 注意
//if MsgBox(Isstr, mbConfirmation, MB_OKCANCEL) = IDOK then
//begin
// isbl := true;
// MsgBox('执行了', mbConfirmation, MB_OK);
//end else
//begin
// isbl := false;
//MsgBox('执行了', mbConfirmation, MB_OK);
//end;
Result := Isbl;
end; //结束
procedure CurStepChanged(CurStep: TSetupStep);
var Isstr :string;
begin
if CurStep=ssInstall then //实际安装前调用
begin
//MsgBox('CurStepChanged:实际安装前调用', mbConfirmation, MB_OKCANCEL); //安装完成后调用
end;
if CurStep=ssPostInstall then
begin
Isstr := ExpandConstant('{tmp}\tmp.rar');
// if FileExists(Isstr) then
// begin
// MsgBox('文件存在',mbConfirmation, MB_OK);
// end else
// begin
// MsgBox('文件不存在',mbConfirmation, MB_OK);
// end;
// MsgBox('CurStepChanged:实际安装后调用', mbConfirmation, MB_OKCANCEL);
end;
end;
//下一步 按钮按钮 事件
function NextButtonClick(CurPageID: Integer): Boolean;
var ResultCode: Integer;
var IsSetup : Boolean;
begin
IsSetup := true ;
case CurPageID of
wpSelectDir:
MsgBox('NextButtonClick:' #13#13 'You selected: ''' + WizardDirValue + '''.', mbInformation, MB_OK); //WizardDirValue路径
wpSelectProgramGroup:
MsgBox('NextButtonClick:' #13#13 'You selected: ''' + WizardGroupValue + '''.', mbInformation, MB_OK); //开始菜单名
wpReady:
begin
if not RegValueExists(HKEY_LOCAL_MACHINE, 'SOFTWARE\Test', 'config') then begin
if MsgBox('程序执行需要Test.ext,是否安装!', mbConfirmation, MB_YESNO) = idYes then begin
ExtractTemporaryFile('test.exe');
if not Exec(ExpandConstant('{tmp}\test.exe'), '', '', SW_SHOWNORMAL, ewWaitUntilTerminated, ResultCode) then
MsgBox('Test.exe出错:' #13#13 ' ' + SysErrorMessage(ResultCode) + '.', mbError, MB_OK);
end else begin
IsSetup := false ;
end ;
BringToFrontAndRestore();
end;
end;
end;
Result := IsSetup;
end;
修改文件某行
procedure test2();
var
fileName,tempStr:String;
svArray: TArrayOfString;
nLines,i:Integer;
begin
fileName := ExpandConstant('{app}\Apache\conf\httpd.conf');
LoadStringsFromFile(fileName, svArray);
nLines := GetArrayLength(svArray);
for i := 0 to nLines - 1 do
begin
tempStr := svArray[i];
if (1 = Pos('ServerRoot', tempStr)) then //Pos函数,判断当前行是否含有'ServerRoot'子串,返回1表示在1的位置找到子串,若不能找到该子串返回0
begin
svArray[i] := ExpandConstant('ServerRoot "{app}\Apache\"'); //修改开头是'ServerRoot'那行文本,此时只是修改内存数据的内容,并未写入文件
StringChangeEx(svArray[i], '\', '/', True); //StringChangeEx函数,将字符串中所有的符号\替换为符号/
end;
if (1 = Pos('Listen', tempStr)) then //找到端口配置行
svArray[i] := 'Listen 80'; //修改Apache端口号
if (1 = Pos('DocumentRoot', tempStr)) then
begin
svArray[i] := ExpandConstant('DocumentRoot "{app}\Apache\htdocs"');
StringChangeEx(svArray[i], '\', '/', True);
end;
if ((1 = Pos('<Directory', tempStr)) and (Pos('htdocs', tempStr) > 1)) then
begin
svArray[i] := ExpandConstant('<Directory "{app}\Apache\htdocs">');
StringChangeEx(svArray[i], '\', '/', True);
end;
end;
SaveStringsToFile(fileName, svArray, false); //最后从内存写回原文件,false表示不追加直接覆盖之前所有内容
end;
查看是否安装运行库
var
vcSP1Missing: Boolean;
function NeedInstallVCSP1(): Boolean;
begin
Result := vcSP1Missing;
end;
function InitializeSetup(): Boolean;
begin
vcSP1Missing := true;
if RegKeyExists(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{710f4c1c-cc18-4c49-8cbf-51240c89a1a2}')
then
begin
vcSP1Missing := false;
end;
result := true;
end;
- Visual C++ 2005 SP1 MFC Security Update Redistributable Package (x86) {710F4C1C-CC18-4C49-8CBF-51240C89A1A2}
- Visual C++ 2010 SP1 Redistributable Package (x86) {F0C3E5D1-1ADE-321E-8167-68EF0DE699A5}
软件是否运行
function IsAppRunning(const FileName : string): Boolean;
var
ProcessRunState :Integer;
begin
result := false;
Exec('cmd.exe', Format('/C tasklist|findstr /i %s',[FileName]), '', SW_HIDE,ewWaitUntilTerminated, ProcessRunState);
if (ProcessRunState = 0) then
begin
result := true;
end;
end;
修改背景图
WizardImageFile=myimage.bmp,myimage2.bmp
100% 164x314
125% 192x386
150% 246x459
175% 273x556
200% 328x604
225% 355x700
250% 410x797
WizardSmallImageFile=mysmallimage.bmp,mysmallimage2.bmp
100% 55x55
125% 64x68
150% 83x80
175% 92x97
200% 110x106
225% 119x123
250% 138x140
数字签名
https://jingyan.baidu.com/article/11c17a2c065713f446e39dc1.html
http://cicada.bajiaohuixiang.com/article/snapshot?id=92&type=clean
其他文档
Pascal Scripting: Support Functions Reference
inno setup读取注册表遇到的一个坑
64位操作系统读取注册表问题:
function GetInstallString(): String;
var
sInstallPath: String;
begin
sInstallPath := 'C:\Program Files\Adobe\Common\Plug-ins\7.0\MediaCore';
if RegValueExists(HKLM64, 'SOFTWARE\Adobe\Premiere Pro\CurrentVersion', 'Plug-InsDir') then
begin
RegQueryStringValue(HKLM64, 'SOFTWARE\Adobe\Premiere Pro\CurrentVersion', 'Plug-InsDir', sInstallPath)
end
Result := sInstallPath;
end;
advanced installer
NSIS
NSIS: Nullsoft Scriptable Install System
牛牛安装包界面美化控件 [nsNiuniuSkin]
http://www.ggniu.cn/download.htm
WixToolSet
http://wixtoolset.org/releases/下载
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="{B7AF3561-68CB-4FEF-8DE4-C011AA462F62}" Name="$(var.PRODUCT_NAME)" Language="1033" Version="1.1.1.1"
Manufacturer="$(var.MANUFACTURER)" UpgradeCode="{780EEB5A-ED25-4E85-AF66-C9EE996B2948}">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<!--net2.0 NETFRAMEWORK20;net3.0 NETFRAMEWORK30 net3.5 NETFRAMEWORK35 net4.0 NETFRAMEWORK40FULL net4.5 NETFRAMEWORK45-->
<PropertyRef Id="NETFRAMEWORK40FULL"></PropertyRef>
<Condition Message="This application requires .NET Framework 4.0.
Please install the .NET Framework then run this installer again.">
<![CDATA[Installed OR NETFRAMEWORK40FULL]]>
</Condition>
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate EmbedCab="yes"/>
<Feature Id="ProductFeature" Title="RandomCodePrintSetup" Level="1">
<ComponentGroupRef Id="ProductComponents" />
</Feature>
<Property Id="WIXUI_INSTALLDIR" Value="INSTALL_FOLDER"/>
<UIRef Id="WixUI_InstallDir"/>
<Icon Id="$(var.ICON_NAME)" SourceFile="$(var.SOURCE_FILE_DIR)/$(var.ICON_NAME)" />
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALL_MANUFACTURER" Name="$(var.MANUFACTURER)" >
<Directory Id="INSTALL_FOLDER" Name="$(var.PRODUCT_NAME)" />
</Directory>
</Directory>
<Directory Id="ProgramMenuFolder">
<Directory Id="ProgramMenuDir" Name="$(var.PRODUCT_NAME)"></Directory>
</Directory>
<Directory Id="DesktopFolder" Name="Desktop" />
</Directory>
</Fragment>
<Fragment>
<ComponentGroup Id="ProductComponents" Directory="INSTALL_FOLDER">
<Component Guid="{FDF4B1C0-E145-4B5B-BD80-B22958C84D6B}" Id="MainApplication">
<File Id="MainApplication" Source="$(var.SOURCE_FILE_DIR)\$(var.APPLICATION_NAME)" DiskId='1' KeyPath='yes'>
</File>
</Component>
<Component Guid="{3E004D4A-7F18-4680-97E8-5B38860208AC}" Id="OtherFile">
<File Id="Config" Source="$(var.SOURCE_FILE_DIR)\Config.dll"></File>
<File Id="TraceLog" Source="$(var.SOURCE_FILE_DIR)\ TraceLog.log"></File>
</Component>
<Component Id="ApplicationShortcut" Guid="{AEFEB53D-37C4-47CD-B7F5-0BF20C08F7B0}">
<Shortcut Id="StartMenuShortcut"
Name="$(var.PRODUCT_NAME)"
Directory="ProgramMenuDir"
Target="[INSTALL_FOLDER]$(var.APPLICATION_NAME)"
WorkingDirectory="INSTALL_FOLDER"
Icon="$(var.ICON_NAME)" IconIndex="0"
/>
<Shortcut Id="DesktopShortcut"
Name="$(var.PRODUCT_NAME)"
Directory="DesktopFolder"
Target="[INSTALL_FOLDER]$(var.APPLICATION_NAME)"
WorkingDirectory="INSTALL_FOLDER"
Icon="$(var.ICON_NAME)" IconIndex="0"
/>
<Shortcut Id="UninstallStartMenu"
Name="Uninstall"
Directory="ProgramMenuDir"
Target="[SystemFolder]msiexec.exe"
Arguments="/x [ProductCode]"
Description="Uninstall"/>
<Shortcut Id="UninstallINSTALL_FOLDER"
Name="Uninstall"
Directory="INSTALL_FOLDER"
Target="[SystemFolder]msiexec.exe"
Arguments="/x [ProductCode]"
Description="Uninstall"/>
<RemoveFolder Id="RemoveShortcutFolder" Directory="ProgramMenuDir" On="uninstall" />
<RegistryKey Root="HKCU" Key="Software\Microsoft\[Manufacturer]\[ProductName]">
<RegistryValue Name="StartMenuShortcut" Type="integer" Value="1" KeyPath="yes" />
<RegistryValue Name='Uninstall' Type='string' Value='Uninstall'/>
</RegistryKey>
</Component>
<Component Id='RemoveFiles' Guid='{F341A78A-44EA-40B7-BDFD-5CA09DF7EB3F}' KeyPath='yes'>
<RemoveFolder Id="INSTALL_FOLDER" Directory="ProgramMenuFolder" On="uninstall" />
<RemoveFolder Id="INSTALL_MANUFACTURER" Directory="ProgramMenuFolder" On="uninstall" />
<RemoveFolder Id="ProgramMenuDir" Directory="ProgramMenuFolder" On="uninstall" />
</Component>
</ComponentGroup>
</Fragment>
</Wix>
http://www.cnblogs.com/stoneniqiu/category/522235.html
https://www.firegiant.com/wix/tutorial/getting-started/the-files-inside/
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<Product Id="*" Name="软件名称v2.0.0" Language="2052" Codepage="936" Version="2.0.0.0" Manufacturer="公司名称" UpgradeCode="6b89c3a7-f25c-4399-9df8-d0b40105cd82">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate />
<!--安装清单-->
<Feature Id="ProductFeature" Title="SetupWixTest" Level="1"> <!--Feature安装清单-->
<ComponentGroupRef Id="ProductComponents" />
<ComponentRef Id="LibsAndFiles"/>
<ComponentRef Id="ApplicationShortcut"/>
<ComponentRef Id="DesktopFolderShortcut"/>
</Feature>
<WixVariable Id="WixUILicenseRtf" Value="license.rtf"/>
<UI> <!--安装风格-->
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLDIR"/>
<UIRef Id="WixUI_InstallDir"/>
</UI>
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder" Name="PFiles">
<Directory Id="INSTALLDIR" Name="SmartTool"> <!--用户选择安装位置-->
</Directory>
</Directory>
<Directory Id="ProgramMenuFolder"> <!--在windows开始菜单中显示-->
<Directory Id="ApplicationProgramsFolder" Name="软件名称"/>
</Directory>
<Directory Id="DesktopFolder" Name="Desktop"/>
</Directory>
</Fragment>
<Fragment> <!--定义需要添加的文件的位置-->
<ComponentGroup Id="ProductComponents" Directory="INSTALLDIR">
<!-- TODO: Remove the comments around this Component element and the ComponentRef below in order to add resources to this installer. -->
<Component Id="ProductComponent">
<File Id="SmartTool.exe" Source="$(var.TianHuangPing.TargetPath)"/>
</Component>
<Component Id="LibOne">
<File Source="$(var.OrderFoodLib.TargetPath)"/>
</Component>
</ComponentGroup>
<DirectoryRef Id="INSTALLDIR">
<Component Id="LibsAndFiles" Guid="ae8c83a1-7615-4439-bf90-4c39db24986f">
<File Id="AutoChangComboBox1.dll" Source="LibFiles/AutoChangComboBox.dll"/>
<File Id="AutoChangCombo1Box.dll" Source="LibFiles/DevExpress.BonusSkins.v16.2.dll"/>
<File Id="AutoCha1ngComboBox.dll" Source="LibFiles/DevExpress.Data.v16.2.dll"/>
<File Id="AutoChang1ComboBox.dll" Source="LibFiles/DevExpress.Printing.v16.2.Core.dll"/>
<File Id="AutoChangC1omboBox.dll" Source="LibFiles/DevExpress.Sparkline.v16.2.Core.dll"/>
<File Id="AutoC1hangComboBox.dll" Source="LibFiles/DevExpress.Utils.v16.2.dll"/>
<File Id="AutoChangComboww1Box.dll" Source="LibFiles/DevExpress.XtraBars.v16.2.dll"/>
<File Id="Aut1oChangComboBox.dll" Source="LibFiles/DevExpress.XtraEditors.v16.2.dll"/>
<File Id="AutoChangCo1mboBox.dll" Source="LibFiles/DevExpress.XtraGrid.v16.2.dll"/>
<File Id="AutoCh2angComboBox.dll" Source="LibFiles/DevExpress.XtraLayout.v16.2.dll"/>
<File Id="AutoChangC2omboBox.dll" Source="LibFiles/DevExpress.XtraPrinting.v16.2.dll"/>
<File Id="Au2toChangComboBox.dll" Source="LibFiles/Impinj.OctaneSdk.dll"/>
<File Id="AutoC2hangComboBox.dll" Source="LibFiles/LLRP.dll"/>
<File Id="AutoChangCombo2Box.dll" Source="LibFiles/LLRP.Impinj.dll"/>
<File Id="AutoChangCombo22Box.dll" Source="LibFiles/MR6100Api.dll"/>
<File Id="configFile" Source="LibFiles/TianHuangPing.exe.config"/>
<File Id="mannifestFile" Source="LibFiles/TianHuangPing.exe.manifest"/>
</Component>
</DirectoryRef>
<DirectoryRef Id="ApplicationProgramsFolder">
<Component Id="ApplicationShortcut" Guid="5A254682-DD5F-453D-8333-144457282026">
<Shortcut Id="LunchApplicationShortcut" Name="软件名称" Description="启动软件名称" Target="[INSTALLDIR]TianHuangPing.exe" WorkingDirectory="INSTALLDIR">
<Icon Id="ico_install" SourceFile="Icons/logo.ico"/>
</Shortcut>
<Shortcut Id="UninstallApplicationShortcut" Name="卸载软件名称" Description="卸载软件名称" Target="[SystemFolder]msiexec.exe" WorkingDirectory="SystemFolder" Arguments="/x [ProductCode]">
<Icon Id="ico_uninstall" SourceFile="Icons/logo.ico"/>
</Shortcut>
<RemoveFolder Id="ApplicationProgramsFolder" On ="uninstall"/>
<RegistryValue Root="HKCU" Key="Software\Microsoft\SmartTool" Name="installed" Type="integer" Value="1" KeyPath="yes"/>
<util:InternetShortcut Id="OnlineDocumentationShortcut" Name="获取在线帮助" Target="http://www.hdu.edu.cn"/>
</Component>
</DirectoryRef>
<DirectoryRef Id="DesktopFolder">
<Component Id="DesktopFolderShortcut" Guid="5A254676-DD1F-453D-8333-144457282027">
<Shortcut Id="DesktopShortcut" Directory="DesktopFolder" Name="软件名称" Target="[INSTALLDIR]TianHuangPing.exe" WorkingDirectory="INSTALLDIR" Icon="ico_install">
</Shortcut>
<RegistryValue Root="HKCU" Key="Software\Microsoft\SmartTool" Name="installed" Type="integer" Value="1" KeyPath="yes"/>
</Component>
</DirectoryRef>
</Fragment>
</Wix>
WixUI_Advanced
:提供了与WixUI_Minimal
类似的一键安装形式,但提供了高级选项按钮。高级选项中,我们可以选择该产品是安装给当前用户还是给所有用户的。
WixAppFolder:指定默认选择当前用户(WixPerUserFolder)还是所有用户(WixPerMachineFolder)。
ApplicationFolderName:来指定产品所安装在的默认文件夹。
WixUI_Minimal
:最小的预定义对话框集合,其将Welcome对话框和协议同意对话框结合,选择协议后就直接安装了。这种对话框集合适用于我们的产品没有自定义部件以及不支持变更安装目录的情况。
WixUI_Mondo
:Welcome、协议同意、安装类型选择、部件选择等自定义安装的对话框,但其不支持安装目录的变更。当我们的产品默认情况下不安装全部部件时,这样典型安装(typical)和完全安装(complete)之间就有个明显的区别,此时推荐使用WixUI_Mondo
WixUI_FeatureTree
:与WixUI_Mondo
的区别是WixUI_FeatureTree
省略了安装类型对话框。协议同意对话框之后就直接到部件(Feature)选择对话框了。当我们的产品默认是安装所有部件时,更推荐采用WixUI_Feature
而不是WixUI_Mondo
。
WixUI_InstallDir
:不支持用户选择安装的部件,但是其增加了让用户选择安装目录的对话框。在Wix文件中需要一个Id为“WIXUI_INSTALLDIR
”的属性来产品要安装的目录的ID(ID必须是全部大写,大写的目的是为了能够让用户在对话框中选择的自定义目录能够回写到相对应ID的Directory元素)。
注意事项
VS要用管理员权限打开,否则权限不够会有各种ICE错误
或者wixproj文件中添加:
<PropertyGroup>
<SuppressValidation>true</SuppressValidation>
</PropertyGroup>
Wix 编译器
准备好了Sample.wxs文件
candle.exe Sample.wxs
light.exe Sample.wixobj
最终封装为Sample.msi文件
XML文档元素
<?xml version='1.0' encoding='windows-1252'?>
<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>
<Product Name='Foobar 1.0' Manufacturer='Acme Ltd.'
Id='YOURGUID-86C7-4D14-AEC0-86416A69ABDE'
UpgradeCode='YOURGUID-7349-453F-94F6-BCB5110BA4FD'
Language='1033' Codepage='1252' Version='1.0.0'>
<Package Id='*' Keywords='Installer' Description="Acme's Foobar 1.0 Installer"
Comments='Foobar is a registered trademark of Acme Ltd.' Manufacturer='Acme Ltd.'
InstallerVersion='100' Languages='1033' Compressed='yes' SummaryCodepage='1252' />
Product
Product 的父级只有wix,主要由Id,Language,等属性
- Id:产品的GUID
- Codepage:指所在地区的代码页,用来进行区域区分
- Language:指所在地区使用的语言,为数字编号,
- Manufacturer:制作厂商
- Name:产品名称
- UpgradeCode:产品更新的GUID,一定要重新生成
- Version:版本号
几个常见的区域代号:
语言 语言-国家 Language Codepage
English en-us 1033 1252
Simplified Chinese zh-cn 2052 936
<?xml version='1.0' encoding='utf-8'?>
<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>
<Product Language='1041' Codepage='932' ...>
<Package Languages='1041' SummaryCodepage='932' ...>
Fragment
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="SetupProject1" />
</Directory>
</Directory>
</Fragment>
<Fragment>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<!-- TODO: Remove the comments around this Component element and the ComponentRef below in order to add resources to this installer. -->
<!-- <Component Id="ProductComponent"> -->
<!-- TODO: Insert files, registry keys, and other resources here. -->
<!-- </Component> -->
<Component Id="ProductComponent">
<File Source="$(var.MyWix.TargetPath)" />
</Component>
</ComponentGroup>
</Fragment>
Fragment 元素是在wix中创建一个安装数据库的基础块(msi文件就是个数据库),定义之后,是不可改变的.它的子元素中含有*Ref的元素必须有对应的单元,比如在Fragment中含有两个Component元素,那么 你必须在Feature中用ComponentRef 与Component对应. 默认生成的文档中含有两个Fragment块。 一个包含的是Directory,一个包含的是ComponentGroup ,前者指的是安装目录,后者顾名思义就是Component的一个集合。
Directory
<Directory Id='TARGETDIR' Name='SourceDir'>
环境提供安装程序预定义名字)
们将使用这三个名称 :ProgramFilesFolder,ProgramMenuFolder, 和DesktopFolder。
在默认的提示中 也可以看见在Component 中添加安装文件,资源,注册表等。这里可以看见最里面的Directory的Id=INSTALLFOLDER是和第二个Fragment中的ComponentGroup的Directory属性是一致的。在Component中就是每一个你需要安装的单元以及它的位置。
<Directory Id="ProgramMenuFolder" Name="Programs">
<Directory Id="ProgramMenuDir" Name="Foobar 1.0">
<Component Id="ProgramMenuDir" Guid="YOURGUID-7E98-44CE-B049-C477CC0A2B00">
<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>
heat 工具
自动生成Components 内容
Condition
条件限制
<Condition Message="You need to be an administrator to install this product.">
AdminUser
</Condition>
指定的 Windows 版本上运行该安装程序
<Condition Message='Windows 95'>Version9X = 400</Condition>
<Condition Message='Windows 95 OSR2.5'>Version9X = 400 AND WindowsBuild = 1111</Condition>
<Condition Message='Windows 98'>Version9X = 410</Condition>
<Condition Message='Windows 98 SE'>Version9X = 410 AND WindowsBuild = 2222</Condition>
<Condition Message='Windows ME'>Version9X = 490</Condition>
<Condition Message='Windows NT4'>VersionNT = 400</Condition>
<Condition Message='Windows NT4 SPn'>VersionNT = 400 AND ServicePackLevel = n</Condition>
<Condition Message='Windows 2000'>VersionNT = 500</Condition>
<Condition Message='Windows 2000 SPn'>VersionNT = 500 AND ServicePackLevel = n</Condition>
<Condition Message='Windows XP'>VersionNT = 501</Condition>
<Condition Message='Windows XP SPn'>VersionNT = 501 AND ServicePackLevel = n</Condition>
<Condition Message='Windows XP Home SPn'>VersionNT = 501 AND MsiNTSuitePersonal AND ServicePackLevel = n</Condition>
<Condition Message='Windows Server 2003'>VersionNT = 502</Condition>
<Condition Message='Windows Vista'>VersionNT = 600</Condition>
<Condition Message='Windows Vista SP1'>VersionNT = 600 AND ServicePackLevel = 1</Condition>
<Condition Message='Windows Server 2008'>VersionNT = 600 AND MsiNTProductType = 3</Condition>
<Condition Message='Windows 7'>VersionNT = 601</Condition>
Property
注册表、INI文件、文件搜索
https://www.firegiant.com/wix/tutorial/getting-started/where-to-install/
Feature
安装条件
Feature 产品的功能列表
一个特性表,特性是可安装的最小单元。 子元素中的ComponentGroupRef 是和 ComponentGroup对应的。前者相当于一个安装目录,后者记录了安装文件的具体位置。
- Id:是唯一的
- Title:就是个短的说明。
- Level:安装的等级,值为0 会使这个特性无效,默认值为1
- Absent:这个属性定义User是否有权在用户接口中去选择使某个特性不安装(absent),值为allow或者disallow之一
其他FILE
可设置注册表
<RegistryKey Id='FoobarRegInstallDir' Root='HKLM' Key='Software\Acme\Foobar 1.0' Action='createAndRemoveOnUninstall'>
<RegistryValue Type='string' Name='InstallDir' Value='[INSTALLDIR]'/>
<RegistryValue Type='integer' Name='Flag' Value='0'/>
</RegistryKey>
设置文件关联
<ProgId Id='AcmeFoobar.xyzfile' Description='Acme Foobar data file'>
<Extension Id='xyz' ContentType='application/xyz'>
<Verb Id='open' Command='Open' TargetFile='FileId' Argument='"%1"' />
</Extension>
</ProgId>
INI文件
<IniFile Id="WriteIntoIniFile" Action="addLine" Key="InstallDir" Name="Foobar.ini" Section="Paths" Value="[INSTALLDIR]" />
RemoveFile
卸载时删除文件
<Component>
...
<RemoveFile Id='LogFile' On='uninstall' Name='Foobar10User.log' />
</Component>
The On attribute will determine when the file will be removed (possible values are install, uninstall and both).
用户接口
提供完整的用户接口的标准安装程序包 , 包括所有标准向导网页 : 许可协定、顾客信息、典型类型 / 自定义 / 完成安装、定制安装的目标文件夹、磁盘使用量的计算要求 , 修改 / 移除 / 修复和回滚。
<Feature Id='Complete' Title='Foobar 1.0' Description='The complete package.'
Display='expand' Level='1' ConfigurableDirectory='INSTALLDIR'>
<Feature Id='MainProgram' Title='Program' Description='The main executable.' Level='1'>
<ComponentRef Id='MainExecutable' />
<ComponentRef Id='HelperLibrary' />
<ComponentRef Id='ProgramMenuDir' />
</Feature>
<Feature Id='Documentation' Title='Description' Description='The instruction manual.' Level='1000'>
<ComponentRef Id='Manual' />
</Feature>
</Feature>
Feature 产品的功能列表
Level允许用户决定哪些功能将被安装。通常的情形是向用户提供三种选择 :典型,完成, 和自定义。
ConfigurableDirectory.通过包括该属性并参照INSTALLDIR因此 , 创建了链接到预定目录中指定作为目标的最里面Directory标签的早些时候 , 我们允许用户改变原定目标。如果我们不使用这个属性 , 用户可以启用和禁用各种特征相同但不能修改安装目录。
UI
wixui 具有五种
- WixUI Mondo 提供完整接口、欢迎页面、许可协议、安装类型 (典型、定制和完成) 、允许功能定制、浏览目录 , 并提供用于所述目标盘。维护模式对话框。
- WixUI FeatureTree 相似的 , 但是它不允许用户选择安装类型。它总是呈定制和功能定制直接进入对话之后的用户已接受的许可协议。
- WixUI InstallDir 允许用户选择一个目的地目录 , 但没有一般常见的特征定制页面。选定的目录之后 , 安装程序将会自动
- WixUI Minimal 简单特征的用户对话框与单个接口结合的欢迎、许可协议页面。之后 , 安装过程没有自动开始 , 允许用户定制。当你的应用程序没有安装到可选的特征。
- WixUI Advanced 有些类似 WixUI Minimal , 因为它提供了一个简单 , 一键安装 , 而且允许选择文件夹功能
为了得到完整的用户界面 , 我们要做的就是添加两行 wixui 接口库包括到我们的项目 :
<uiref ID="WixUI_Mondo" />
<uiref ID="WixUI_ErrorProgressText" />
图标
<Icon Id="Foobar10.exe" SourceFile="FoobarAppl10.exe" />
</Product>
</Wix>
替换文件以及图片
<WixVariable Id="WixUILicenseRtf" Value="path\License.rtf" />
<WixVariable Id="WixUIBannerBmp" Value="path\banner.bmp" />
<WixVariable Id="WixUIDialogBmp" Value="path\dialog.bmp" />
<WixVariable Id="WixUIExclamationIco" Value="path\exclamation.ico" />
<WixVariable Id="WixUIInfoIco" Value="path\information.ico" />
<WixVariable Id="WixUINewIco" Value="path\new.ico" />
<WixVariable Id="WixUIUpIco" Value="path\up.ico" />
- WixUIBannerBmp 493 by 58 pixels, this bitmap will appear at the top of all but the first page of the installer.
- WixUIDialogBmp 493 by 312 pixels, this bitmap will appear on the first page of the installer.
- WixUIExclamationIco 32 by 32 pixels, exclamation mark icon.
- WixUIInfoIco 32 by 32 pixels, information sign icon.
- WixUINewIco 16 by 16 pixels, new folder icon.
- WixUIUpIco 16 by 16 pixels, parent folder icon.
- WixUILicenseRtf Preferably, use a simple editor like Wordpad to create it, or if you insist on overly complex applications like Word, consider resaving the final version from Wordpad, anyway. The RTF will be less complicated and smaller.
加新界面需要修改源代码:https://www.firegiant.com/wix/tutorial/user-interface/new-link-in-the-chain/
本地字符串
itle="!(loc.UserRegistrationDlg_Title)"
添加wxl
<?xml version="1.0" encoding="utf-8"?>
<WixLocalization Culture="fr-fr" Codepage="1252" xmlns="http://schemas.microsoft.com/wix/2006/localization">
<String Id="UserRegistrationDlg_Title" Overridable="yes">???</String>
<String Id="UserRegistrationDlg_UserName" Overridable="yes">???</String>
<String Id="UserRegistrationDlg_Organization" Overridable="yes">???</String>
...
</WixLocalization>
事件和动作
升级和模块化
NET 和. NET
安装.net Frame
要创建Bootstrapper项目,生成exe文件
<PropertyRef Id="NETFRAMEWORK10"/>
<Condition Message='This setup requires the .NET Framework 1.0 installed.'>
<![CDATA[Installed OR NETFRAMEWORK10]]>
</Condition>
简单的示例
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:bal="http://schemas.microsoft.com/wix/BalExtension"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<Bundle Name="..." Version="..." Manufacturer="..." UpgradeCode="..." Copyright="..." IconSourceFile="..." AboutUrl="...">
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense" />
<util:RegistrySearch Root="HKLM" Key="SOFTWARE\Microsoft\Net Framework Setup\NDP\v4\Full" Value="Version" Variable="Net4FullVersion" />
<util:RegistrySearch Root="HKLM" Key="SOFTWARE\Microsoft\Net Framework Setup\NDP\v4\Full" Value="Version" Variable="Net4x64FullVersion" Win64="yes" />
<Chain>
<ExePackage Id="Net45" Name="Microsoft .NET Framework 4.5.1 Setup" Cache="no" Compressed="yes" PerMachine="yes" Permanent="yes" Vital="yes" InstallCommand="/q"
SourceFile="NDP451-KB2859818-Web.exe"
DetectCondition="(Net4FullVersion = "4.5.50938") AND (NOT VersionNT64 OR (Net4x64FullVersion = "4.5.50938"))"
InstallCondition="(VersionNT >= v6.0 OR VersionNT64 >= v6.0) AND (NOT (Net4FullVersion = "4.5.50938" OR Net4x64FullVersion = "4.5.50938"))"/>
<ExePackage Id="Net4Full" Name="Microsoft .NET Framework 4.0 Setup" Cache="no" Compressed="yes" PerMachine="yes" Permanent="yes" Vital="yes" InstallCommand="/q"
SourceFile="dotNetFx40_Full_setup.exe"
DetectCondition="Net4FullVersion AND (NOT VersionNT64 OR Net4x64FullVersion)"
InstallCondition="(VersionNT < v6.0 OR VersionNT64 < v6.0) AND (NOT (Net4FullVersion OR Net4x64FullVersion))"/> />
<RollbackBoundary />
<MsiPackage Id="MainPackage" SourceFile="Main_package.msi" DisplayInternalUI="yes" Compressed="yes" Vital="yes" />
</Chain>
</Bundle>
</Wix>
添加网络连接
<Component>
...
<IniFile Id='Launch' Action='addLine' Name='Launch.url' Directory='INSTALLDIR'
Section='InternetShortcut' Key='URL' Value='http://www.acmefoobar.com' />
...
</Component>
<Property Id="BROWSER">
<RegistrySearch Id='DefaultBrowser' Type='raw' Root='HKCR' Key='http\shell\open\command' />
</Property>
<CustomAction Id='LaunchBrowser' Property='BROWSER' ExeCommand='www.something.com' Return='asyncNoWait' />
<InstallExecuteSequence>
...
<Custom Action='LaunchBrowser' After='InstallFinalize'>NOT Installed</Custom>
</InstallExecuteSequence>
<Property Id="URL" Value="http://www.something.com" />
...
<Shortcut Id="WebShortcut" Name="Web URL" Description="Jump to our website" Target="[URL]" />
WiX 工具集目录手册表
添加文件:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" UpgradeCode="PUT-GUID-HERE" Version="1.0.0.0" Language="1033" Name="My Application Name" Manufacturer="My Manufacturer Name">
<Package InstallerVersion="300" Compressed="yes"/>
<Media Id="1" Cabinet="myapplication.cab" EmbedCab="yes" />
<!-- Step 1: Define the directory structure -->
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="APPLICATIONROOTDIRECTORY" Name="My Application Name"/>
</Directory>
</Directory>
<!-- Step 2: Add files to your installer package -->
<DirectoryRef Id="APPLICATIONROOTDIRECTORY">
<Component Id="myapplication.exe" Guid="PUT-GUID-HERE">
<File Id="myapplication.exe" Source="MySourceFiles\MyApplication.exe" KeyPath="yes" Checksum="yes"/>
</Component>
<Component Id="documentation.html" Guid="PUT-GUID-HERE">
<File Id="documentation.html" Source="MySourceFiles\documentation.html" KeyPath="yes"/>
</Component>
</DirectoryRef>
<!-- Step 3: Tell WiX to install the files -->
<Feature Id="MainApplication" Title="Main Application" Level="1">
<ComponentRef Id="myapplication.exe" />
<ComponentRef Id="documentation.html" />
</Feature>
</Product>
</Wix>
创建快捷键
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" UpgradeCode="PUT-GUID-HERE" Version="1.0.0.0" Language="1033" Name="My Application Name" Manufacturer="My Manufacturer Name">
<Package InstallerVersion="300" Compressed="yes"/>
<Media Id="1" Cabinet="myapplication.cab" EmbedCab="yes" />
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="APPLICATIONROOTDIRECTORY" Name="My Application Name"/>
</Directory>
<!-- Step 1: Define the directory structure -->
<Directory Id="ProgramMenuFolder">
<Directory Id="ApplicationProgramsFolder" Name="My Application Name"/>
</Directory>
</Directory>
<DirectoryRef Id="APPLICATIONROOTDIRECTORY">
<Component Id="myapplication.exe" Guid="PUT-GUID-HERE">
<File Id="myapplication.exe" Source="MySourceFiles\MyApplication.exe" KeyPath="yes" Checksum="yes"/>
</Component>
<Component Id="documentation.html" Guid="PUT-GUID-HERE">
<File Id="documentation.html" Source="MySourceFiles\documentation.html" KeyPath="yes"/>
</Component>
</DirectoryRef>
<!-- Step 2: Add the shortcut to your installer package -->
<DirectoryRef Id="ApplicationProgramsFolder">
<Component Id="ApplicationShortcut" Guid="PUT-GUID-HERE">
<Shortcut Id="ApplicationStartMenuShortcut"
Name="My Application Name"
Description="My Application Description"
Target="[#myapplication.exe]"
WorkingDirectory="APPLICATIONROOTDIRECTORY"/>
<RemoveFolder Id="ApplicationProgramsFolder" On="uninstall"/>
<RegistryValue Root="HKCU" Key="Software\MyCompany\MyApplicationName" Name="installed" Type="integer" Value="1" KeyPath="yes"/>
</Component>
</DirectoryRef>
<Feature Id="MainApplication" Title="Main Application" Level="1">
<ComponentRef Id="myapplication.exe" />
<ComponentRef Id="documentation.html" />
<!-- Step 3: Tell WiX to install the shortcut -->
<ComponentRef Id="ApplicationShortcut" />
</Feature>
</Product>
</Wix>