我编写了一个应该作为.Net安装程序项目的一部分调用的工具。
它应该询问用户目录,然后更新我的配置。
我使用以下代码来显示文件选择器dlg:
{
FolderBrowserDialog dlg = new FolderBrowserDialog();
dlg.Description = "Trace-Verzeichnis auswählen";
dlg.ShowNewFolderButton = true;
if (DialogResult.OK == dlg.ShowDialog( this ))
{
tbTraceDir.Text = dlg.SelectedPath;
}
}
如果我从命令行运行该工具,FolderBrowserDialog
显示正常。
如果它作为安装程序包的一部分被调用,则从安装程序类中,它会无限期地挂起在ShowDialog()
编辑:从VStudio或命令行运行时的行为相同... 我正在运行.Net 4(不是客户端配置文件)
任何提示我可能做错了什么?
感谢
马里奥
答案 0 :(得分:2)
似乎我错过了这艘船,但我正在寻找类似的东西found an excellent answer that actually works,我也会解释原因。您应该向安装程序项目添加新的自定义操作。然后,您需要做的就是:
[CustomAction]
public static ActionResult SpawnBrowseFolderDialog(Session session)
{
Thread worker = new Thread(() =>
{
FolderBrowserDialog dialog = new FolderBrowserDialog();
dialog.SelectedPath = session["INSTALLFOLDER"];
DialogResult result = dialog.ShowDialog();
session["INSTALLFOLDER"] = dialog.SelectedPath;
});
worker.SetApartmentState(ApartmentState.STA);
worker.Start();
worker.Join();
return ActionResult.Success;
}
或者,您可以在新线程中执行任何您想要的操作......实际上,这可行的原因是您需要分配一个必须具有STA公寓状态的新线程。 Windows中的UI组件通常需要在单线程(STA)单元状态下运行,因为这会在UI组件上强制执行正确的并发,因为一次只允许一个线程修改UI。
答案 1 :(得分:1)
问题是自定义操作等待(无限)用户输入,但它在SYSTEM帐户下运行。
需要UI访问的自定义操作必须安排到具有模拟用户帐户的立即执行的UI序列。
WiX示例:
<CustomAction Id='FooAction'
BinaryKey='FooBinary'
DllEntry='FooEntryPoint'
Execute='immediate'
Return='check'/>
<Binary Id='FooBinary' SourceFile='foo.dll'/>
<InstallUISequence>
<Custom Action='FooAction' After='AppSearch'></Custom>
</InstallUISequence>
答案 2 :(得分:1)
今天我遇到了类似的问题。我有以下代码:
using System;
using System.Windows.Forms;
class dummy{
public static void Main() {
FolderBrowserDialog f = new FolderBrowserDialog();
f.SelectedPath = System.Environment.CurrentDirectory;
f.Description= "Select a folder, for great justice.";
f.ShowNewFolderButton = true;
if(f.ShowDialog() == DialogResult.OK) {
Console.Write(f.SelectedPath);
}
}
}
看起来很好,对吧?它编译和链接没有错误,但生成的可执行文件只是挂起而没有显示文件夹选择器。
为我修复的是在[STAThread]
之前添加Main()
。
using System;
using System.Windows.Forms;
class dummy{
[STAThread]
public static void Main() {
FolderBrowserDialog f = new FolderBrowserDialog();
f.SelectedPath = System.Environment.CurrentDirectory;
f.Description= "Select a folder, for great justice.";
f.ShowNewFolderButton = true;
if(f.ShowDialog() == DialogResult.OK) {
Console.Write(f.SelectedPath);
}
}
}
现在文件夹浏览器窗口正确呈现。