如何编写一个 PowerShell 脚本

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 的函数一一讲解,有兴趣的可以查阅文档来了解其作用

  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
中文名: PowerShell脚本编写手册 原名: Windows Powershell Scripting Guide 作者: Ed Wilson 资源格式: PDF 版本: 影印版 出版社: Microsoft Press书号: 073562279发行时间: 2008年 地区: 美国 语言: 英文 内容简介: Get practical guidance for using Windows PowerShell to manage Windows Vista and Windows Server 2008. Written by Ed Wilson, a leading scripting expert and trainer at Microsoft, this reference offers a task-based approach to help you find the information you need for day-to-day tasks. With more than 200 scripts, it offers rich examples that administrators can customize for their own environment and needs. The scripts range in complexity from one-line commands, to full-blown scripts with managed output and command-line arguments examples that are applicable to all skill levels. Includes a companion CD with fully searchable eBook, sample scripts, and other resources for managing your Windows-based environment.Key Book Benefits Delivers more than 200 scripts administrators can customize and use to get up and running quickly Provides multiple ways of accomplishing tasks: from one-line commands to full-blown scripts with managed output and command-line arguments Features a task-oriented approach, and organized to help you quickly find the information you need for your day-to-day activities Includes a companion CD with a fully searchable eBook, sample scripts, and other resources for on-the-job results 目录: 1. The Shell in Windows Powershell. 2. Scripting Windows Powsershell 3. Managing Logs 4. Managing Services 5. Managing Shares 6. Managing Printing 7. Desktop Maintenance 8. Networking 9. Configuration Desktop Settings 10. Managing Post-Deployment Issues 11. Managing User Data 12. Troubleshooting Windows 13. Managing Domain Users 14. Configuring the Cluster Service 15. Managing Internet Information Services 16. Working with the Certificate Store 17. Managing the Terminal Services Service 18. Configuring Network Services 19. Working with Windows Server 2008 Server Core

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值