使用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")

 

标签:工具分享, MSI程序包