如何使用Powershell添加/删除对csproj的引用? [英] How do I use Powershell to add/remove references to a csproj?
问题描述
In relation to this previous question I am trying to create a batch file which as part must remove and add a reference to an XML *.csproj file. I have looked at this, this, this and this previous question but as a powershell n00b am unable to get it working (so far).
有人可以帮我以下吗?我想删除VS2010 csproj文件(XML)中的两个特定引用,并添加一个新引用。
Can anyone help me with the following? I want to remove two specific references in a VS2010 csproj file (XML) and add a new reference.
我打开了csproj,可以在以下位置找到引用
I opened the csproj and the reference can be found at the following location
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- ... -->
<!-- Omitted for brevity -->
<!-- ... -->
<ItemGroup Condition="'$(BuildingInsideVisualStudio)' == 'true'">
<AvailableItemName Include="Effect" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SomeDirectory\SomeProjectFile.csproj">
<Project>{AAB784E4-F8C6-4324-ABC0-6E9E0F73E575}</Project>
<Name>SomeProject</Name>
</ProjectReference>
<ProjectReference Include="..\AnotherDirectory\AnotherProjectFile.csproj">
<Project>{B0AA6A94-6784-4221-81F0-244A68C374C0}</Project>
<Name>AnotherProject</Name>
</ProjectReference>
</ItemGroup>
<!-- ... -->
<!-- Omitted for brevity -->
<!-- ... -->
</Project>
基本上我想:
- 删除这两个引用
- 插入对由相对路径指定的预编译DLL的新引用
- 或添加程序集相对路径指定的项目的引用位置
作为一个非常简单的示例,我尝试了以下powershell脚本删除所有ProjectReference节点。我将路径传递给csproj作为参数。我收到错误无法验证参数 XML。参数为空或空
。我可以确认它是 加载csproj并将其保存在原位而未修改,因此路径是正确的。
As a very simple example I have tried the following powershell script to delete all the ProjectReference nodes. I pass the path to csproj as argument. I get the error Cannot validate the argument 'XML'. The Argument is null or empty
. I can confirm it is loading the csproj and saving it in-place unmodified so the path is correct.
param($path)
$MsbNS = @{msb = 'http://schemas.microsoft.com/developer/msbuild/2003'}
function RemoveElement([xml]$Project, [string]$XPath, [switch]$SingleNode)
{
$xml | Select-Xml -XPath $XPath | ForEach-Object{$_.Node.ParentNode.RemoveAll()}
}
$proj = [xml](Get-Content $path)
[System.Console]::WriteLine("Loaded project {0} into {1}", $path, $proj)
RemoveElement $proj "//ProjectReference" -SingleNode
# Also tried
# RemoveElement $proj "/Project/ItemGroup/ProjectReference[@Include=`'..\SomeDirectory\SomeProjectFile.csproj`']" -SingleNode
# but complains cannot find XPath
$proj.Save($path)
我在做什么错?欢迎任何意见/建议:)
What am I doing wrong? Any comments/suggestions welcome :)
推荐答案
我认为问题在于您的XML文件具有默认命名空间 xmlns = http://schemas.microsoft.com/developer/msbuild/2003
。这会导致XPath问题。因此,您的XPath // ProjectReference
将返回0个节点。有两种解决方法:
I think the problem is that your XML file has a default namespace xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
. This causes problems with XPath. So you XPath //ProjectReference
will return 0 nodes. There are two ways to solve this:
- 使用名称空间管理器。
- 使用与名称空间无关的XPath
这是使用命名空间管理器的方法:
Here's is how you could use a namespace manager:
$nsmgr = New-Object System.Xml.XmlNamespaceManager -ArgumentList $proj.NameTable
$nsmgr.AddNamespace('a','http://schemas.microsoft.com/developer/msbuild/2003')
$nodes = $proj.SelectNodes('//a:ProjectReference', $nsmgr)
或:
Select-Xml '//a:ProjectReference' -Namespace $nsmgr
以下是使用与名称空间无关的XPath的方法:
Here's how to do it using namespace agnostic XPath:
$nodes = $proj.SelectNodes('//*[local-name()="ProjectReference"]')
或:
$nodes = Select-Xml '//*[local-name()="ProjectReference"]'
第二种方法可能很危险,因为如果有一个以上的名字可以选择错误的节点,但不是您的情况。
The second approach can be dangerous because if there were more than one namespace it could select the wrong nodes but not it your case.
这篇关于如何使用Powershell添加/删除对csproj的引用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!