WIx "Remember property pattern" 不允许属性在自定义操作中可用
WIx "Remember property pattern" not allowing properties to be available in custom action
我使用的是 Wix 版本 3.9R2
我按照建议 here 在我的产品 installs/repairs/uninstalls 中创建持久属性。
当我安装时,从命令行设置的属性被正确发送到我的自定义操作方法。当我重新安装产品时,他们没有,尽管日志显示属性填充了正确的值。这是我的 install logs(安装和修复)。
此外,这是我的 wxs 文件。我省略了一些我认为不相关的部分。
<?xml version="1.0" encoding="UTF-8"?>
<Wix>
<Product>
<!--These are all of our properties that we can configure-->
<Property Id="APPPOOLUSERACCOUNTTYPE" Value="networkService" />
<Property Id="APPPOOLUSERNAME" Value="Username" />
<Property Id="APPPOOLUSERPASSWORD" Value="Password" />
<Property Id="DATABASECONNECTIONSTRING">
<RegistrySearch Id="DatabaseConnectionStringProperty" Root="HKLM"
Key="SOFTWARE\MedXStorage\Database"
Name="ConnectionString" Type="raw" />
</Property>
<Property Id="DATABASENAME">
<RegistrySearch Id="DatabaseNameProperty" Root="HKLM"
Key="SOFTWARE\MedXStorage\Database"
Name="DatabaseName" Type="raw" />
</Property>
<!--Actions to restore any settings set from the command line-->
<CustomAction Id="DATABASECONNECTIONSTRING_SaveCmdLineValue" Property="CMDLINE_DATABASECONNECTIONSTRING" Value="[DATABASECONNECTIONSTRING]" Execute="firstSequence" />
<CustomAction Id="DATABASECONNECTIONSTRING_SetFromCmdLineValue" Property="DATABASECONNECTIONSTRING" Value="[CMDLINE_DATABASECONNECTIONSTRING]" Execute="firstSequence" />
<CustomAction Id="DATABASENAME_SaveCmdLineValue" Property="CMDLINE_DATABASENAME" Value="[DATABASENAME]" Execute="firstSequence" />
<CustomAction Id="DATABASENAME_SetFromCmdLineValue" Property="DATABASENAME" Value="[CMDLINE_DATABASENAME]" Execute="firstSequence" />
<!--Action that deploys the database-->
<CustomAction Id="DeployDatabaseAction"
BinaryKey="MedXStorage.InstallerActions.dll"
DllEntry="DeployDatabase" />
<InstallExecuteSequence>
<!--Restore and settings set from the command line-->
<Custom Action="DATABASECONNECTIONSTRING_SaveCmdLineValue" Before="AppSearch" />
<Custom Action="DATABASECONNECTIONSTRING_SetFromCmdLineValue" After="AppSearch">CMDLINE_DATABASECONNECTIONSTRING</Custom>
<Custom Action="DATABASENAME_SaveCmdLineValue" Before="AppSearch" />
<Custom Action="DATABASENAME_SetFromCmdLineValue" After="AppSearch">CMDLINE_DATABASENAME</Custom>
<!--Lets try to deploy our datbase-->
<Custom Action="DeployDatabaseAction" After="InstallInitialize">
<![CDATA[&DatabaseFeature=3 OR REINSTALL><DatabaseFeature]]>
</Custom>
</InstallExecuteSequence>
<InstallUISequence>
<!--Restore and settings set from the command line-->
<Custom Action="DATABASECONNECTIONSTRING_SaveCmdLineValue" Before="AppSearch" />
<Custom Action="DATABASECONNECTIONSTRING_SetFromCmdLineValue" After="AppSearch">CMDLINE_DATABASECONNECTIONSTRING</Custom>
<Custom Action="DATABASENAME_SaveCmdLineValue" Before="AppSearch" />
<Custom Action="DATABASENAME_SetFromCmdLineValue" After="AppSearch">CMDLINE_DATABASENAME</Custom>
</InstallUISequence>
</Product>
</Wix>
这是我的 C# 操作方法。
[CustomAction]
public static ActionResult DeployDatabase(Session session)
{
try
{
session.Log("Begin DeployDatabase");
var connectionString = session["DATABASECONNECTIONSTRING"];
var databaseName = session["DATABASENAME"];
var dacpacLocation = session["DATABASEDACPACLOCATION"];
session.Log("Starting database deploy with...");
session.Log(" ConnectionString=" + connectionString);
session.Log(" DatabaseName=" + databaseName);
session.Log(" DacpacLocation=" + dacpacLocation);
if (string.IsNullOrEmpty(connectionString))
{
session.Log("Connection string must be provided.");
return ActionResult.Failure;
}
if (string.IsNullOrEmpty(connectionString))
{
session.Log("Database name must be provided.");
return ActionResult.Failure;
}
if (string.IsNullOrEmpty(dacpacLocation))
{
session.Log("Dacpac must be provided.");
return ActionResult.Failure;
}
if (!File.Exists(dacpacLocation))
{
session.Log("The dacpac doesn't exist at " + dacpacLocation + ".");
return ActionResult.Failure;
}
SqlPackage.Deploy(dacpacLocation, connectionString, databaseName, (messageType, message) => session.Log("Sql deploy message: " + messageType + ": " + message));
return ActionResult.Success;
}
catch (Exception ex)
{
session.Log("Error deploying database.");
var exception = ex;
while (exception != null)
{
session.Log("---");
session.Log("Message:" + exception.Message);
session.Log("Stacktrace:" + exception.StackTrace);
session.Log("---");
exception = exception.InnerException;
}
return ActionResult.Failure;
}
}
在修复日志中,您可以看到它正确设置了属性。
Property(C): DATABASECONNECTIONSTRING = Data Source=(localdb)\ProjectsV12;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False
但是,在我的自定义操作中,我无法检索此 属性。
Starting database deploy with...
ConnectionString=
DatabaseName=
DacpacLocation=C:\Users\Paul\AppData\Local\Temp\tmpA791.tmp
为什么同样的 msi 在安装期间给我正确的属性值,但 none 在修复时给我?
WiX 使用 属性 元素上的 Secure 属性来构建 SecureCustomProperties property.
The SecureCustomProperties is a list of public properties delimited by
semi-colons. These properties are included with the default list of
restricted public properties that the installer can pass to the server
side when doing a managed installation with elevated privileges.
FWIW,记住我 属性 模式在我看来是不完整的。我通常也会更进一步地实现 属性 源优先模式。这个想法是在命令行传递的值或在 UI 中选择的值应该覆盖应该覆盖默认值的记忆值。
如果要将属性从 UI 序列转移到服务器的执行序列中,属性应标记为 Secure=:yes - 这可能是问题所在。
我使用的是 Wix 版本 3.9R2
我按照建议 here 在我的产品 installs/repairs/uninstalls 中创建持久属性。
当我安装时,从命令行设置的属性被正确发送到我的自定义操作方法。当我重新安装产品时,他们没有,尽管日志显示属性填充了正确的值。这是我的 install logs(安装和修复)。
此外,这是我的 wxs 文件。我省略了一些我认为不相关的部分。
<?xml version="1.0" encoding="UTF-8"?>
<Wix>
<Product>
<!--These are all of our properties that we can configure-->
<Property Id="APPPOOLUSERACCOUNTTYPE" Value="networkService" />
<Property Id="APPPOOLUSERNAME" Value="Username" />
<Property Id="APPPOOLUSERPASSWORD" Value="Password" />
<Property Id="DATABASECONNECTIONSTRING">
<RegistrySearch Id="DatabaseConnectionStringProperty" Root="HKLM"
Key="SOFTWARE\MedXStorage\Database"
Name="ConnectionString" Type="raw" />
</Property>
<Property Id="DATABASENAME">
<RegistrySearch Id="DatabaseNameProperty" Root="HKLM"
Key="SOFTWARE\MedXStorage\Database"
Name="DatabaseName" Type="raw" />
</Property>
<!--Actions to restore any settings set from the command line-->
<CustomAction Id="DATABASECONNECTIONSTRING_SaveCmdLineValue" Property="CMDLINE_DATABASECONNECTIONSTRING" Value="[DATABASECONNECTIONSTRING]" Execute="firstSequence" />
<CustomAction Id="DATABASECONNECTIONSTRING_SetFromCmdLineValue" Property="DATABASECONNECTIONSTRING" Value="[CMDLINE_DATABASECONNECTIONSTRING]" Execute="firstSequence" />
<CustomAction Id="DATABASENAME_SaveCmdLineValue" Property="CMDLINE_DATABASENAME" Value="[DATABASENAME]" Execute="firstSequence" />
<CustomAction Id="DATABASENAME_SetFromCmdLineValue" Property="DATABASENAME" Value="[CMDLINE_DATABASENAME]" Execute="firstSequence" />
<!--Action that deploys the database-->
<CustomAction Id="DeployDatabaseAction"
BinaryKey="MedXStorage.InstallerActions.dll"
DllEntry="DeployDatabase" />
<InstallExecuteSequence>
<!--Restore and settings set from the command line-->
<Custom Action="DATABASECONNECTIONSTRING_SaveCmdLineValue" Before="AppSearch" />
<Custom Action="DATABASECONNECTIONSTRING_SetFromCmdLineValue" After="AppSearch">CMDLINE_DATABASECONNECTIONSTRING</Custom>
<Custom Action="DATABASENAME_SaveCmdLineValue" Before="AppSearch" />
<Custom Action="DATABASENAME_SetFromCmdLineValue" After="AppSearch">CMDLINE_DATABASENAME</Custom>
<!--Lets try to deploy our datbase-->
<Custom Action="DeployDatabaseAction" After="InstallInitialize">
<![CDATA[&DatabaseFeature=3 OR REINSTALL><DatabaseFeature]]>
</Custom>
</InstallExecuteSequence>
<InstallUISequence>
<!--Restore and settings set from the command line-->
<Custom Action="DATABASECONNECTIONSTRING_SaveCmdLineValue" Before="AppSearch" />
<Custom Action="DATABASECONNECTIONSTRING_SetFromCmdLineValue" After="AppSearch">CMDLINE_DATABASECONNECTIONSTRING</Custom>
<Custom Action="DATABASENAME_SaveCmdLineValue" Before="AppSearch" />
<Custom Action="DATABASENAME_SetFromCmdLineValue" After="AppSearch">CMDLINE_DATABASENAME</Custom>
</InstallUISequence>
</Product>
</Wix>
这是我的 C# 操作方法。
[CustomAction]
public static ActionResult DeployDatabase(Session session)
{
try
{
session.Log("Begin DeployDatabase");
var connectionString = session["DATABASECONNECTIONSTRING"];
var databaseName = session["DATABASENAME"];
var dacpacLocation = session["DATABASEDACPACLOCATION"];
session.Log("Starting database deploy with...");
session.Log(" ConnectionString=" + connectionString);
session.Log(" DatabaseName=" + databaseName);
session.Log(" DacpacLocation=" + dacpacLocation);
if (string.IsNullOrEmpty(connectionString))
{
session.Log("Connection string must be provided.");
return ActionResult.Failure;
}
if (string.IsNullOrEmpty(connectionString))
{
session.Log("Database name must be provided.");
return ActionResult.Failure;
}
if (string.IsNullOrEmpty(dacpacLocation))
{
session.Log("Dacpac must be provided.");
return ActionResult.Failure;
}
if (!File.Exists(dacpacLocation))
{
session.Log("The dacpac doesn't exist at " + dacpacLocation + ".");
return ActionResult.Failure;
}
SqlPackage.Deploy(dacpacLocation, connectionString, databaseName, (messageType, message) => session.Log("Sql deploy message: " + messageType + ": " + message));
return ActionResult.Success;
}
catch (Exception ex)
{
session.Log("Error deploying database.");
var exception = ex;
while (exception != null)
{
session.Log("---");
session.Log("Message:" + exception.Message);
session.Log("Stacktrace:" + exception.StackTrace);
session.Log("---");
exception = exception.InnerException;
}
return ActionResult.Failure;
}
}
在修复日志中,您可以看到它正确设置了属性。
Property(C): DATABASECONNECTIONSTRING = Data Source=(localdb)\ProjectsV12;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False
但是,在我的自定义操作中,我无法检索此 属性。
Starting database deploy with...
ConnectionString=
DatabaseName=
DacpacLocation=C:\Users\Paul\AppData\Local\Temp\tmpA791.tmp
为什么同样的 msi 在安装期间给我正确的属性值,但 none 在修复时给我?
WiX 使用 属性 元素上的 Secure 属性来构建 SecureCustomProperties property.
The SecureCustomProperties is a list of public properties delimited by semi-colons. These properties are included with the default list of restricted public properties that the installer can pass to the server side when doing a managed installation with elevated privileges.
FWIW,记住我 属性 模式在我看来是不完整的。我通常也会更进一步地实现 属性 源优先模式。这个想法是在命令行传递的值或在 UI 中选择的值应该覆盖应该覆盖默认值的记忆值。
如果要将属性从 UI 序列转移到服务器的执行序列中,属性应标记为 Secure=:yes - 这可能是问题所在。