WIX 以管理员权限执行自定义操作
WIX execute custom action with admin privilege
我已经为我的 WIX 安装程序编写了自定义操作。该操作的执行属性在 InstallFinalize 之前设置为 deferred 和 Impersonate 和 运行,但它在该操作中遇到了一个问题,即缺少管理员权限。该操作在 INSTALLFOLDER 中创建一个文件,该文件是 Program File (x86)
那是我的 WIX 代码:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*"
Name="WixTesterSetup"
Language="1033"
Version="1.0.0.0"
Manufacturer="WixTester"
UpgradeCode="77b7ed9a-5394-43e9-aecb-cd9985368ef6">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate />
<Feature Id="Core" Title="Core" Level="1" ConfigurableDirectory="INSTALLFOLDER" />
<UI>
<UIRef Id="WixUI_Minimal" />
<Publish Dialog="ExitDialog"
Control="Finish"
Event="DoAction"
Value="LaunchApplication">WIXUI_EXITDIALOGOPTIONALCHECKBOX = 1 and NOT Installed</Publish>
</UI>
<Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOXTEXT" Value="Launch Wix Tester" />
<Property Id="WixShellEecxTarget" Value="[#WixTester.exe]" />
<CustomAction Id="LaunchApplication" BinaryKey="WixCA" DllEntry="WixShellExec" Impersonate="yes" />
<Binary Id="CustomActionBinary" SourceFile="$(var.RegistrationInfoCustomAction.TargetDir)$(var.RegistrationInfoCustomAction.TargetName).CA.dll"/>
<CustomAction Id="RegistrationInfoCustomAction" BinaryKey="CustomActionBinary" DllEntry="SaveUserInfo" Execute="deferred" Impersonate="no" />
<InstallExecuteSequence>
<Custom Action='RegistrationInfoCustomAction' Before='InstallFinalize'>NOT Installed</Custom>
</InstallExecuteSequence>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="WixTesterSetup">
<Component Feature="Core">
<File Id="WixTester.exe" Source="$(var.WixTester.TargetPath)" KeyPath="yes" Checksum="yes"/>
</Component>
</Directory>
</Directory>
</Directory>
</Product>
</Wix>
简单的自定义操作:
public class CustomActions
{
[CustomAction]
public static ActionResult SaveUserInfo(Session session)
{
File.Create(System.IO.Path.Combine(session.GetTargetPath("INSTALLFOLDER"), "test.xml"));
return ActionResult.Success;
}
}
对 WixTester 不感兴趣:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Test Started");
Console.ReadLine();
}
}
Diagnose: I suspect there is something else wrong than just permissions. Please try the following:
Verbose Log File:请创建详细日志文件:
msiexec.exe /I "C:\file.msi" /QN /L*V "C:\msilog.log"
Hot Log Interpretation Tip: Search for "value 3" in the log file to find errors as explained by Rob Mensching
(Wix & Orca
author). MSI log files can be overwhelming otherwise.
More: How to interpret an MSI Log File (and in PDF format from WayBack).
调试自定义操作:您是否将调试器附加到有问题的自定义操作?请在此处查找信息: - and a direct link to an Advanced Installer demonstration video. And a link to MSDN / Microsoft Docs.
Debugging In Short: show a message box and attach to it.
XML 文件:XML 文件可以用 WiX XML features 安装,但不应该通过自定义操作生成。您还可以在应用程序本身启动时在用户可写的位置创建文件。以下是后者的几个链接:
- 如何部署设置文件:Create folder and file on Current user profile, from Admin Profile
- 处理写入权限被拒绝:System.UnauthorizedAccessException while running .exe under program files
Recommendation: I do not know which approach can work for you. Recommend you generate the file via the application and save in the
userprofile. One xml file per user.
链接:
- 有关日志记录的更多信息:
问题是延迟的自定义操作无法访问 session["PropertyName"]
解决方案是使用 session.CustomActionData["PORTProperty"]
并通过自定义操作类型 51 传递变量。新的 WIX 代码看起来像:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*"
Name="WixTesterSetup"
Language="1033"
Version="1.0.0.0"
Manufacturer="WixTester"
UpgradeCode="77b7ed9a-5394-43e9-aecb-cd9985368ef6">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate />
<Feature Id="Core" Title="Core" Level="1" ConfigurableDirectory="INSTALLFOLDER" />
<UI>
<UIRef Id="WixUI_Minimal" />
<Publish Dialog="ExitDialog"
Control="Finish"
Event="DoAction"
Value="LaunchApplication">WIXUI_EXITDIALOGOPTIONALCHECKBOX = 1 and NOT Installed</Publish>
</UI>
<Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOXTEXT" Value="Launch Wix Tester" />
<Property Id="WixShellEecxTarget" Value="[#WixTester.exe]" />
<CustomAction Id="LaunchApplication" BinaryKey="WixCA" DllEntry="WixShellExec" Impersonate="yes" />
<Binary Id="CustomActionBinary" SourceFile="$(var.RegistrationInfoCustomAction.TargetDir)$(var.RegistrationInfoCustomAction.TargetName).CA.dll"/>
<CustomAction Id="RegistrationInfoCustomAction" BinaryKey="CustomActionBinary" DllEntry="SaveUserInfo" Execute="deferred" Impersonate="no" />
<CustomAction Id="CustomAction51" Property="RegistrationInfoCustomAction" Value="INSTALLFOLDER=[INSTALLFOLDER]" />
<InstallExecuteSequence>
<Custom Action="CustomAction51" Before='InstallFinalize' />
<Custom Action='RegistrationInfoCustomAction' After='CustomAction51'>NOT Installed</Custom>
</InstallExecuteSequence>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="WixTesterSetup">
<Component Feature="Core">
<File Id="WixTester.exe" Source="$(var.WixTester.TargetPath)" KeyPath="yes" Checksum="yes"/>
</Component>
</Directory>
</Directory>
</Directory>
</Product>
</Wix>
自定义操作现在看起来像:
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Mime;
using System.Text;
using System.Windows.Forms;
using Microsoft.Deployment.WindowsInstaller;
namespace RegistrationInfoCustomAction
{
public class CustomActions
{
[CustomAction]
public static ActionResult SaveUserInfo(Session session)
{
File.Create(System.IO.Path.Combine(session.CustomActionData["INSTALLFOLDER"], "test.xml"));
return ActionResult.Success;
}
}
}
我已经为我的 WIX 安装程序编写了自定义操作。该操作的执行属性在 InstallFinalize 之前设置为 deferred 和 Impersonate 和 运行,但它在该操作中遇到了一个问题,即缺少管理员权限。该操作在 INSTALLFOLDER 中创建一个文件,该文件是 Program File (x86)
那是我的 WIX 代码:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*"
Name="WixTesterSetup"
Language="1033"
Version="1.0.0.0"
Manufacturer="WixTester"
UpgradeCode="77b7ed9a-5394-43e9-aecb-cd9985368ef6">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate />
<Feature Id="Core" Title="Core" Level="1" ConfigurableDirectory="INSTALLFOLDER" />
<UI>
<UIRef Id="WixUI_Minimal" />
<Publish Dialog="ExitDialog"
Control="Finish"
Event="DoAction"
Value="LaunchApplication">WIXUI_EXITDIALOGOPTIONALCHECKBOX = 1 and NOT Installed</Publish>
</UI>
<Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOXTEXT" Value="Launch Wix Tester" />
<Property Id="WixShellEecxTarget" Value="[#WixTester.exe]" />
<CustomAction Id="LaunchApplication" BinaryKey="WixCA" DllEntry="WixShellExec" Impersonate="yes" />
<Binary Id="CustomActionBinary" SourceFile="$(var.RegistrationInfoCustomAction.TargetDir)$(var.RegistrationInfoCustomAction.TargetName).CA.dll"/>
<CustomAction Id="RegistrationInfoCustomAction" BinaryKey="CustomActionBinary" DllEntry="SaveUserInfo" Execute="deferred" Impersonate="no" />
<InstallExecuteSequence>
<Custom Action='RegistrationInfoCustomAction' Before='InstallFinalize'>NOT Installed</Custom>
</InstallExecuteSequence>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="WixTesterSetup">
<Component Feature="Core">
<File Id="WixTester.exe" Source="$(var.WixTester.TargetPath)" KeyPath="yes" Checksum="yes"/>
</Component>
</Directory>
</Directory>
</Directory>
</Product>
</Wix>
简单的自定义操作:
public class CustomActions
{
[CustomAction]
public static ActionResult SaveUserInfo(Session session)
{
File.Create(System.IO.Path.Combine(session.GetTargetPath("INSTALLFOLDER"), "test.xml"));
return ActionResult.Success;
}
}
对 WixTester 不感兴趣:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Test Started");
Console.ReadLine();
}
}
Diagnose: I suspect there is something else wrong than just permissions. Please try the following:
Verbose Log File:请创建详细日志文件:
msiexec.exe /I "C:\file.msi" /QN /L*V "C:\msilog.log"
Hot Log Interpretation Tip: Search for "value 3" in the log file to find errors as explained by
Rob Mensching
(Wix & Orca author). MSI log files can be overwhelming otherwise.More: How to interpret an MSI Log File (and in PDF format from WayBack).
调试自定义操作:您是否将调试器附加到有问题的自定义操作?请在此处查找信息:
Debugging In Short: show a message box and attach to it.
XML 文件:XML 文件可以用 WiX XML features 安装,但不应该通过自定义操作生成。您还可以在应用程序本身启动时在用户可写的位置创建文件。以下是后者的几个链接:
- 如何部署设置文件:Create folder and file on Current user profile, from Admin Profile
- 处理写入权限被拒绝:System.UnauthorizedAccessException while running .exe under program files
Recommendation: I do not know which approach can work for you. Recommend you generate the file via the application and save in the userprofile. One xml file per user.
链接:
- 有关日志记录的更多信息:
问题是延迟的自定义操作无法访问 session["PropertyName"]
解决方案是使用 session.CustomActionData["PORTProperty"]
并通过自定义操作类型 51 传递变量。新的 WIX 代码看起来像:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*"
Name="WixTesterSetup"
Language="1033"
Version="1.0.0.0"
Manufacturer="WixTester"
UpgradeCode="77b7ed9a-5394-43e9-aecb-cd9985368ef6">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate />
<Feature Id="Core" Title="Core" Level="1" ConfigurableDirectory="INSTALLFOLDER" />
<UI>
<UIRef Id="WixUI_Minimal" />
<Publish Dialog="ExitDialog"
Control="Finish"
Event="DoAction"
Value="LaunchApplication">WIXUI_EXITDIALOGOPTIONALCHECKBOX = 1 and NOT Installed</Publish>
</UI>
<Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOXTEXT" Value="Launch Wix Tester" />
<Property Id="WixShellEecxTarget" Value="[#WixTester.exe]" />
<CustomAction Id="LaunchApplication" BinaryKey="WixCA" DllEntry="WixShellExec" Impersonate="yes" />
<Binary Id="CustomActionBinary" SourceFile="$(var.RegistrationInfoCustomAction.TargetDir)$(var.RegistrationInfoCustomAction.TargetName).CA.dll"/>
<CustomAction Id="RegistrationInfoCustomAction" BinaryKey="CustomActionBinary" DllEntry="SaveUserInfo" Execute="deferred" Impersonate="no" />
<CustomAction Id="CustomAction51" Property="RegistrationInfoCustomAction" Value="INSTALLFOLDER=[INSTALLFOLDER]" />
<InstallExecuteSequence>
<Custom Action="CustomAction51" Before='InstallFinalize' />
<Custom Action='RegistrationInfoCustomAction' After='CustomAction51'>NOT Installed</Custom>
</InstallExecuteSequence>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="WixTesterSetup">
<Component Feature="Core">
<File Id="WixTester.exe" Source="$(var.WixTester.TargetPath)" KeyPath="yes" Checksum="yes"/>
</Component>
</Directory>
</Directory>
</Directory>
</Product>
</Wix>
自定义操作现在看起来像:
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Mime;
using System.Text;
using System.Windows.Forms;
using Microsoft.Deployment.WindowsInstaller;
namespace RegistrationInfoCustomAction
{
public class CustomActions
{
[CustomAction]
public static ActionResult SaveUserInfo(Session session)
{
File.Create(System.IO.Path.Combine(session.CustomActionData["INSTALLFOLDER"], "test.xml"));
return ActionResult.Success;
}
}
}