Msbuild 在InvokeProcess TF工作流活动中捕获regsvr32的输出

Msbuild 在InvokeProcess TF工作流活动中捕获regsvr32的输出,msbuild,tfsbuild,Msbuild,Tfsbuild,我有一个构建过程设置,可以使用团队构建构建托管解决方案。此解决方案要求在通过COM与非托管组件交互时,在构建解决方案之前向服务器注册非托管组件 我用来注册ComObject的活动(InvokeProcess)如下所示 regsvr32.exe /s ComObject.ocx regsvr32.exe /u /s ComObject.ocx 我用来注销它的活动(InvokeProcess)如下所示 regsvr32.exe /s ComObject.ocx regsvr32.exe /u

我有一个构建过程设置,可以使用团队构建构建托管解决方案。此解决方案要求在通过COM与非托管组件交互时,在构建解决方案之前向服务器注册非托管组件

我用来注册ComObject的活动(InvokeProcess)如下所示

regsvr32.exe /s ComObject.ocx
regsvr32.exe /u /s ComObject.ocx
我用来注销它的活动(InvokeProcess)如下所示

regsvr32.exe /s ComObject.ocx
regsvr32.exe /u /s ComObject.ocx
我还使用stdOutput和errOutput作为每个操作的消息,将
WriteBuildMessage
WriteBuildError
添加到
InvokeProcess
活动中。我还确保将构建消息的重要性设置为高

我的理解是,这应该将标准输出和错误输出重定向到这些日志记录活动中

只要我没有将MSBuild的
/maxcpucount
参数设置为大于1的任何值,registrion、build和unregistrion就可以正常工作

一旦我将其设置为大于1的值,我们在进程结束时的清理脚本将失败,并在尝试删除相关文件时显示此错误消息

Access to the path '...\ComObject.ocx' is denied.'
我认为发生的情况是,注销活动无法从服务器注销ComObject.ocx,因为当它在多个cpu上运行时,MSBuild没有完成它。然后,当我开始尝试从构建服务器中删除它时,它仍然在系统中注册,并且将由于拒绝访问错误而失败

那么,如何将regsvr32输出到stdOutput和errOutput,以便WriteBuildMessage和writeBuildError活动能够在生成日志中正确显示它呢。如果使用不存在的文件调用regsvr32,则在构建日志中看不到任何内容

我希望这是有道理的

更新

这个问题的解决方案来自pantelif解决方案的一个小调整。我所做的是在引发异常的if块中,我使用以下消息执行WriteBuild错误:

String.Format("ErrorMessage: {0}", New System.ComponentModel.Win32Exception( System.Runtime.InteropServices.Marshal.GetL‌​astWin32Error() ).ToString() )

这允许我从regsvr32.exe获取错误并将其写入构建日志。

至于您的第一个问题:
我相信,通过应用E.Hofman提出的技术,可以捕获输出。

更具体地说,如果您在“InvokeProcess”中构造一个序列,如presented(图也来自Ewald的帖子):


&然后分配“WriteBuildMessage”来标记“ErrorMessage”,您可能最终会在生成的生成日志中获得所需的输出。

这一半适用于regsvr32.exe。因此,我在这里结束的工作是放弃本文中的错误消息部分,重点关注文章中概述的exitCode。在此之后,在引发异常的if块中,我使用以下消息执行WriteBuildError:String.Format(“ErrorMessage:{0}”,New System.ComponentModel.Win32Exception(System.Runtime.InteropServices.Marshal.GetLastWin32Error()).ToString()。这并不能解决我的问题,但它确实帮了我大忙。非常感谢。事实上,根据帖子的标题,把多个问题背在上面是不公平的。您解决了我从regsvr32获取输出的问题。