C# WIX-从后台更改对话框文本标签即时自定义操作
我已经定义了扫描lan网络计算机的自定义操作。此操作声明为立即操作,并在用户单击对话框按钮后触发:C# WIX-从后台更改对话框文本标签即时自定义操作,c#,wix,windows-installer,wix3.5,C#,Wix,Windows Installer,Wix3.5,我已经定义了扫描lan网络计算机的自定义操作。此操作声明为立即操作,并在用户单击对话框按钮后触发: <CustomAction Id="actionGetNetworkComputers" BinaryKey="actionBinary" DllEntry="GetNetworkComputers" Execute="immediate" Return="check"/> 这有两个主要问题: 操作被阻止,因此安装程序窗口冻结,直到nb.getNetworkComputers重新启动
<CustomAction Id="actionGetNetworkComputers" BinaryKey="actionBinary" DllEntry="GetNetworkComputers" Execute="immediate" Return="check"/>
这有两个主要问题:
操作被阻止,因此安装程序窗口冻结,直到nb.getNetworkComputers重新启动。若我将action return声明为asyncWait,则会执行action,但检索到的值不会插入到ComboBox中。另外,我需要一些指示操作进度的标签,例如:“扫描网络,请稍候”,并在扫描结束后隐藏此标签
wix能做到这一点吗?有什么建议吗?我认为最好的办法是安排CA is Sync Check退出代码,让您的CA显示自己的模式对话框,并显示一个“取消”按钮,告诉您扫描正在进行。然后使用BackgroundProcess类旋转扫描,同时检查是否选择了cancel。完成后(对于real或cancelled),为state设置属性并返回success
然后,在MSI控制事件中,您可以检查该属性,并根据业务规则禁止转换到下一个对话框或允许转换(互斥控制事件条件)。您的意思是从自定义操作调用生成对话框吗?我不知道如何从自定义操作显示生成对话框,也不知道如何使用BackgroundProcess类。我是否应该在用户单击“取消”按钮后将网络扫描内容移动到后台线程并退出线程?我知道如何使用winforms窗口来实现这一点,但我不知道在这种情况下如何使用wix生成对话框。你能再解释一下吗?不,在这种情况下,我实际上是说在.NET中处理UI。第一个对话框将调用DoAction YourCustomAction,自定义操作将弹出一个前台模式对话框,显示进度并允许取消,同时允许取消操作。我发现后台进程很容易使用,但若你们知道如何用线程的另一种方式来实现,那个也没问题。好吧,但正如我所知(若我错了请纠正我),在wix安装过程中显示模式对话框的唯一方法是使用“生成对话框”。任何直接使用.net工具(例如winformms)创建的gui都将始终是无模式的,甚至可以出现在安装程序窗口的下方-这是不可接受的。所以,要明确的是:你的意思是我应该调用标准的.net对话框(winforms窗口)还是某种wix/msi对话框?在第一种情况下-似乎不可能使其成为模态,在第二种情况下,我不知道如何使用这种对话框来中断我的网络扫描线程,或者我相当确定有某种方法可以在.NET中创建模态对话框,并确保将其带到前台。您可能需要P/Invoke或其他方法,但这是可以做到的。当窗体加载时,它会在另一个线程上启动后台进程,并等待它返回。同时,您可以按cancel按钮并向后台进程发送消息,以终止后台工作线程,然后退出表单。此时,CA将控制权返回给MSI。这是可以做到的,你可能只需要使用你的.NET排骨。你确定吗?即使我把自定义操作中创建的winforms窗口放在首位,这仍然是错误的,因为.net窗口需要父窗口是模态的(父窗口句柄)。按照您所说的方式,仍然可以单击安装程序窗口并使我的窗口处于非活动状态(如果它有“始终在顶部”标志,则不隐藏,但处于非活动状态),因为这不可能将msi安装程序窗口设置为winforms窗口的父窗口。我已经弄明白了,wix文档也很清楚——他们说,我应该使用生成对话框来显示真正的模态对话框,并与安装程序ui集成。
public static ActionResult GetNetworkComputers(Session session)
{
ListNetworkComputers.NetworkBrowser nb = new ListNetworkComputers.NetworkBrowser();
Microsoft.Deployment.WindowsInstaller.View lView = session.Database.OpenView("DELETE FROM ComboBox WHERE ComboBox.Property='SERVER_LIST'");
lView.Execute();
lView = session.Database.OpenView("SELECT * FROM ComboBox");
lView.Execute();
int Index = 1;
try
{
foreach (string s in nb.getNetworkComputers())
{
Record lRecord = session.Database.CreateRecord(4);
lRecord.SetString(1, "SERVER_LIST");
lRecord.SetInteger(2, Index);
lRecord.SetString(3, s);
lRecord.SetString(4, s);
lView.Modify(ViewModifyMode.InsertTemporary, lRecord);
++Index;
}
}
catch (Exception ex)
{
session.Log(ex.StackTrace);
}
lView.Close();
return ActionResult.Success;
}