Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/visual-studio-2010/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xml 如何使用Powershell添加/删除对csproj的引用?_Xml_Visual Studio 2010_Powershell_Csproj - Fatal编程技术网

Xml 如何使用Powershell添加/删除对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*.csproj文件的引用。我已经看过了,和前面的问题,但作为powershell n00b,我无法让它工作(到目前为止)

有人能帮我做以下事情吗?我想删除VS2010 csproj文件(XML)中的两个特定引用,并添加一个新引用

我打开了csproj,可以在以下位置找到参考

<?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个节点。有两种方法可以解决此问题:

  • 使用命名空间管理器
  • 使用与命名空间无关的XPath
  • 以下是如何使用命名空间管理器:

    $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)