Powershell脚本正在本地工作,但在Azure发布管道上引发“调用“ReadAllText”时发生异常“

vhmi4jdf  于 2022-12-18  发布在  Shell
关注(0)|答案(1)|浏览(151)

正如我的标题所示,我正在尝试对*Azure发布管道*采取以下措施:
1.打开
.zip
文件
1.查找具有此名称的JSON文件
1.编辑并保存
1.关闭**.zip文件
此外,正如我的标题所述,我设法使它在本地工作,它工作。然而,当我添加
PowerShell任务**
在Linux、macOS或Windows上运行PowerShell脚本
使用下面的代码发送到我的Azure发布管道,它将引发异常:

Exception calling "ReadAllText" with "2" argument(s): "Could not find file 'C:\azagent\A1\_work\r17\a\appsettings.Production.json'."
At C:\azagent\A1\_work\_temp\75ed88f3-4260-42d8-afba-43d0aa0f6a93.ps1:40 char:1+ $JsonData = [IO.File]::ReadAllText($configFile, [Text.Encoding]::GetEncoding(
125 ...

我已经尝试了我的代码片段中所看到的一切,但无法使其工作:

# cd to the agent artifacts directory (where the zip file exist)
cd $env:Agent_ReleaseDirectory
cd "_MyProject.ProjectApi-CI\drop"

$fileToEdit = "appsettings.Production.json"

[Reflection.Assembly]::LoadWithPartialName("System.IO.Compression.FileSystem");
# Open zip and find the particular file (assumes only one inside the Zip file)
$zipfileName = dir -filter '*.zip'
$zip =  [System.IO.Compression.ZipFile]::Open($zipfileName.FullName, "Update")

# $configFile = $zip.Entries.Where({$_.name -like $fileToEdit}) | Select-Object -first 1
$configFile = $zip.Entries.Where({$_.name -like $fileToEdit}) 

# ==================================================================================

# Read the contents of the file
# and IMMEDIATELY Convert file to JSON
$JsonData = [IO.File]::ReadAllText($configFile, [Text.Encoding]::GetEncoding(1252)) | ConvertFrom-Json

# Read the contents of the file
# $content = Get-Content -Path $configFile

# Convert file to JSON
# $JsonData = $text | ConvertFrom-Json

# List all of the Properties of this JSON file
#($JsonData | Get-Member -Type NoteProperty).Name

# Access property by name
# $JsonData.AppSettings.IsDebug

# Change selected variables with new values
$JsonData.AppSettings.setting1 = $true
$JsonData.AppSettings.setting2 = "Some text here"
$JsonData.AppSettings.setting3 = "Some more text here"

# update (json) file with new (json) content (this works only when there is not zip file stuff)
# $JsonData | ConvertTo-Json | Set-Content $configFile

# This will return "PSCustomObject"
# $JsonData.GetType();

# In order to write content of "$JsonData" variable, I need to convert it to string 
# It would also work with "$desiredFile.Write($jsonString | ConvertTo-Json)" but depth is only 2 by default
$jsonString = ConvertTo-Json -InputObject $JsonData -Depth 5
# $jsonString

# ==================================================================================

# Update file with new content
$desiredFile = [System.IO.StreamWriter]($configFile).Open()
$desiredFile.BaseStream.SetLength(0)

# Insert the $text to the file and close
$desiredFile.Write($jsonString)
$desiredFile.Flush()
$desiredFile.Close()

# Write the changes and close the zip file
$zip.Dispose()

所以问题在于:

$JsonData = [IO.File]::ReadAllText($configFile, [Text.Encoding]::GetEncoding(1252)) | ConvertFrom-Json


但是我找不到任何其他方法来读取**.zip**中的文本。例如,Get-Content需要路径。根据我的理解,它抛出异常是因为[IO.File]::ReadAllText需要路径作为第二个变量,但话又说回来,为什么它在本地工作?

**编辑:**我知道为什么它在本地工作。当你用WinRar在本地打开文件时,它会把这个文件添加到temp文件夹。这就是为什么它在本地工作。但是,在写这篇文章的时候,我还没有找到一种方法来做到这一点,因为Azure Release管道上的Powershell版本有问题。

xesrikrc

xesrikrc1#

不确定这是否能解决您的问题,但可以肯定的是,它与每个系统都更兼容,这可能是您当前代码失败的原因。这将使用ZipArchive Class而不是ZipFile打开Zip条目流,然后使用StreamReader读取 wrapped stream。此方法应适用于从Windows PowerShell 5.1到PowerShell Preview 7.3的所有PowerShell版本。0-参考1

Add-Type -AssemblyName System.IO.Compression

$encoding   = [Text.Encoding]::GetEncoding(1252)
$file       = Get-Item .\myZip.zip
$fileStream = $file.Open([IO.FileMode]::Open)
$zipArchive = [IO.Compression.ZipArchive]::new($fileStream, [IO.Compression.ZipArchiveMode]::Update)
# If you know the exact relative path to the file, use this method
# otherwise you can still use your `.Where{ $_.Name -like ... }` method
$zipEntry   = $zipArchive.GetEntry('dir1/dir2/myJson.json')
$zipStream  = $zipEntry.Open()
$reader     = [IO.StreamReader]::new($zipStream, $encoding)
$JsonData = $reader.ReadToEnd() | ConvertFrom-Json
$JsonData.AppSettings.setting1 = $true
$JsonData.AppSettings.setting2 = "Some text here"
$JsonData.AppSettings.setting3 = "Some more text here"
$json   = ConvertTo-Json -InputObject $JsonData -Depth 5
$zipStream.SetLength(0) # => Starts writing from the beginning of the stream
$writer = [IO.StreamWriter]::new($zipStream, $encoding)
$writer.BaseStream.SetLength(0)
$writer.Write($json)
$writer, $reader, $zipEntry, $zipArchive, $fileStream | ForEach-Object Dispose

相关问题