2016-03-02 75 views
0

我一直在疯狂地试图弄清楚为什么视图没有更新。从我在网上看到的所有帖子中,我认为我做对了,但我一直在收到一个空错误。如果我尝试使用session.Database.FilePath加载数据库,它说FilePath为空。视图本身正在返回虚拟行,所以数据库就在那里。这只是奇怪的。当修改数据库时,WiX工具集自定义操作失败

下面是财产

<Property Id="IIS_SITE" /> 

的二进制和自定义操作

<CustomAction Id="UpdateComboBoxes" DllEntry="UpdateComboBoxes" BinaryKey="UpdateComboBoxes" Execute="immediate" Return="check" /> 
<Binary Id="UpdateComboBoxes" SourceFile="..\ProjectName.CustomActions\bin\Release\ProjectName.CustomActions.CA.dll"/> 

安装UI序列

<InstallUISequence> 
    <Custom Action="UpdateComboBoxes" Before="CostFinalize"></Custom> 
</InstallUISequence> 

控制

<Control Id="IisSite" Type="ComboBox" Sorted="yes" ComboList="yes" Property="IIS_SITE" X="45" Y="85" Width="220" Height="18" > 
     <ComboBox Property="IIS_SITE" > 
     <ListItem Text="Dummy" Value="Dummy"/> 
     </ComboBox> 
    </Control> 

自定义操作

 [CustomAction] 
    public static ActionResult UpdateComboBoxes(Session session) 
    { 
     session.Log("Begin Custom Action UpdateComboBoxes"); 
     try 
     { 
      session.Log(string.Format("Database Location is: {0}", session.Database.FilePath)); 
      var database = session.Database; 
       using (var view = database.OpenView("SELECT * FROM ComboBox WHERE Property = 'IIS_SITE'")) 
       { 

        view.Execute(); 
        session.Log("Executed view"); 

        var isReadOnly = database.IsReadOnly; 

        session.Log(string.Format("Database is read only: {0}", isReadOnly)); 
        session.Log(string.Format("# of rows in ComboBox Table: {0}", 
         view.Database.CountRows("ComboBox", "Property = 'IIS_SITE'"))); 

        using (var serverManager = new ServerManager()) 
        { 
         session.Log("Accessed Server Manager"); 
         var index = 1; 
         var rowIndex = 1; 
         session.Log(string.Format("Going through {0} sites", serverManager.Sites.Count)); 
         foreach (var site in serverManager.Sites) 
         { 
          if (!string.IsNullOrEmpty(site.Name)) 
          { 
           session.Log(string.Format("Site # {0} {1}", index, site.Name)); 
           var record = session.Database.CreateRecord(4); 
           //Property 
           record.SetString(1, "IIS_SITE"); 
           //Order 
           record.SetString(2, rowIndex.ToString()); 
           //Value 
           record.SetString(3, site.Name); 
           //Text 
           record.SetString(4, site.Name); 

           session.Log(string.Format("Modifying the view for site # {0}", index)); 
           view.Modify(ViewModifyMode.InsertTemporary, record); 
          } 
          session.Log("Incrementing index"); 
          index++; 
          rowIndex++; 
         } 
        } 

        session.Log("Closing the view"); 
       } 
     } 
     catch (Exception e) 
     { 

      session.Log(string.Format("ERROR in UpdateComboBoxes: {0}", e.Message)); 
      session.Log(e.StackTrace); 
      var inner = e.InnerException; 
      if(inner != null) 
      { 
       session.Log(string.Format("{0}{1}", "\t", inner.Message)); 
       session.Log(string.Format("{0}{1}", "\t", inner.StackTrace)); 
      } 
      while ((inner = inner.InnerException) != null) 
      { 
       session.Log(string.Format("{0}{1}", "\t", inner.Message)); 
       session.Log(string.Format("{0}{1}", "\t", inner.StackTrace)); 
      } 
      return ActionResult.Failure; 
     } 
     return ActionResult.Success; 
    } 

我得到的错误:

MSI(C)(!B0 F4)[14:46:40:369]:注意:1:2259 2:3:4:
UpdateComboBoxes中的错误:执行期间函数失败。 在Microsoft.Deployment.WindowsInstaller.View.Modify(ViewModifyMode模式,录音记录) 在VideoQuestionInstaller.CustomActions.CustomActions.UpdateComboBoxes(会话的会话) 异常的自定义操作抛出: System.Reflection.TargetInvocationException:异常已被抛出调用的目标。 ---> System.NullReferenceException:未将对象引用设置为对象的实例。 在VideoQuestionInstaller.CustomActions.CustomActions.UpdateComboBoxes(会话会话) ---内部异常堆栈跟踪的结尾--- 在System.RuntimeMethodHandle.InvokeMethod(目标对象,对象参数,签名Sig,布尔构造函数) 在系统。 Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj,Object parameters,Object arguments) at Microsoft.Deployment.WindowsInstaller.CustomActionProxy System.Reflection.RuntimeMethodInfo.Invoke(Object obj,BindingFlags invokeAttr,Binder binder,Object parameters,CultureInfo culture) 。 InvokeCustomAction(Int32 sessionHandle,String entryPoint,IntPtr remotingDelegatePtr)

我查了一下,错误2259意味着数据库无法更新,这是自错误发生前的最后一个日志以来非常清楚:修改站点#1的视图。

有没有人有任何想法我做错了,为什么ComboBox数据库没有更新?

在此先感谢!

回答

0

没关系,我找出了问题所在。以下是我固定它:

我补充说,隐藏起来,组合框表的创建,而不必把假值转换成实际的组合框我打算用

<Property Id="HIDDEN_IIS_SITE" /> 

    <Control Id="DummyComboBox" Hidden="yes" Type="ComboBox" Sorted="yes" ComboList="yes" Property="HIDDEN_IIS_SITE" X="45" Y="85" Width="220" Height="18" > 
     <ComboBox Property="HIDDEN_IIS_SITE" > 
     <ListItem Text="Dummy" Value="Dummy"/> 
     </ComboBox> 
    </Control> 

然后又控制我修改了自定义操作,以便它获得实际的现有行数,然后添加到记录添加的数字中,以便使用正确的订单号码

[CustomAction] 
    public static ActionResult UpdateComboBoxes(Session session) 
    { 
     session.Log("Begin Custom Action UpdateComboBoxes"); 
     try 
     { 
      var database = session.Database; 
       using (var view = database.OpenView("SELECT * FROM ComboBox WHERE Property = 'IIS_SITE'")) 
       { 

        view.Execute(); 
        session.Log("Executed view"); 

        var index = view.Database.CountRows("ComboBox", "Property = 'IIS_SITE'"); 

        using (var serverManager = new ServerManager()) 
        { 
         foreach (var site in serverManager.Sites) 
         { 
          if (!string.IsNullOrEmpty(site.Name)) 
          { 
           var record = session.Database.CreateRecord(4); 
           //Property 
           record.SetString(1, "IIS_SITE"); 
           //Order 
           record.SetString(2, (++index).ToString()); 
           //Value 
           record.SetString(3, site.Name); 
           //Text 
           record.SetString(4, site.Name); 

           view.InsertTemporary(record); 

           session.Log("Inserted new record"); 
          } 
         } 
        } 
        session.Log("Closing the view"); 
       } 
     } 
     catch (Exception e) 
     { 

      session.Log(string.Format("ERROR in UpdateComboBoxes: {0}", e.Message)); 
      session.Log(e.StackTrace); 
      var inner = e.InnerException; 
      if(inner != null) 
      { 
       session.Log(string.Format("{0}{1}", "\t", inner.Message)); 
       session.Log(string.Format("{0}{1}", "\t", inner.StackTrace)); 
      } 
      while (inner != null && (inner = inner.InnerException) != null) 
      { 
       session.Log(string.Format("{0}{1}", "\t", inner.Message)); 
       session.Log(string.Format("{0}{1}", "\t", inner.StackTrace)); 
      } 
      return ActionResult.Failure; 
     } 
     return ActionResult.Success; 
    }