mirror of
https://github.com/PowerShell/PowerShell
synced 2026-06-08 12:12:50 +00:00
Change Get-FileHash to close file handles before writing output (#12474)
This commit is contained in:
@@ -126,49 +126,10 @@ namespace Microsoft.PowerShell.Commands
|
||||
|
||||
foreach (string path in pathsToProcess)
|
||||
{
|
||||
byte[] bytehash = null;
|
||||
string hash = null;
|
||||
Stream openfilestream = null;
|
||||
|
||||
try
|
||||
if (ComputeFileHash(path, out string hash))
|
||||
{
|
||||
openfilestream = File.OpenRead(path);
|
||||
bytehash = hasher.ComputeHash(openfilestream);
|
||||
|
||||
hash = BitConverter.ToString(bytehash).Replace("-", string.Empty);
|
||||
WriteHashResult(Algorithm, hash, path);
|
||||
}
|
||||
catch (FileNotFoundException ex)
|
||||
{
|
||||
var errorRecord = new ErrorRecord(
|
||||
ex,
|
||||
"FileNotFound",
|
||||
ErrorCategory.ObjectNotFound,
|
||||
path);
|
||||
WriteError(errorRecord);
|
||||
}
|
||||
catch (UnauthorizedAccessException ex)
|
||||
{
|
||||
var errorRecord = new ErrorRecord(
|
||||
ex,
|
||||
"UnauthorizedAccessError",
|
||||
ErrorCategory.InvalidData,
|
||||
path);
|
||||
WriteError(errorRecord);
|
||||
}
|
||||
catch (IOException ioException)
|
||||
{
|
||||
var errorRecord = new ErrorRecord(
|
||||
ioException,
|
||||
"FileReadError",
|
||||
ErrorCategory.ReadError,
|
||||
path);
|
||||
WriteError(errorRecord);
|
||||
}
|
||||
finally
|
||||
{
|
||||
openfilestream?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,6 +151,61 @@ namespace Microsoft.PowerShell.Commands
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read the file and calculate the hash.
|
||||
/// </summary>
|
||||
/// <param name="path">Path to file which will be hashed.</param>
|
||||
/// <param name="hash">Will contain the hash of the file content.</param>
|
||||
/// <returns>Boolean value indicating whether the hash calculation succeeded or failed.</returns>
|
||||
private bool ComputeFileHash(string path, out string hash)
|
||||
{
|
||||
byte[] bytehash = null;
|
||||
Stream openfilestream = null;
|
||||
|
||||
hash = null;
|
||||
|
||||
try
|
||||
{
|
||||
openfilestream = File.OpenRead(path);
|
||||
|
||||
bytehash = hasher.ComputeHash(openfilestream);
|
||||
hash = BitConverter.ToString(bytehash).Replace("-", string.Empty);
|
||||
}
|
||||
catch (FileNotFoundException ex)
|
||||
{
|
||||
var errorRecord = new ErrorRecord(
|
||||
ex,
|
||||
"FileNotFound",
|
||||
ErrorCategory.ObjectNotFound,
|
||||
path);
|
||||
WriteError(errorRecord);
|
||||
}
|
||||
catch (UnauthorizedAccessException ex)
|
||||
{
|
||||
var errorRecord = new ErrorRecord(
|
||||
ex,
|
||||
"UnauthorizedAccessError",
|
||||
ErrorCategory.InvalidData,
|
||||
path);
|
||||
WriteError(errorRecord);
|
||||
}
|
||||
catch (IOException ioException)
|
||||
{
|
||||
var errorRecord = new ErrorRecord(
|
||||
ioException,
|
||||
"FileReadError",
|
||||
ErrorCategory.ReadError,
|
||||
path);
|
||||
WriteError(errorRecord);
|
||||
}
|
||||
finally
|
||||
{
|
||||
openfilestream?.Dispose();
|
||||
}
|
||||
|
||||
return hash != null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create FileHashInfo object and output it.
|
||||
/// </summary>
|
||||
|
||||
@@ -77,4 +77,19 @@ Describe "Get-FileHash" -Tags "CI" {
|
||||
$result.Path | Should -Be $testDocument
|
||||
}
|
||||
}
|
||||
|
||||
Context "File should be closed before Get-FileHash writes pipeline output" {
|
||||
It "Should be able to edit the file without 'file is in use' exceptions" {
|
||||
# This test runs against a copy of the document
|
||||
# because it involves renaming it,
|
||||
# and that might break tests added later on.
|
||||
$testDocumentCopy = "${testDocument}-copy"
|
||||
Copy-Item -Path $testdocument -Destination $testDocumentCopy
|
||||
|
||||
$newPath = Get-FileHash -Path $testDocumentCopy | Rename-Item -NewName {$_.Hash} -PassThru
|
||||
$newPath.FullName | Should -Exist
|
||||
|
||||
Remove-Item -Path $testDocumentCopy -Force
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user