使用python脚本批量修改vc工程文件

Posted clever101

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用python脚本批量修改vc工程文件相关的知识,希望对你有一定的参考价值。

作者:朱金灿
来源:clever101的专栏

为什么大多数人学不会人工智能编程?>>>

问题描述

   vc工程文件中的很多属性设置,比如输出目录、中间目录和输出文件名等等。使用vs单独操作设置较为繁琐,如果几十甚至上百个工程操作就更为繁琐了。于是决定编写一个python脚本来实现批量修改vc工程文件。

实现思路

   首先我们打开一个vc工程文件,可以发现它本质上的一个xml文件。如下:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup Label="ProjectConfigurations">
    <ProjectConfiguration Include="Debug|Win32">
      <Configuration>Debug</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|Win32">
      <Configuration>Release</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Debug|x64">
      <Configuration>Debug</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|x64">
      <Configuration>Release</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
  </ItemGroup>
  <PropertyGroup Label="Globals">
    <ProjectGuid>E23129FC-0417-462C-890C-D0EC20E735AB</ProjectGuid>
    <Keyword>Win32Proj</Keyword>
    <RootNamespace>WatermarkAssist</RootNamespace>
    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\\Microsoft.Cpp.Default.props" />
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
    <ConfigurationType>DynamicLibrary</ConfigurationType>
    <UseDebugLibraries>true</UseDebugLibraries>
    <PlatformToolset>v140</PlatformToolset>
    <CharacterSet>Unicode</CharacterSet>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
    <ConfigurationType>DynamicLibrary</ConfigurationType>
    <UseDebugLibraries>false</UseDebugLibraries>
    <PlatformToolset>v140</PlatformToolset>
    <WholeProgramOptimization>true</WholeProgramOptimization>
    <CharacterSet>Unicode</CharacterSet>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
    <ConfigurationType>DynamicLibrary</ConfigurationType>
    <UseDebugLibraries>true</UseDebugLibraries>
    <PlatformToolset>v140</PlatformToolset>
    <CharacterSet>Unicode</CharacterSet>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
    <ConfigurationType>DynamicLibrary</ConfigurationType>
    <UseDebugLibraries>false</UseDebugLibraries>
    <PlatformToolset>v140</PlatformToolset>
    <WholeProgramOptimization>true</WholeProgramOptimization>
    <CharacterSet>Unicode</CharacterSet>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\\Microsoft.Cpp.props" />
  <ImportGroup Label="ExtensionSettings">
  </ImportGroup>
  <ImportGroup Label="Shared">
  </ImportGroup>
  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
    <Import Project="$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>
  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    <Import Project="$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>
  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <Import Project="$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>
  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <Import Project="$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>
  <PropertyGroup Label="UserMacros" />
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
    <LinkIncremental>true</LinkIncremental>
    <OutDir>D:\\Program Files (x86)\\Adobe\\Acrobat 11.0\\Acrobat\\plug_ins</OutDir>
    <IntDir>..\\..\\..\\Intdir\\$(Configuration)_$(Platform)\\$(ProjectName)</IntDir>
    <TargetExt>.api</TargetExt>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <LinkIncremental>true</LinkIncremental>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    <LinkIncremental>false</LinkIncremental>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <LinkIncremental>false</LinkIncremental>
  </PropertyGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
    <ClCompile>
      <PrecompiledHeader>
      </PrecompiledHeader>
      <WarningLevel>Level3</WarningLevel>
      <Optimization>Disabled</Optimization>
      <PreprocessorDefinitions>_DEBUG;WIN_PLATFORM;WIN32;_WINDOWS;WIN_ENV;ACRO_SDK_LEVEL=0x00060000;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <AdditionalIncludeDirectories>..\\..\\Headers\\SDK;..\\..\\Headers\\API;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
    </ClCompile>
    <Link>
      <SubSystem>Windows</SubSystem>
      <GenerateDebugInformation>true</GenerateDebugInformation>
      <AdditionalOptions>/EXPORT:PlugInMain</AdditionalOptions>
    </Link>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <ClCompile>
      <PrecompiledHeader>
      </PrecompiledHeader>
      <WarningLevel>Level3</WarningLevel>
      <Optimization>Disabled</Optimization>
      <PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;WATERMARKASSIST_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </ClCompile>
    <Link>
      <SubSystem>Windows</SubSystem>
      <GenerateDebugInformation>true</GenerateDebugInformation>
    </Link>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    <ClCompile>
      <WarningLevel>Level3</WarningLevel>
      <PrecompiledHeader>
      </PrecompiledHeader>
      <Optimization>MaxSpeed</Optimization>
      <FunctionLevelLinking>true</FunctionLevelLinking>
      <IntrinsicFunctions>true</IntrinsicFunctions>
      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;WATERMARKASSIST_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </ClCompile>
    <Link>
      <SubSystem>Windows</SubSystem>
      <EnableCOMDATFolding>true</EnableCOMDATFolding>
      <OptimizeReferences>true</OptimizeReferences>
      <GenerateDebugInformation>true</GenerateDebugInformation>
    </Link>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <ClCompile>
      <WarningLevel>Level3</WarningLevel>
      <PrecompiledHeader>
      </PrecompiledHeader>
      <Optimization>MaxSpeed</Optimization>
      <FunctionLevelLinking>true</FunctionLevelLinking>
      <IntrinsicFunctions>true</IntrinsicFunctions>
      <PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;WATERMARKASSIST_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </ClCompile>
    <Link>
      <SubSystem>Windows</SubSystem>
      <EnableCOMDATFolding>true</EnableCOMDATFolding>
      <OptimizeReferences>true</OptimizeReferences>
      <GenerateDebugInformation>true</GenerateDebugInformation>
    </Link>
  </ItemDefinitionGroup>
  <ItemGroup>
    <ClCompile Include="PIMain.c" />
    <ClCompile Include="WatermarkAssist.cpp" />
    <ClCompile Include="WatermarkAssistInit.cpp" />
  </ItemGroup>
  <Import Project="$(VCTargetsPath)\\Microsoft.Cpp.targets" />
  <ImportGroup Label="ExtensionTargets">
  </ImportGroup>
</Project>

   因此我们使用python的xml解析库就可以解决问题了。我们看到这个xml文件也是比较容易读懂的,比如Condition="’$(Configuration)|$(Platform)’==‘Debug|Win32’">节点下的<OutDir>节点就是设置输出目录的,<IntDir>节点就是设置临时目录的。

关键代码

   代码不复杂,关键有两处。一是使用python的xml解释库xml.etree.ElementTree解析vc工程文件之前需要先注册命名空间,代码如下:

ET.register_namespace('', "http://schemas.microsoft.com/developer/msbuild/2003")

   二是脚本中的find_nodes函数的使用,调用代码如下:

import xml.etree.ElementTree as ET
from xml.etree.ElementTree import ElementTree,Element
#修改vc工程的输出目录和中间目录、设置输出文件名、pdb文件和导入库文件
def ModifyPrjProperty(tree):
#find_nodes函数负责找到PropertyGroup节点下的所有子节点
    nodes = find_nodes(tree, 'http://schemas.microsoft.com/developer/msbuild/2003PropertyGroup')
    for groupNode in nodes:
        propertyNodes = groupNode.getchildren()
        #遍历子节点
        for propertyNode in propertyNodes:
            if propertyNode.tag == 'http://schemas.microsoft.com/developer/msbuild/2003OutDir':
                print 'finded OutDir'
                #propertyNode.text = "..\\..\\\\..\\\\..\\\\OutDir\\\\$(Configuration)_$(Platform)"
                propertyNode.text = "D:\\\\Program Files (x86)\\\\Adobe\\Acrobat 11.0\\\\Acrobat\\\\plug_ins"
                continue
            if propertyNode.tag == 'http://schemas.microsoft.com/developer/msbuild/2003IntDir':
                print 'finded IntDir'
                propertyNode.text = "..\\..\\..\\..\\Intdir\\$(Configuration)_$(Platform)\\$(ProjectName)"
                continue
    nodes = find_nodes(tree, 'http://schemas.microsoft.com/developer/msbuild/2003ItemDefinitionGroup')
    for groupNode in nodes:
        propertyNodes = groupNode.getchildren()
        for propertyNode in propertyNodes:
            if propertyNode.tag == 'http://schemas.microsoft.com/developer/msbuild/2003ClCompile':
                ClCompileNodes = propertyNode
                for ciNode in ClCompileNodes:
                    if ciNode.tag == 'http://schemas.microsoft.com/developer/msbuild/2003AssemblerListingLocation':
                        print 'finded AssemblerListingLocation'
                        ciNode.text = "$(IntDir)"
                        continue
                    if ciNode.tag == 'http://schemas.microsoft.com/developer/msbuild/2003ObjectFileName':
                        print 'finded ObjectFileName'
                        ciNode.text = "$(IntDir)"
                        continue
                    if ciNode.tag == 'http://schemas.microsoft.com/developer/msbuild/2003ProgramDataBaseFileName':
                        print 'finded ProgramDataBaseFileName'
                        ciNode.text = "$(IntDir)vc$(PlatformToolsetVersion).pdb"
                        continue
                    if ciNode.tag == 'http://schemas.microsoft.com/developer/msbuild/2003RuntimeLibrary':
                        print 'finded RuntimeLibrary'
                        ciNode.text = "MultiThreadedDebugDLL"
                        continue
            if propertyNode.tag == 'http://schemas.microsoft.com/developer/msbuild/2003Link':
                LinkNodes = propertyNode
                for linkNode in LinkNodes:
                    if linkNode.tag == python脚本-批量修改文件名中相同的字符串

Python3 写的远程批量修改文件内容的脚本

Python脚本批量给文件添加内容

python脚本,批量删除文件或文件夹中特定字符

批量修改Linux密码脚本(Python)

批量修改Linux密码脚本(Python)