我有一个小问题导致我的自动构建失败.
当我们打开最近从VS2005转换到VS2008 VS的解决方案时,通过ClearCase请求我们签出解决方案文件.
如果我们允许它,那么它无论如何都不会进行任何更改,默认情况下,ClearCase不喜欢没有更改的签名.所以我们撤消结帐 - 从那时起VS很高兴,它能够写出.suo文件.
如果我们取消读取保护解决方案文件,启动VS2008它会创建.suo文件,如果我们然后取消劫持.sln文件(无论如何都没有改变,因此VS2008没有注意到)并再次启动VS2008它很好 - 不要求结账.
在我的构建脚本中,我从视图中删除所有视图私有文件,然后使用强制取消劫持受控文件进行更新.然后我们构建部署项目(以及所有依赖项),并且当.suo文件被删除时,它每次都属于checkout .sln文件行为.
在构建服务器上,没有任何人看到对话框要求结帐,构建挂起.
我可以更改(也就是bodge)构建脚本以不删除.suo文件,但我宁愿不这样做.
编辑:澄清 - .suo文件未检入ClearClase - 它是由VS2008创建的视图专用文件,但是为了创建此文件,它想要检查.sln文件是不是真正的原因.
进一步编辑:
我找到了解决方案 - 我根据我在这个帖子上的后续帖子禁用了集成.
回到.NET 1.0天,我写了一个方法来返回MS Windows上的快捷方式的目标.它通过使用Windows脚本托管对象模型的互操作和强制通过COM接口执行此操作:
private FileInfo GetFileFromShortcut(FileInfo shortcut)
{
FileInfo targetFile = null;
try
{
IWshRuntimeLibrary.WshShell wShell = new IWshRuntimeLibrary.WshShellClass();
IWshRuntimeLibrary.WshShortcut wShortcut = (IWshRuntimeLibrary.WshShortcut)wShell.CreateShortcut(shortcut.FullName);
// if the file wasn't a shortcut then the TargetPath comes back empty
string targetName = wShortcut.TargetPath;
if (targetName.Length > 0)
{
targetFile = new FileInfo(targetName);
}
}
catch (Exception)
{ // will return a null targetFile if anything goes wrong
}
return targetFile;
}
Run Code Online (Sandbox Code Playgroud)
这仍然让我感到困扰,我希望用更优雅的东西取代它,但前提是替换实际上至少也是如此.我仍然找不到寻找快捷方式目标的本地C#方式.有没有,或者这仍然是做这种事情的最佳方式?
我打电话有从LsaOpenPolicy政策手柄和LookupAccountName帐户的SID ADVAPI32.DLL LsaEnumerateAccountRights功能.
然而,尝试为我可能,我总是又回到0xC0000034它通过LsaNtStatusToWinError翻译后给我"引用的文件不能被发现."
这不是很好.我的代码处理这个并继续使用LsaAddAccountRights授予帐户SID SeServiceLogonRight,所以我知道策略句柄和帐户SID是正常的,因为如果其中一个出现问题就会爆炸.
最终结果是该帐户确实具有所需的权限,因此代码的整体运行.
但是,我在MSI自定义操作中使用它,安装检查以查看该帐户是否有权,如果没有(或如上所述失败),它授予权限并记住它已在安装中完成州.如果发生回滚并且添加了正确的回滚,则将其删除.我们从未在卸载中删除,因为其他应用程序可能已使用我们运行的服务所使用的相同域帐户进行安装.
所以问题是当MSI执行回滚时 - 它总是会删除权限,因为它总是认为已经添加了它.因此,使用LsaEnumerateAccountRights检查权限是为了这个 - 但我无法让它工作.
任何想法 - 请注意,我使用C#与DllImport属性,露出Win32函数,和我之前C#有就是Unix不是世界上最好的Win32编程!
我将XSL放在一起,而不是创建一个NAnt构建脚本,使用XML文件作为输入来定义所有需要构建的项目.我们有许多非常相似的项目,包括标准布局和切换区域的定义标准,因此有一个XML文件定义了开发人员想要发生的事情,而不是描述它是如何完成的,这将极大地有助于构建服务的使用.
我想在产品构建XML文件的早期定义要使用的构建模式,即
<Build>
<BuildModes>
<Mode name="Debug" />
<Mode name="Release" />
</BuildModes>
<ItemsToBuild>
<Item name="first item" .... />
<Item name="second item" .... />
</ItemsToBuild>
</Build>
Run Code Online (Sandbox Code Playgroud)
我想要一个
<xsl:for-each select="/Build/BuildModes/Mode">
<xsl:for-each select="/Build/ItemsToBuild/Item">
<exec program="devenv">
<xsl:attribute name="line">
use the @name from the Mode and other stuff from Item to build up the command line
</xsl:attribute>
</xsl:for-each>
</xsl:for-each>
Run Code Online (Sandbox Code Playgroud)
现在,我可以通过在两个for-each线之间定义来保持Mode/@ name值,但这有点乱,我真正想要做的是翻转nexting以便构建模式在里面Item循环使它构建一种模式然后构建另一种模式.目前它将构建所有调试,然后构建所有发布版本.要做到这一点,我必须有几个声明,这将变得非常混乱.
因此,当源文档中的元素未嵌套时,它会嵌套.
编辑:
好吧,因为下面接受的答案显示在大多数情况下使用for-each是一个坏主意,我已将此示例重新编写为以下内容.它略有不同,因为我正在使用的架构被简化为上面的帖子,但你明白了.
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="ISO-8859-1" indent="yes"/>
<xsl:template match="/BuildDefinition">
<xsl:apply-templates select="/BuildDefinition/VS2008SLN/DeploymentProject"/>
</xsl:template>
<xsl:template match="/BuildDefinition/VS2008SLN/DeploymentProject">
<xsl:apply-templates select="/BuildDefinition/BuildModes/Mode">
<xsl:with-param name="BuildTarget" select="." /> …Run Code Online (Sandbox Code Playgroud)