【问题标题】:How to debug custom bootstrap application?如何调试自定义引导应用程序?
【发布时间】:2012-06-12 17:44:51
【问题描述】:

我正在使用 Burn for MSI 软件包。我正在使用 Votive (Visual Studio) 和我自己的自定义 BA 而不是 WiXBA。我尝试使用Debugger.Launch() 调试自定义BA。但是当我开始调试时,会出现错误消息。

没有为任何调用堆栈帧加载符号。无法显示源代码

我意识到 package.exe 链接了位于 C:\Documents and Settings\user\Local Settings\Temp\{GUID}\ 的 CustomBA dll。 {GUID} 总是被改变。所以,每当我运行 package.exe 时,总是会更改目录。

我认为这是发生错误的原因。

在 Visual Studio 中,当我使用位于绝对路径 (.../Debug/bin/CustomBA.dll) 的 CustomBA dll 启动 package.exe 时。但执行package.exe后,会链接到Local Settings\Temp\{GUID}目录。因此,当我们开始调试并附加到 CustomBA dll 时,CustomBA dll 的目录会动态更改,并出现No symbols are loaded 错误。

  • 为什么 package.exe 链接位于 C:\Documents and Settings\user\Local Settings\Temp\{GUID}\ 的 dll?我们可以选择路径吗 对于 dll 是静态的吗?
  • 如果我们不能静态选择dll路径,我该如何使用调试 CustomBA 的功能?

【问题讨论】:

    标签: wix windows-installer wix3.6 burn votive


    【解决方案1】:

    要调试引导程序应用程序,您需要在同一个解决方案中同时使用 Bundle .wixproj 和 BA .csproj(或 .vcxproj,如果您正在使用本机 .dll),并且 Bundle 项目应该依赖于 BA项目因此重建工作正常。以下步骤应该允许您单步执行您的代码。

    注意:确保您没有运行提升的 Visual Studio。如果您禁用了 UAC,请重新启用它。如果 Visual Studio 正在提升运行,这些步骤将无法正常工作。

    1. 重建项目。这可确保您创建的 Bundle 中包含更新的 BA.dll。
    2. 在解决方案资源管理器中右键单击 BA .csproj 并选择 Set as StartUp Project。 BA .csproj 应该是粗体。
    3. 右键单击 BA .csproj 并选择 Properties
    4. 在 BA .csproj 的 Properties 上,选择 Debug 选项卡。
    5. Debug 选项卡中,选择标记为Start external program 的单选按钮
    6. 浏览到构建 Bundle 的路径。

    现在,您可以按 F5 并开始调试。请记住,每当您更改 BA .csproj 时,您还需要确保重新构建 Bundle .wixproj。否则,Bundle 将与您的旧 BA 一起启动,并且调试器会发现新构建的 BA 的 .pdbs 不匹配。

    额外的功劳:如果您在调试器设置中禁用 Just My Code 并下载 pdbs.zip 和 sources.zip 以匹配您的 WiX 安装版本,您实际上可以逐步完成刻录代码以及您的BA 看看一切是如何协同工作的。

    【讨论】:

    • 只是好奇你是否有兴趣解释如果 VS 运行提升时进程无法正常工作的原因......
    • Rob,如果允许 Wix 项目具有运行/调试功能,将会极大地缓解压力。这是故意遗漏的吗?正如您所指出的,即使这种解决方法也需要双重构建,以确保您正在运行您认为正在运行的代码。 “任何时候您更改 BA.csproj”是您打算在那里调试的大部分时间。
    • 你能告诉我如何进入烧录吗?我已经将 VS 指向 pdb,在调试模式下重建刻录,但它似乎总是被跳过。我在 msiengine.cpp 中设置的断点是“错误的”,并告诉我它将被跳过,因为没有为文档加载任何符号。
    • 我正在使用您的流程。当我单击开始时,安装程​​序会启动。但是,尽管我的自定义 BA 出现了,但我的断点从未被命中。我正在使用带有 VS 2015 社区的 Wix 3.10。任何提示表示赞赏。
    【解决方案2】:

    我在这篇文章中关注了Rob's suggestion,但遗憾的是我无法让它为我工作(Visual Studio 2015,Wix 3.10.3,使用 WixWPF 管理 Bootstrapper 应用程序)。没有断点被击中。我注意到调试器将自己附加到错误的进程,安装程序有两个正在运行的进程(我猜是 BA 和 Bundle)。当我更改进程时,断点被命中,但我的托管 BA 有我想在调试器实际连接之前调试的代码

    我设法找到了一个解决方案,即在附加调试器之前应用程序不会启动。我将此代码放在我的托管 BA 的构造函数代码隐藏文件(在 DEBUG 块中)中......

    public MainWindow()
    {
    #if DEBUG
        // Do not start until debugger attached
        while(!System.Diagnostics.Debugger.IsAttached)
        {
            System.Threading.Thread.Sleep(1000);
        }
    #endif
        InitializeComponent();
        InstallData = new InstallerInfo();
    }
    

    现在,当我将托管的 Bootstrapper 应用程序(带调试)与 Bundle 一起编译并运行它时,应用程序将不会启动,直到您附加到托管的 Bootstrapper 应用程序 Tools > Attach to Process > Find your exe in the list

    【讨论】:

    • 感谢您的指点。在与您相同的设置中,这似乎也对我有用。
    【解决方案3】:

    不能在 Visual Studio 的调试模式下运行自定义 BA。

    您可以做的是运行生成的 exe 文件,然后将 Visual Studio 附加到可让您调试它的进程。 (在菜单中:Tools > Attach to Process > Find your exe in the list

    【讨论】:

    • +1:在关闭 UAC 的情况下为我工作。 FWIW,我还在我的 BA 的 Run() 开头添加了一个 System.Threading.Thread.Sleep(5000);,这样我就有时间附上。
    【解决方案4】:

    正如上面建议的许多其他答案,调试器附加到运行安装程序可执行文件的进程。您需要手动将调试器附加到在临时文件夹下生成的 UI 进程,就像许多以前所做的那样。

    为了允许子进程自动附加而无需提及所有额外代码,您可以按照上述方式进行:

    1. 安装名为 MicrosoftChildProcessDebuggingPowerTool 的 Visual Studio 扩展。
    2. 在调试启动操作中设置可执行文件,就像 Rob 提到的那样。
    3. 启用本机代码调试(重要)
    4. 通过以下方式打开子进程调试 调试 -> 其他调试目标 -> 子进程调试设置 -> 启用子进程调试 -> 保存

    【讨论】:

      【解决方案5】:

      唯一真正有效的是:

      protected override void Run()
      {
          Debugger.Launch();
      }
      

      在您的引导程序 UI 应用程序(BootstrapperApplication 后代)中。然后从资源管理器中启动构建的 bootstrapper.exe 并在“选择即时调试器”窗口中重用您的 Visual Studio 实例。 不要忘记在重新构建之前清理解决方案。这有时会妨碍正确调试。

      PS:如果在查找引导程序 UI 程序集的正确 pdb 时遇到问题,请选择与引导程序设置相同的体系结构。混合架构可能会导致调试问题。

      干杯

      【讨论】:

        【解决方案6】:

        Rob 的解决方案不起作用。 AhmedBM 的方法可行,但仍可进一步简化,以便 VS 运行 WiX 引导程序进程,然后立即附加到子进程。

        public void Run(EnvDTE80.DTE2 DTE, Microsoft.VisualStudio.Shell.Package package)
        {
            //kill old ones if any
            System.Diagnostics.Process.Start(@"c:\Windows\System32\taskkill.exe", "/F /IM Bootstrapper.exe /T");
            System.Threading.Thread.Sleep(1000);
            //start new one
            System.Diagnostics.Process.Start(@"<solution path>\src\Bootstrapper\bin\Debug\Bootstrapper.exe");
            System.Threading.Thread.Sleep(1000);
        
            foreach (Process proc in DTE.Debugger.LocalProcesses)
            {
                if (proc.Name.ToString().Contains(@".cr\Bootstrapper.exe"))
                {           
                        proc.Attach();
                        return;  
                }
            }
            System.Windows.MessageBox.Show("Bootstrapper Process was not found.");
        }
        

        唯一的问题是您需要 DTE 对象。在早期版本的 VS 中,我们有可以访问的宏。但是在 VS 2017 中我们没有它们。因此,您可以快速制作简单的 VS 扩展并在其中添加运行代码的命令。或者使用已经存在的扩展,其中一些允许自定义命令。

        【讨论】:

          【解决方案7】:

          将 MessageBox 作为 BA 的第一行。运行 BA,MessageBox 就会出现。在点击 OK 之前,从菜单 DEBUG|Attach to Process,选择您的 BA 和 Attach。然后点击MessageBox的OK。现在开始调试!

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-05-04
            • 1970-01-01
            • 2013-04-12
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2023-04-04
            • 2015-03-01
            相关资源
            最近更新 更多