使用PowerShell创建MSI
作者:Sec-Labs | 发布时间:
项目地址
https://github.com/ironmansoftware/psmsi
安装器
PSMSI 包括用于创建 MSI 程序包的 cmdlet,这些程序包可以包含您希望的任何文件和目录结构。 它还包括通过包含自定义 EULA 和图像来自定义安装程序界面的功能。
入门
要开始使用 PSMSI 创建安装程序,您需要下载最新版本的 PSMSI 模块。 这可以与安装 Install-Module 。
Install-Module PSMSI
创建您的第一个安装程序
该 New-Installer cmdlet 用于生成安装程序。 它可以包含用于安装的目录和文件。 第一步是定义安装程序的基本参数。
Product 和 UpgradeCode 参数是必需的。 UpgradeCode 是一个 GUID,需要在您的产品的每个版本中保持相同,并且应该与其他产品不同。
New-Installer -Product "My First Product" -UpgradeCode '1a73a1be-50e6-4e92-af03-586f4a9d9e82'
在 New-Installer cmdlet 的 Content 参数中,您需要包含一个用于在最终用户机器上安装的根目录。 根目录需要是一个预定义的目录。 New-InstallerDirectory 上的参数集之一定义了一个 PredefinedDirectory 参数,您可以使用它来选择目标根目录。
New-InstallerDirectory -PredefinedDirectory "LocalAppDataFolder"
您现在可以选择在根目录中指定嵌套目录。 如果它不存在,将创建它并在卸载时将其删除。
New-InstallerDirectory -DirectoryName "My First Product"
最后,您可以在目录中包含文件。 New-InstallerFile cmdlet 接受带有您要安装的文件路径的 Source 参数。
New-InstallerFile -Source .\MyTextFile.txt
此安装程序的完整脚本如下所示。
New-Installer -Product "My First Product" -UpgradeCode '1a73a1be-50e6-4e92-af03-586f4a9d9e82' -Content {
New-InstallerDirectory -PredefinedDirectory "LocalAppDataFolder" -Content {
New-InstallerDirectory -DirectoryName "My First Product" -Content {
New-InstallerFile -Source .\license.txt
}
}
} -OutputDirectory (Join-Path $PSScriptRoot "output")
运行上述脚本将在输出目录中生成 WXS、WXSOBJ 和 MSI 文件。 MSI 是您需要提供给最终用户的唯一文件。 WXS 和 WXSOBJ 文件是用于生成这些安装程序的 Windows Installer XML 工具包的产物。
安装人员
所有用户安装
您可以使用 -RequriesElevation 参数 New-Installer 从默认 PerUser 安装更改为 PerMachine 安装。
下面创建一个将安装到程序文件文件夹的安装程序。
New-Installer -Product "My First Product" -UpgradeCode '1a73a1be-50e6-4e92-af03-586f4a9d9e82' -Content {
New-InstallerDirectory -PredefinedDirectory "ProgramFilesFolder" -Content {
New-InstallerDirectory -DirectoryName "My First Product" -Content {
New-InstallerFile -Source .\license.txt
}
}
} -OutputDirectory (Join-Path $PSScriptRoot "output") -RequiresElevation
添加\删除程序图标
可以使用 AddRemoveProgramsIcon of定义将在添加\删除程序中显示的应用程序图标 New-Installer 。
New-Installer -Product "My First Product" -UpgradeCode '1a73a1be-50e6-4e92-af03-586f4a9d9e82' -Content {
New-InstallerDirectory -PredefinedDirectory "ProgramFilesFolder" -Content {
New-InstallerDirectory -DirectoryName "My First Product" -Content {
New-InstallerFile -Source .\license.txt
}
}
} -OutputDirectory (Join-Path $PSScriptRoot "output") -AddRemoveProgramsIcon "icon.ico"
升级码
该 UpgradeCode 值应该是静态的,以确保升级成功。 通过 on 定义升级代码 New-Installer 。
New-Installer -Product "My First Product" -UpgradeCode '1a73a1be-50e6-4e92-af03-586f4a9d9e82' -Content {
New-InstallerDirectory -PredefinedDirectory "ProgramFilesFolder" -Content {
New-InstallerDirectory -DirectoryName "My First Product" -Content {
New-InstallerFile -Source .\license.txt
}
}
} -OutputDirectory (Join-Path $PSScriptRoot "output")
版本
安装程序版本使用 Version 参数设置 New-Installer 。 您可以通过增加版本并保持升级代码相同来提供升级。
版本默认为 1.0。
New-Installer -Product "My First Product" -UpgradeCode '1a73a1be-50e6-4e92-af03-586f4a9d9e82' -Content {
New-InstallerDirectory -PredefinedDirectory "ProgramFilesFolder" -Content {
New-InstallerDirectory -DirectoryName "My First Product" -Content {
New-InstallerFile -Source .\license.txt
}
}
} -OutputDirectory (Join-Path $PSScriptRoot "output") -Version 2.0
自定义操作
自定义操作允许您在安装和卸载期间运行 PowerShell 脚本。 您需要将脚本作为文件包含在安装程序中。 使用 的 FileId 参数 New-InstallerCustomAction 引用您要执行的 PS1 文件。
例如,您可能有 MyCustomAction.ps1 一个 ID 为的脚本 CustomAction 。
New-InstallerFile -Source .\myCustomAction.ps1 -Id 'CustomAction'
然后您可以在安装期间将该脚本用作自定义操作。
New-InstallerCustomAction -FileId 'CustomAction' -RunOnInstall
参数
您可以将参数传递给 PowerShell.exe 和您的脚本。 该 Arguments 参数将自定义参数传递给 PowerShell.exe(如 -NoProfile)。 该 ScriptArguments 参数定义要传递给脚本本身的参数。
检查返回值
这将检查 PowerShell.exe 的退出代码。 如果退出代码不为零,则会导致安装失败。
安装时运行
在安装期间运行自定义操作。
卸载时运行
在卸载期间运行自定义操作。
目录和文件
New-InstallerDirectory 您可以使用和 创建目录和文件 New-InstallerFile 。 目录应以 MSI 提供的预定义目录之一开头。
预定义目录
使用 的 PredefinedDirectory 参数 New-InstallerDirectory 定义安装的根文件夹。 您可以使用 Program Files , AppData 和等目录 CommonAppData 。
自定义文件夹
自定义文件夹出现在预定义的目录中。 您可以嵌套文件夹以创建文件夹树。 然后文件夹可以包含文件。 使用 的 DirectoryName 参数 New-InstallerDirectory 创建目录。 用于 Content 指定要包含的文件夹或文件。
包含 Configurable on 属性 New-InstallerDirectory 将允许最终用户在安装期间选择一个目录。
New-InstallerDirectory -DirectoryName "My First Product" -Content {
New-InstallerFile -Source .\license.txt
} -Configurable
文件
文件由它们的当前位置和 ID 定义。 该 Source 参数应标识您希望包含的文件。 它在 New-InstallerDirectory 树中的位置将定义它在磁盘上的安装位置。
New-InstallerDirectory -DirectoryName "My First Product" -Content {
New-InstallerFile -Source .\license.txt
}
捷径
可以使用 为安装程序定义快捷方式 New-InstallerShortcut 。 您将定义快捷方式所在的位置, New-InstallerDirectory 并通过 Id 引用文件。
例如,要按 ID 定义文件,您可以包含 Id 参数 New-InstallerFile .
New-InstallerFile -Source .\MyTextFile.txt -Id "myTestFile"
接下来,您将在目录中定义快捷方式并通过 ID 引用该文件。
New-InstallerDirectory -PredefinedDirectory "DesktopFolder" -Content {
New-InstallerShortcut -Name "My Test File" -FileId "myTestFile"
}
工作目录
您可以通过指定文件夹的 ID 来设置快捷方式的工作目录。 下面的示例将工作目录设置为安装目录的 ID。
New-Installer -ProductName "MyImage" -UpgradeCode (New-Guid) -Version 1.0.0 -Content {
New-InstallerDirectory -PredefinedDirectoryName ProgramFilesFolder -Content {
New-InstallerDirectory -DirectoryName 'MyDir' -Id 'MyDir' -Content {
New-InstallerFile -Id 'Image' -Source 'services.png'
}
}
New-InstallerDirectory -PredefinedDirectoryName DesktopFolder -Content {
New-InstallerShortcut -Name 'Test' -FileId 'Image' -WorkingDirectoryId 'MyDir'
}
} -OutputDirectory .\installer -RequiresElevation
用户界面
您可以使用 的 UserInterface 参数自定义安装程序 New-Installer 的用户界面 New-InstallerUserInterface 。
用户界面可以包括适用于您的安装程序的自定义图形和 EULA。
$UserInterface = New-InstallerUserInterface -Eula (Join-Path $PSScriptRoot 'eula.rtf') -TopBanner (Join-Path $PSScriptRoot "banner.png") -Welcome (Join-Path $PSScriptRoot "welcome.png")