如何调试自定义的引导程序应用?

19

我正在使用Burn制作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的目录会动态更改,并出现未加载符号的错误。

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

28
为了调试一个引导程序应用程序,您需要将您的Bundle .wixproj和BA .csproj(如果您正在进行本机.dll,则为.vcxproj)放在同一个解决方案中,并且Bundle项目应依赖于BA项目,以便重建可以正常工作。按照以下步骤,您就可以进入您的代码。
注意:确保您没有以管理员身份运行Visual Studio。如果禁用了UAC,请重新启用它。如果Visual Studio以管理员身份运行,则这些步骤将无法正常工作。
1. 重新构建项目。这将确保您创建了一个带有已更新的BA.dll的Bundle。 2. 在"解决方案资源管理器"中右键单击BA .csproj并选择“设为启动项目”。BA .csproj应加粗显示。 3. 右键单击BA .csproj并选择“属性”。 4. 在BA .csproj的“属性”上选择“调试”选项卡。 5. 在“调试”选项卡中,选择标记为“启动外部程序”的单选按钮。 6. 浏览到构建Bundle的路径。
现在,您可以按F5开始调试。请记住,每次更改BA .csproj时,您还需要确保重新构建Bundle .wixproj。否则,Bundle将使用旧的BA启动,调试器会发现新构建的BA的.pdbs不匹配。
额外的学分:如果您在调试器设置中禁用了"Just My Code"并下载了与您的WiX安装的匹配构建的pdbs.zip和sources.zip,您实际上可以一起步进Burn代码以及您的BA,以查看所有工作方式。

4
有兴趣详细阐述一下为什么如果Visual Studio以管理员权限运行,该过程就无法正确工作吗? - Lynn Crumbling
2
Rob,让Wix项目具有运行/调试功能将会非常缓解压力。这是故意省略的吗?正如你所指出的,即使使用这种变通方法,也需要进行双重构建以确保您运行的代码与您想要运行的代码相同。更改BA.csproj时的任何时间都是您要在那里调试的大部分时间。 - Jason Kleban
请问您如何进入burn调试?我已经将VS指向了pdb,在调试模式下重新构建了burn,但它似乎总是被跳过。我在msiengine.cpp中设置的断点“出错”并告诉我,因为没有为该文档加载符号,所以将跳过它。 - Jon
8
我正在使用你们的流程,点击启动后安装程序会启动。但是,我的断点从未被触发,尽管我的自定义 BA 出现了。我正在使用 Wix 3.10 和 VS 2015 Community。欢迎提供任何提示。 - skjoshi

10

我遵循了Rob在这篇帖子中的建议,但不幸的是它无法为我工作(Visual Studio 2015,Wix 3.10.3,使用WixWPF的托管引导程序应用程序)。没有任何断点被命中。我注意到调试器会将自己附加到错误的进程上,安装程序有两个正在运行的进程(我猜测是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();
}

现在,当我将我的托管引导程序应用程序(使用调试)与Bundle一起编译并运行时,应用程序将不会启动,直到您附加到托管引导程序应用程序工具 > 附加到进程 > 在列表中找到您的exe


谢谢指针。在与你相同的设置中,这似乎对我也有效。 - skjoshi

5

不能从Visual Studio中以调试模式运行自定义BA。

你可以运行生成的exe文件,然后附加Visual Studio到该进程上进行调试(在菜单中选择:工具 > 附加到进程 > 在列表中找到你的exe)。


2
+1:在关闭UAC的情况下对我有用。顺便说一句,在我的BA中,我还在“Run()”的开头加入了一个System.Threading.Thread.Sleep(5000);,这样我就有时间附加了。 - Lynn Crumbling

1

唯一真正有效的是:

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

在您的启动程序UI应用程序(BootstrapperApplication后代)中进行必要的更改。然后从资源管理器启动构建好的bootstrapper.exe,并在“选择即时调试程序”窗口中重用Visual Studio实例。 在重新构建之前不要忘记清除解决方案。这有时可以防止正确调试。
PS:当找不到启动程序UI程序集的正确pdb时,请选择与启动程序设置相同的体系结构。混合使用可能会导致调试问题。
祝好

1
正如其他答案所建议的那样,调试器附加到运行安装程序可执行文件的进程上。你需要手动将调试器附加到像许多人之前生成在临时文件夹下的UI进程。
为了允许自动附加子进程而不需要提及所有额外的代码,你可以按照以下步骤操作:
1. 安装名为MicrosoftChildProcessDebuggingPowerTool的Visual Studio扩展。 2. 像Rob提到的那样设置可执行文件的调试启动操作。 3. 启用本机代码调试(重要)。 4. 打开子进程调试: 调试 -> 其他调试目标 -> 子进程调试设置 -> 启用子进程调试 -> 保存。

0
在你的BA中插入一个MessageBox作为第一行。运行BA,MessageBox将会出现。在点击OK之前,从菜单DEBUG|Attach to Process中选择你的BA并附加。然后点击MessageBox的OK。现在你可以进行调试了!

0
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 扩展,并添加运行代码的命令。或者使用已经存在的扩展,其中一些允许制作自定义命令。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接