Xml 如何使用Powershell添加/删除对csproj的引用?
关于,我正在尝试创建一个批处理文件,作为一部分,它必须删除并添加对XML*.csproj文件的引用。我已经看过了,和前面的问题,但作为powershell n00b,我无法让它工作(到目前为止) 有人能帮我做以下事情吗?我想删除VS2010 csproj文件(XML)中的两个特定引用,并添加一个新引用 我打开了csproj,可以在以下位置找到参考Xml 如何使用Powershell添加/删除对csproj的引用?,xml,visual-studio-2010,powershell,csproj,Xml,Visual Studio 2010,Powershell,Csproj,关于,我正在尝试创建一个批处理文件,作为一部分,它必须删除并添加对XML*.csproj文件的引用。我已经看过了,和前面的问题,但作为powershell n00b,我无法让它工作(到目前为止) 有人能帮我做以下事情吗?我想删除VS2010 csproj文件(XML)中的两个特定引用,并添加一个新引用 我打开了csproj,可以在以下位置找到参考 <?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="4.0"
<?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>
我做错了什么?欢迎任何评论/建议:)我认为问题在于您的XML文件有一个默认名称空间
xmlns=”http://schemas.microsoft.com/developer/msbuild/2003“
。这会导致XPath出现问题。因此,XPath//ProjectReference
将返回0个节点。有两种方法可以解决此问题:
$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)
或:
下面介绍了如何使用与命名空间无关的XPath:
$nodes = $proj.SelectNodes('//*[local-name()="ProjectReference"]')
或:
第二种方法可能是危险的,因为如果有多个名称空间,它可能会选择错误的节点,但不是您的情况
为了子孙后代,我将提供完整的powershell脚本来添加和删除对csproj文件的引用如果你觉得这有用,请投票支持安迪·阿里斯梅迪的答案,因为他帮助我找到了答案。请随时给我一个+1,当你在它;-)
AddReference.ps1
# Calling convension:
# AddReference.PS1 "Mycsproj.csproj",
# "MyNewDllToReference.dll",
# "MyNewDllToReference"
param([String]$path, [String]$dllRef, [String]$refName)
$proj = [xml](Get-Content $path)
[System.Console]::WriteLine("")
[System.Console]::WriteLine("AddReference {0} on {1}", $refName, $path)
# Create the following hierarchy
# <Reference Include='{0}'>
# <HintPath>{1}</HintPath>
# </Reference>
# where (0) is $refName and {1} is $dllRef
$xmlns = "http://schemas.microsoft.com/developer/msbuild/2003"
$itemGroup = $proj.CreateElement("ItemGroup", $xmlns);
$proj.Project.AppendChild($itemGroup);
$referenceNode = $proj.CreateElement("Reference", $xmlns);
$referenceNode.SetAttribute("Include", $refName);
$itemGroup.AppendChild($referenceNode)
$hintPath = $proj.CreateElement("HintPath", $xmlns);
$hintPath.InnerXml = $dllRef
$referenceNode.AppendChild($hintPath)
$proj.Save($path)
# Calling Convention
# RemoveReference.ps1 "MyCsProj.csproj"
# "..\SomeDirectory\SomeProjectReferenceToRemove.dll"
param($path, $Reference)
$XPath = [string]::Format("//a:ProjectReference[@Include='{0}']", $Reference)
[System.Console]::WriteLine("");
[System.Console]::WriteLine("XPATH IS {0}", $XPath)
[System.Console]::WriteLine("");
$proj = [xml](Get-Content $path)
[System.Console]::WriteLine("Loaded project {0} into {1}", $path, $proj)
[System.Xml.XmlNamespaceManager] $nsmgr = $proj.NameTable
$nsmgr.AddNamespace('a','http://schemas.microsoft.com/developer/msbuild/2003')
$node = $proj.SelectSingleNode($XPath, $nsmgr)
if (!$node)
{
[System.Console]::WriteLine("");
[System.Console]::WriteLine("Cannot find node with XPath {0}", $XPath)
[System.Console]::WriteLine("");
exit
}
[System.Console]::WriteLine("Removing node {0}", $node)
$node.ParentNode.RemoveChild($node);
$proj.Save($path)
哇,非常有用!让我试试这个。感谢您的第一次尝试,我调用了
proj.NameTable'和
nsmgr.AddNamespace`并得到System.Xml.NameTable不包含名为AddNamespace的方法
duh[System.Xml.XmlNamespaceManager]$nsmgr=$proj.NameTable
有效。确定通过此操作删除节点。似乎正在选择节点而没有error@Dr.AndrewBurnett-汤普森我应该注意到这是未经测试的。我更新了我的答案来解决这个问题。不用担心,已经解决了。我用上面的测试XML创建了一个powershell,并一直使用它,直到它将其删除。您的AddNamespace是正确的-使用它可以找到节点并将其删除。谢谢仅供参考。代替[system.console]::WriteLine
您可以使用Write-Host
cmdlet,例如Write-Host(“这是{0}键入“-f”less”)
<代码>-f用于字符串格式:-)
$nodes = Select-Xml '//*[local-name()="ProjectReference"]'
# Calling convension:
# AddReference.PS1 "Mycsproj.csproj",
# "MyNewDllToReference.dll",
# "MyNewDllToReference"
param([String]$path, [String]$dllRef, [String]$refName)
$proj = [xml](Get-Content $path)
[System.Console]::WriteLine("")
[System.Console]::WriteLine("AddReference {0} on {1}", $refName, $path)
# Create the following hierarchy
# <Reference Include='{0}'>
# <HintPath>{1}</HintPath>
# </Reference>
# where (0) is $refName and {1} is $dllRef
$xmlns = "http://schemas.microsoft.com/developer/msbuild/2003"
$itemGroup = $proj.CreateElement("ItemGroup", $xmlns);
$proj.Project.AppendChild($itemGroup);
$referenceNode = $proj.CreateElement("Reference", $xmlns);
$referenceNode.SetAttribute("Include", $refName);
$itemGroup.AppendChild($referenceNode)
$hintPath = $proj.CreateElement("HintPath", $xmlns);
$hintPath.InnerXml = $dllRef
$referenceNode.AppendChild($hintPath)
$proj.Save($path)
# Calling Convention
# RemoveReference.ps1 "MyCsProj.csproj"
# "..\SomeDirectory\SomeProjectReferenceToRemove.dll"
param($path, $Reference)
$XPath = [string]::Format("//a:ProjectReference[@Include='{0}']", $Reference)
[System.Console]::WriteLine("");
[System.Console]::WriteLine("XPATH IS {0}", $XPath)
[System.Console]::WriteLine("");
$proj = [xml](Get-Content $path)
[System.Console]::WriteLine("Loaded project {0} into {1}", $path, $proj)
[System.Xml.XmlNamespaceManager] $nsmgr = $proj.NameTable
$nsmgr.AddNamespace('a','http://schemas.microsoft.com/developer/msbuild/2003')
$node = $proj.SelectSingleNode($XPath, $nsmgr)
if (!$node)
{
[System.Console]::WriteLine("");
[System.Console]::WriteLine("Cannot find node with XPath {0}", $XPath)
[System.Console]::WriteLine("");
exit
}
[System.Console]::WriteLine("Removing node {0}", $node)
$node.ParentNode.RemoveChild($node);
$proj.Save($path)