4

我编写了一个工具,它应该被称为 .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(不是客户端配置文件)

任何提示我可能做错了什么?

谢谢

马里奥

4

3 回答 3

2

似乎我错过了这艘船,但我一直在寻找类似的东西,并找到了一个真正有效的绝佳答案,我也会解释原因。您应该向安装程序项目添加新的自定义操作。然后,您需要做的就是:

[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。

于 2014-11-04T15:52:09.447 回答
1

问题是自定义操作(无限地)等待用户输入,但它在 SYSTEM 帐户下运行。

需要 UI 访问的自定义操作必须安排到 UI 序列,并使用立即执行来模拟用户帐户。

维克斯示例:

<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>
于 2012-04-02T19:44:33.523 回答
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);
        }
    }
}

现在文件夹浏览器窗口正确呈现。

于 2013-04-03T13:29:05.127 回答