Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/266.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# InstallFinalize后,WIX自定义操作修改INSTALLFOLDER中的文件_C#_Wix_Wix3.5_Wix3_Wix3.6 - Fatal编程技术网

C# InstallFinalize后,WIX自定义操作修改INSTALLFOLDER中的文件

C# InstallFinalize后,WIX自定义操作修改INSTALLFOLDER中的文件,c#,wix,wix3.5,wix3,wix3.6,C#,Wix,Wix3.5,Wix3,Wix3.6,我已经为我的wixv3安装程序编写了一个C#自定义操作,它应该修改INSTALLFOLDER中的appsettings.json。该操作的Execute属性设置为immediate and Impersonate=“no”,它在InstallFinalize之后调用,但在此操作中遇到一个问题,即缺少管理员权限。 该操作修改INSTALLFOLDER(即程序文件(x86))中的appsettings.json 自定义操作正常读取、反序列化、修改和序列化数据,无错误。 写入InstallFolder

我已经为我的wixv3安装程序编写了一个C#自定义操作,它应该修改INSTALLFOLDER中的appsettings.json。该操作的Execute属性设置为immediate and Impersonate=“no”,它在InstallFinalize之后调用,但在此操作中遇到一个问题,即缺少管理员权限。 该操作修改INSTALLFOLDER(即程序文件(x86))中的appsettings.json

自定义操作正常读取、反序列化、修改和序列化数据,无错误。 写入InstallFolder中的appsettings.json时出错。 虽然出现了错误,但应用程序的其余部分已安装且工作正常

我已尝试在所有可能的组合中组合执行和自定义操作,如果在安装完成之前将自定义操作更改为运行,我将获得写入InstallFolder的权限,但找不到appsettings.json文件,因为此时的所有文件都是临时文件(.tmp),和不相关的名字

出现的错误是:

my Product.wsx代码的一部分:

      <Property Id="Password" Value="Error password" />
      <Property Id="FilePath" Value="C:\Program Files (x86)\Company\Product\" />
      
      <CustomAction Id="SetUserName" Property="Username" Value="[ACCOUNT]"/>
      <CustomAction Id="SetPassword" Property="Password" Value="[PASSWORD]"/>
      <CustomAction Id="SetFilePath" Property="FilePath" Value="[INSTALLFOLDER]"/>
      
      <Binary Id="GetData" SourceFile="$(var.SetupExtensions.TargetDir)\$(var.SetupExtensions.TargetName).CA.dll" />  
      <CustomAction Id="ChangeJSON" BinaryKey="GetData" DllEntry="CustomAction1" Execute="immediate" Impersonate="no"  Return="check"/>
      
      <InstallExecuteSequence>
          <Custom Action="SetUserName" After="CostFinalize" />
          <Custom Action="SetPassword" After="CostFinalize" />
          <Custom Action="SetFilePath" After="CostFinalize"/>
          <Custom Action='ChangeJSON'  After='InstallFinalize'></Custom>
      </InstallExecuteSequence> 

我的自定义操作代码:

      public static ActionResult CustomAction1(Session session)
      {
          try
          {
              session.Log( "Begin CustomAction1" );
              string user = session["Username"];
              string password = session["Password"];
              string loc = session["FilePath"];

              var json = System.IO.File.ReadAllText( loc +"appsettings.json" );
              var root = JsonConvert.DeserializeObject<Root>(json);

              root.Default.UserName = user;
              root.Default.Password = password;
          
              json = JsonConvert.SerializeObject( root, Formatting.Indented );
              System.IO.File.WriteAllText( loc + "appsettings.json", json );
              //The MessageBox bellow shows(and is with correct info) when I remove System.IO.File.WriteAllText above ^^
              MessageBox.Show("Username: "+ user +"\nPassword: "+password +"\nFilePath: " + loc);
              return ActionResult.Success;
          }
          catch(Exception ex )
          {
              session.Log( "Error: " + ex.Message );
              MessageBox.Show(ex.Message);
              return ActionResult.Failure;
          }
publicstaticactionresult自定义操作1(会话)
{
尝试
{
session.Log(“开始定制操作1”);
字符串user=session[“Username”];
字符串密码=会话[“密码”];
字符串loc=会话[“文件路径”];
var json=System.IO.File.ReadAllText(loc+“appsettings.json”);
var root=JsonConvert.DeserializeObject(json);
root.Default.UserName=用户;
root.Default.Password=密码;
json=JsonConvert.SerializeObject(根,格式化,缩进);
System.IO.File.WriteAllText(loc+“appsettings.json”,json);
//当我删除上面的System.IO.File.WriteAllText时,下面的消息框显示(并带有正确的信息)^^
显示(“用户名:+user+”\n密码:+password+”\n路径:+loc);
返回操作结果。成功;
}
捕获(例外情况除外)
{
session.Log(“错误:+ex.Message”);
MessageBox.Show(例如Message);
返回操作结果。失败;
}

如何通过自定义操作修改appsettings.json?

更改系统状态的自定义操作应在InstallInitialize和InstallFinalize之间运行。这意味着您应在InstallFinalize之前而不是之后安排它

它还应该在没有模拟的延迟执行中运行。您将需要在此之前安排另一个自定义操作,该操作将创建自定义操作数据并将数据传递给延迟的自定义操作

理想情况下,您还应该具有回滚和提交操作,以支持使用WixFailWhenFerred自定义操作进行回滚和测试

阅读:

<强>应用程序启动< /强>:如果可以的话,我想通过应用程序启动序列更新JSON。<强> >代码> <强>单源解决方案,<强> >代码> < /强>开发人员熟悉的域,<强> >代码> 3 > /代码> < /强>更容易和更好的调试特性和<强> <代码> 4)< /代码>

模拟-
排序-
调节复杂度
,就像您在自定义操作中得到的:


延迟CA示例:您可以在此处找到延迟模式自定义操作WiX解决方案的示例:

内联示例:此旧答案显示答案中内联的关键结构:

CustomActionData:延迟模式自定义操作无法像立即模式自定义操作那样访问会话对象属性值。正如Painter所写,您需要“发送”通过将数据写入执行脚本,将文本或设置设置设置为延迟模式。然后,通过读取特殊属性
CustomActionData
,可以在延迟模式下使用数据。上述示例应具有所需的结构,以了解其工作原理。以及

事务:延迟模式自定义操作只能存在于InstallInitialize和InstallFinalize之间。这些操作之间的操作以提升的权限运行,并且可以写入每台计算机的位置(普通用户不可写入)。您可以在InstallFinalize开始之前安排自己测试当前的删除机制(我会尝试其他方法)

回滚CAs:回滚自定义操作旨在撤消对JSON自定义操作所做的操作,然后将所有操作恢复到以前的状态(安装失败后清除)。编写这些内容非常复杂,需要进行大量测试-许多只是跳过它们。最好尝试找到一个库或框架来为您完成这项工作。除了下面链接的库或框架外,我不知道其他库或框架,我也不知道它的状态。回滚自定义操作必须在
installExecuteSeSequence
(当MSI回滚时,它会反向执行序列)

由于这些复杂性,自定义操作成为部署错误的主要来源:


链接:

  • (不确定该系统的状态)

似乎您应该设置
execute=“deferred”
在您的自定义操作中。请参阅:该自定义操作功能很好-我一直忘了它。这是测试回滚时的一个关键元素。不用为每个项目自己编写此功能非常好。您知道我在回答中提到的JSON WiX项目吗?还有其他项目吗?嗨,Tkank you f