PowerShell 脚本的后缀是 .ps1

前提:

ps1 脚本可以帮忙我们快速修改文件内容,还不需要调用文件的底层 api,方便快捷

在编写 CMakeLists 时发现,项目不能够很好的使用 vcpkg tool chain,哪怕是在命令行中指定 vcpkg.cmake

如果只是简单的项目,vcpkg tool chain 可以正常工作,但是在稍微复杂一些的项目中,比如依赖的 vcpkg 的库过多,就会发现在编译时提示找不到相关的库

不过总的来说,这些都不是本文的重点,重点是如何编写好一个 ps1 脚本

正文:

我们需要读取一个文件的内容,并修改文件中的某个变量名,以及在特定的上下文中插入自定义字符串

# 读取项目文件内容
$scriptDir = $PSScriptRoot
$vcxprojPath = Join-Path $scriptDir "\build\project.vcxproj"
$vcxprojContent = Get-Content $vcxprojPath # 定义常量
$configurationPlatformDebug = '"''$(Configuration)|$(Platform)''==''Debug|Win32''"'
$configurationPlatformRelease = '"''$(Configuration)|$(Platform)''==''Release|Win32''"' # 添加 Vcpkg
$targetLine1 = ' <GenerateManifest Condition=' + $configurationPlatformRelease + '>true</GenerateManifest>'
$targetLine2 = ' </PropertyGroup>' # 修改 Debug 配置
$targetLine3 = ' <OutDir Condition=' + $configurationPlatformDebug + '>' + (Join-Path $scriptDir "build\Debug\") + '</OutDir>'
$targetLine4 = ' <IntDir Condition=' + $configurationPlatformDebug + '>project.dir\Debug\</IntDir>'
$targetLine5 = ' <TargetName Condition=' + $configurationPlatformDebug + '>project</TargetName>' # 修改 Release 配置
$targetLine6 = ' <OutDir Condition=' + $configurationPlatformRelease + '>' + (Join-Path $scriptDir "build\Release\") + '</OutDir>'
$targetLine7 = ' <IntDir Condition=' + $configurationPlatformRelease + '>project.dir\Release\</IntDir>'
$targetLine8 = ' <TargetName Condition=' + $configurationPlatformRelease + '>project</TargetName>' $targetLine9 = ' <PropertyGroup Condition=' + $configurationPlatformRelease + ' Label="Configuration">' $targetLine10 = ' <TargetExt Condition=' + $configurationPlatformRelease + '>.exe</TargetExt>' # 要替换的新文本
$newAttributes = @"
<PropertyGroup Label="Vcpkg" Condition=$configurationPlatformDebug>
<VcpkgConfiguration>Debug</VcpkgConfiguration>
</PropertyGroup>
<PropertyGroup Label="Globals">
<VcpkgTriplet Condition="'`$(Platform)'=='Win32'">x86-windows-static</VcpkgTriplet>
</PropertyGroup>
"@ $newTargetLines3 = ' <OutDir Condition=' + $configurationPlatformDebug + '>$(SolutionDir)bin\$(Configuration)\</OutDir>'
$newTargetLines4 = ' <IntDir Condition=' + $configurationPlatformDebug + '>$(SolutionDir)temp\$(Configuration)\$(ProjectName)\</IntDir>'
$newTargetLines5 = ' <TargetName Condition=' + $configurationPlatformDebug + '>$(SolutionName)_d</TargetName>' $newTargetLines6 = ' <OutDir Condition=' + $configurationPlatformRelease + '>$(SolutionDir)bin\Project\$(PJVersion)\</OutDir>'
$newTargetLines7 = ' <IntDir Condition=' + $configurationPlatformRelease + '>$(SolutionDir)temp\$(Configuration)\$(ProjectName)\</IntDir>'
$newTargetLines8 = ' <TargetName Condition=' + $configurationPlatformRelease + '>$(SolutionName)</TargetName>' $newTargetLines9 = ' <ConfigurationType>DynamicLibrary</ConfigurationType>' $newTargetLines10 = ' <TargetExt Condition=' + $configurationPlatformRelease + '>.dll</TargetExt>' $foundLines = @() # 因为只遍历一遍,所以要按先后顺序放置待修改的行
for ($i = 0; $i -lt $vcxprojContent.Length - 1; $i++) {
$line = $vcxprojContent[$i] # 检查是否找到目标行
if ($line -eq $targetLine9) {
$foundLines += $i + 1
} if ($line -eq $targetLine3) {
$foundLines += $i
} if ($line -eq $targetLine4) {
$foundLines += $i
} if ($line -eq $targetLine5) {
$foundLines += $i
} if ($line -eq $targetLine6) {
$foundLines += $i
} if ($line -eq $targetLine7) {
$foundLines += $i
} if ($line -eq $targetLine8) {
$foundLines += $i
} if ($line -eq $targetLine10) {
$foundLines += $i
} if ($line -eq $targetLine1 -and $vcxprojContent[$i + 1] -eq $targetLine2) {
$foundLines += $i + 2
} } # 判断是否找到所有待替换的行
if ($foundLines.Count -eq 9) {
# 替换目标行
$vcxprojContent[$foundLines[0]] = $newTargetLines9
$vcxprojContent[$foundLines[1]] = $newTargetLines3
$vcxprojContent[$foundLines[2]] = $newTargetLines4
$vcxprojContent[$foundLines[3]] = $newTargetLines5
$vcxprojContent[$foundLines[4]] = $newTargetLines6
$vcxprojContent[$foundLines[5]] = $newTargetLines7
$vcxprojContent[$foundLines[6]] = $newTargetLines8
$vcxprojContent[$foundLines[7]] = $newTargetLines10
# 在目标行后面插入新文本
$vcxprojContent = [System.Collections.ArrayList]($vcxprojContent -split "`r`n")
$vcxprojContent.Insert($foundLines[8], $newAttributes)
# 将修改后的内容保存回文件
$vcxprojContent | ForEach-Object { $_ } | Set-Content $vcxprojPath Write-Host "Target lines replaced successfully in project."
} else {
Write-Host "Specific lines not found in the file in project."
}

我们还可以通过 ps1 脚本改文件编码格式

比如 visual studio 默认接受 UTF-16 编码的 rc 文件,而我们使用 CMake 中的 configure_file 函数生成的文件默认是 UTF-8 编码

那么我们可以使用 -Encoding 来改变

# project.rc 转为 UTF-16 编码
$rcPath = Join-Path $scriptDir "\build\project.rc"
# 读取 UTF-8 编码的文件内容
$content = Get-Content -Path $rcPath -Encoding UTF8
# 将内容以 UTF-16 编码保存
Set-Content -Path $rcPath -Value $content -Encoding Unicode

补充:

时间匆忙,无法对每个 ps1 的函数一一讲解,有兴趣的可以查阅文档来了解其作用

如何编写一个 PowerShell 脚本的更多相关文章

  1. 编写一个BAT脚本协助运维人员遇到问题时候调测数据库是否有效连接成功的操作攻略

    简单摘要: 1.内网系统出现故障需要排查 2.运维人员不熟悉数据库操作,没法通过连接数据库和执行SQL语句的方式排查数据库及数据是否正常 3.解决方案:编写一个bat脚本,运维人员双击运行即可.   ...

  2. 工程师技术(五):Shell脚本的编写及测试、重定向输出的应用、使用特殊变量、编写一个判断脚本、编写一个批量添加用户脚本

    一.Shell脚本的编写及测 目标: 本例要求两个简单的Shell脚本程序,任务目标如下: 1> 编写一个面世问候 /root/helloworld.sh 脚本,执行后显示出一段话“Hello ...

  3. shell编写一个判断脚本

                                                              shell编写一个判断脚本 4.1问题 本例要求在虚拟机server0上创建/roo ...

  4. 从0开始的Python学习013编写一个Python脚本

    通过之前的学习我们已经了解了Python的很多基础运用了,现在我们尝试着做一个有使用价值的小脚本. 问题 需求: 我想要一个可以给我备份重要文件的程序. 需求分析: 首先文件是有存储路径,文件的路径和 ...

  5. python+pytest接口自动化(12)-自动化用例编写思路 (使用pytest编写一个测试脚本)

    经过之前的学习铺垫,我们尝试着利用pytest框架编写一条接口自动化测试用例,来厘清接口自动化用例编写的思路. 我们在百度搜索天气查询,会出现如下图所示结果: 接下来,我们以该天气查询接口为例,编写接 ...

  6. 分享我编写的powershell脚本:ssh-copy-id.ps1

      问:通过[字符串界面].如何从win,通过ssh,连接到sshd?答:在任意版本win中,通过cmd.exe,powershell.exe中调用ssh.exe,连接sshd.   问:通过[pow ...

  7. 编写一个python脚本功能-备份

    版本一 解决方案当我们基本完成程序的设计,我们就可以编写代码了,它是对我们的解决方案的实施.版本一例10.1 备份脚本——版本一 #!/usr/bin/python # Filename: backu ...

  8. 1.编写一个shell脚本

    一.shell和shell脚本 在linux系统下,以 #/bin/bash开头的文本会被shell解释器进行解释.   shell是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操 ...

  9. sql server编写一个语句脚本自动清空各表数据以初始化数据库

    问题:有时已有项目要移植,例如原来在广州地区使用的某系统,突然说惠州那边也要用这套一样的系统.或者,在demo环境下弄了一些测试数据.然后要清空全部表数据.如果表比较多的话,逐个表手工编写脚本就太麻烦 ...

  10. Python编写一个Python脚本

    我想要一个可以为我的所有重要文件创建备份的程序.(下面测试环境为python2.7) 1.backup_ver1.py #!/usr/bin/python import os import time ...

随机推荐

  1. [转帖]Linux 页表、大页与透明大页

    一. 内存映射与页表 1. 内存映射 我们通常所说的内存容量,指的是物理内存,只有内核才可以直接访问物理内存,进程并不可以. Linux 内核给每个进程都提供了一个独立的虚拟地址空间,并且这个地址空间 ...

  2. [转帖]Elasticsearch 技术分析(七): Elasticsearch 的性能优化

    https://www.cnblogs.com/jajian/p/10176604.html 硬件选择# Elasticsearch(后文简称 ES)的基础是 Lucene,所有的索引和文档数据是存储 ...

  3. Nginx反向代理总结

    反向代理的种类 1. LVS的方案 2. DNS轮询的方案 3. Nginx的4层代理 4. Nginx的7层代理 5. 网络NAT的处理 Nginx的反向代理-四层` 编译时增加 --with-st ...

  4. Linux下面sysstat的安装与简介

    https://blog.51cto.com/smoke520/2160073   在Linux系统下获取sysstat-10.0.5.tar.gz的两种方式: 方式一: 下载sysstat-10.0 ...

  5. [转贴]汉字编码:GB2312, GBK, GB18030, Big5

    汉字编码:GB2312, GBK, GB18030, Big5 https://www.cnblogs.com/malecrab/p/5300497.html 前一篇博文:ANSI是什么编码?中有这样 ...

  6. Linux无头模式使用mat分析dump的方法

    摘要 mat可以很好的进行jvm的内存dump的分析. 但是大部分服务器是没有GUI界面的. 而且就算是有GUI界面也很难直接使用. 但是随着jvm堆区越来越大. WindowsPC机器已经很难进行分 ...

  7. SQLSERVER 标准版与企业版的版本标识区别

    1.  windows 标准版  sqlserver 标准版 2. Windows 数据中心版 sqlserver 企业版 3. Win10 之后 服务器版本缩减的很厉害 只有两个版本了 如图示 4. ...

  8. K8S多节点情况下使用nginx负载ingress或者是istio域名服务的处理

    K8S多节点情况下使用nginx负载ingress或者是istio域名服务的处理 背景 公司内部有一个自建的K8S测试集群.同事这边使用istio或者是ingress发布了一个域名服务. 公司这边的D ...

  9. 小程序字节转GBK及UTF8

    前段时间在Android原生搞的BLE扫码枪又要移植到小程序上来.本以为小程序不支持BLE的,结果一搜,还真支持-_-|| . 蓝牙部分问题不大,遇到的主要问题是,小程序环境如何对字符编码进行判断以及 ...

  10. 【0基础学爬虫】爬虫基础之自动化工具 Playwright 的使用

    大数据时代,各行各业对数据采集的需求日益增多,网络爬虫的运用也更为广泛,越来越多的人开始学习网络爬虫这项技术,K哥爬虫此前已经推出不少爬虫进阶.逆向相关文章,为实现从易到难全方位覆盖,特设[0基础学爬 ...