2

Hello PowerShell Experts,

The script snippet below works when adding files to Zip file. However, if the file to be added is open in another program then it fails with exception, "The process cannot access the file[..]". I tried using [IO.FileShare]::ReadWrite but no success yet.

Any suggestion as to how to open the files for reading and writing to zip regardless whether the file is open in another program or not?

Script Source

# write entries with relative paths as names
foreach ($fname in $FullFilenames) {
    $rname = $(Resolve-Path -Path $fname -Relative) -replace '\.\\',''
    Write-Output $rname
    $zentry = $zip.CreateEntry($rname)
    $zentryWriter = New-Object -TypeName System.IO.BinaryWriter $zentry.Open()
    $zentryWriter.Write([System.IO.File]::ReadAllBytes($fname)) #FAILS HERE
    $zentryWriter.Flush()
    $zentryWriter.Close()
}
user5349170
  • 141
  • 1
  • 12
  • constructor $handle = [System.IO.File]::Open($fname, 'Open', 'Read', 'ReadWrite') opens the file. How do we read the bytes from this file so that it can be written into zip archive? – user5349170 Apr 22 '22 at 19:01
  • 1
    wait, I deleted my comment because you mentioned "I tried using `[IO.FileShare]::ReadWrite`" and that didnt work. does it work what I posted before? – Santiago Squarzon Apr 22 '22 at 19:05
  • Your suggestion works, trying to find how we read the bytes from this opened file for write into zip. PS C:\Temp> $handle CanRead : True CanWrite : False CanSeek : True IsAsync : False Length : 18970 Name : C:\Temp\targetfile.docx Position : 0 Handle : 3104 SafeFileHandle : Microsoft.Win32.SafeHandles.SafeFileHandle CanTimeout : False ReadTimeout : WriteTimeout : – user5349170 Apr 22 '22 at 19:11
  • The script is from following thread, by user user2349693. It works fine without any issue if files are not locked. https://stackoverflow.com/questions/51392050/compress-archive-and-preserve-relative-paths/51394271#51394271 – user5349170 Apr 22 '22 at 19:15

1 Answers1

1

Since we're missing some important part of your code, I'll just assume what might work in this case, and following assumptions based on your comments.

First you would open the file with FileShare.ReadWrite:

$handle = [System.IO.File]::Open($fname, 'Open', 'Read', 'ReadWrite')

Then you should be able to use the .CopyTo(Stream) method from FileStream:

$zentry  = $zip.CreateEntry($rname)
$zstream = $zentry.Open()
$handle.CopyTo($zstream)
$zstream.Flush()
$zstream.Dispose()
$handle.Dispose()
Santiago Squarzon
  • 41,465
  • 5
  • 14
  • 37