Error 32 Two-way synchronisation with delete with PowerShell

Advertisement

Stay_happy
Joined:
Posts:
10

Error 32 Two-way synchronisation with delete with PowerShell

Hello,
I use this https://winscp.net/eng/docs/library_example_two_way_synchronize_delete for the synch with am SSH server and I keep getting the error 32.
Error: Exception when calling Resolve with 1 argument(s): "The transfer completed successfully, but the temporary file "Appointments Overview SS2017.pdf.filepart" could not be renamed to the target file "Appointments Overview SS2017.pdf". If the problem persists, try turning off transfer continuation support.
System error. Code: 32.
The process cannot access the file because it is used by another process
(Error message translated from German to English)

The Error occurs with pictures and maybe also with other files.
I don't know of any process that accesses the files and no write protection or similar has been set.
The error occurs on different laptops and also when I open PowerShell as admin and also with different folders that contain images.
Error also occurs with deactivated four program
It occurs sometimes after 10 files, sometimes after 30 or more files.
If anyone could help me I would be very grateful.

Reply with quote

Advertisement

martin
Site Admin
martin avatar
Joined:
Posts:
41,454
Location:
Prague, Czechia

Re: Error 32 Two-way synchronisation with delete with powershell

There's likely some process on the server that picks the newly uploaded files for some inspection and locks them in the process. That prevents WinSCP from renaming them.
It might be the antivirus.
You might workaround that by disabling transfer to temporary file name. Use TransferOptions.ResumeSupport property.
See also Transfer was successfully finished, but temporary transfer file … could not be renamed to target file name …

Reply with quote

Stay_happy
Joined:
Posts:
10

I can not get it working, please help me

Thank you very much for your answere.

The error occurs when transferring .jpg files from the ssh server to my win laptop.
I don't think it is the anti vieren program because the error occurs even with the guard disabled.
I have tried unsuccessfully to modify this PowerShell script https://winscp.net/eng/docs/library_example_two_way_synchronize_delete properly. So that the sync skips the error and continues with the other files.
I have also tried these approaches without any success:
https://winscp.net/forum/viewtopic.php?t=26829
https://winscp.net/eng/docs/library_example_recursive_download_custom_error_handling
https://winscp.net/eng/docs/library_session_queryreceived
Would it be possible for you to please send me the modified PowerShell script? I would be very grateful for it.

Kind regards

Reply with quote

martin
Site Admin
martin avatar
Joined:
Posts:
41,454
Location:
Prague, Czechia

Re: I can not get it working, please help me

You do not want to ignore the error!
You want to disable the transfer to temporary file name.
$transferOptions = New-Object WinSCP.TransferOptions
$transferOptions.ResumeSupport = New-Object WinSCP.TransferResumeSupport
$transferOptions.ResumeSupport.State = [WinSCP.TransferResumeSupportState]::Off
 
$difference.Resolve($session, $transferOptions) | Out-Null

Reply with quote

Stay_happy
Joined:
Posts:
10

I can not find the pasage

I can not find this passage
$transferOptions = New-Object WinSCP.TransferOptions
$transferOptions.ResumeSupport = New-Object WinSCP.TransferResumeSupport
$transferOptions.ResumeSupport.State = [WinSCP.TransferResumeSupportState]::Off
$difference.Resolve($session, $transferOptions) | Out-Null
in this script

Reply with quote

Advertisement

Stay_happy
Joined:
Posts:
10

Thank you a lot, but I have another error

Thank you a lot for the support.
Sometimes during the synchronisation there is a rest of an file that the software can not find. When I search for the file I can't find them too. Only when I copy the complete path from PowerShell and paste it in the Windows 11 explorer, my laptop tries to open the file (so I guess there is something). However it can not open the file and I can not find it in the Windows 11 Explorer.
So how can I modify the synchronisation, to save all errors in a txt and continue even when an error occurs? I want the software to skip the file it can not find. I do not think i can use a mask because I have many diffent files with the problem.

I am using script based on:
https://winscp.net/eng/docs/library_example_two_way_synchronize_delete

Reply with quote

martin
Site Admin
martin avatar

Re: Thank you a lot, but I have another error

Just wrap the $difference.Resolve call in try...catch, log the error and continue.

Reply with quote

Stay_happy
Joined:
Posts:
10

Please help me out, i can not get it running

Could you please build it in this skript? Because i tried a lot but nothing works.
Please use this skript below because I added a exception for ntuser files.
I would be so happy if anyone would help me out because I invested soooo much time in this projekt but I can not get it running.
Thank you a lot.
$transferOptions = New-Object WinSCP.TransferOptions
$transferOptions.ResumeSupport = New-Object WinSCP.TransferResumeSupport
$transferOptions.ResumeSupport.State = [WinSCP.TransferResumeSupportState]::Off
$transferOptions.AddRawSettings("ExcludeHiddenFiles", "1")
$transferOptions.FileMask = "*.* | printru.ini"#habe ich nachträglich hinzugefügt
$transferOptions.FileMask = "*.* | Desktop.ini"; #habe (ich) nachträglich hinzugefügt
$transferOptions.FileMask = "*.* | ntuser.dat";    #habe ich nachträglich hinzugefügt
 
$difference.Resolve($session, $transferOptions) | Out-Null

Reply with quote

Advertisement

martin
Site Admin
martin avatar
Joined:
Posts:
41,454
Location:
Prague, Czechia

Re: Please help me out, i can not get it running

See how continueOnError is implemented in:
Keep local directory up to date (download changed files from remote SFTP/FTP server)
try
{
    $difference.Resolve($session) | Out-Null
}
catch
{
    Write-Host -ForegroundColor Red $_.Exception.Message
    [System.Console]::Beep()
}

Additionally, your code that sets FileMask three times makes no sense. You just overwrite the previous value. You have to set all your three exclusions in one mask:
$transferOptions.FileMask = "| printru.ini, Desktop.ini, ntuser.dat"

Reply with quote

Stay_happy
Joined:
Posts:
10

Could you please impelment it in the script? I do not know how

I have no idea what I have to do regarding the $difference.Resolve.

Could you please implement it in the script for me? I do not know how.
Thank you a lot for your help.

Reply with quote

martin
Site Admin
martin avatar

Re: Could you please impelment it in the script? I do not know how

I do not know what else should I do for you.
What's so complicated about replacing the $difference.Resolve($session) line with the code from my previous post?

Reply with quote

Stay_happy
Joined:
Posts:
10

I realised that it is not an option to skip the error, sorry that i did not believed it.

I tried it as i am supossed to do but get this error every time i try it.
when calling "Resolve" with 2 argument(s):
"The removed file "/29199214_219757.jpg" cannot be overwritten."$$
Select "Delete" to delete and recreate the file instead of overwriting it . $$
File or directory not found .
Error code: 2
Error message from server : NO such file /29199214_219757.jpg".
I spend several hours trying to solve it bye my own. But I was unsuccessful.
Could you please help me?
Thank you.

Reply with quote

Advertisement

martin
Site Admin
martin avatar

Re: I realised that it is not an option to skip the error, sorry that i did not believed it.

So please post your code and session log file (Session.SessionLogPath).

Reply with quote

Stay_happy
Joined:
Posts:
10

My code:
# @name         Two-Way Synchronization with Delete...
# @command      powershell.exe -ExecutionPolicy Bypass -File "%EXTENSION_PATH%" ^
#                   -sessionUrl "!E" -localPath "%LocalPath%" -remotePath "%RemotePath%" ^
#                   -listPath "%ListPath%" -refresh -pause -sessionLogPath "%SessionLogPath%"
# @description  Synchronizes files on local and remote directories including file deletions ^
#                   by remembering a list of previous local files
# @version      2
# @homepage     https://winscp.net/eng/docs/library_example_two_way_synchronize_delete
# @require      WinSCP 5.18.1
# @option       - -run group "Directories"
# @option         LocalPath -run textbox "&Local directory:" "!\"
# @option         RemotePath -run textbox "&Remote directory:" "!/"
# @option       - -run group "Options"
# @option         ListPath -run textbox "Re&member previous local files in:" ^
#                     "%LOCALAPPDATA%\WinSCP\TwoWayDelete\!N.txt"
# @option       - -config group "Logging"
# @option         SessionLogPath -config sessionlogfile
# @optionspage  https://winscp.net/eng/docs/library_example_two_way_synchronize_delete#options
 
param (
    # Use Generate Session URL function to obtain a value for -sessionUrl parameter.
    $sessionUrl = "sftp://user:mypassword;fingerprint=ssh-rsa-xxxxxxxxxxx...@example.com/",
    [Parameter(Mandatory = $True)]
    $localPath,
    [Parameter(Mandatory = $True)]
    $remotePath,
    [Parameter(Mandatory = $True)]
    $listPath,
    $sessionLogPath = $Null,
    [Switch]
    $pause,
    [Switch]
    $refresh
)
 
 
try
{
    # Load WinSCP .NET assembly
    $assemblyPath = if ($env:WINSCP_PATH) { $env:WINSCP_PATH } else { $PSScriptRoot }
    Add-Type -Path (Join-Path $assemblyPath "WinSCPnet.dll")
 
    # Setup session options from URL
    $sessionOptions = New-Object WinSCP.SessionOptions
    $sessionOptions.ParseUrl($sessionUrl)
 
    $listPath = [Environment]::ExpandEnvironmentVariables($listPath)
    $listDir = (Split-Path -Parent $listPath) 
    New-Item -ItemType directory -Path $listDir -Force | Out-Null 
 
    if (Test-Path $listPath)
    {
        Write-Host "Loading list of previous local files..."
        [string[]]$previousFiles = Get-Content $listPath
    }
    else
    {
        Write-Host "No list of previous local files"
        $previousFiles = @()
    }
 
    $needRefresh = $False
 
    $session = New-Object WinSCP.Session
   $fileTransferOptions = New-Object WinSCP.TransferOptions($Null)
   $fileTransferOptions.FileMask = "*.* | Desktop.ini"
 
    try
    {
        $session.SessionLogPath = $sessionLogPath
 
        Write-Host "Connecting..."
        $session.Open($sessionOptions)
 
        Write-Host "Comparing files..."
        $differences =
            $session.CompareDirectories(
                [WinSCP.SynchronizationMode]::Both, $localPath, $remotePath, $False, $False, "Time", $fileTransferOptions)
 
        if ($differences.Count -eq 0)
        {
            Write-Host "No changes found."   
        }
        else
        {
            Write-Host "Synchronizing $($differences.Count) change(s)..."
   # options: new TransferOptions { FileMask = "|*.txt" });
 
 
            foreach ($difference in $differences)
            {
                $action = $difference.Action
                if ($action -eq [WinSCP.SynchronizationAction]::UploadNew)
                {
                    if ($previousFiles -contains $difference.Local.FileName)
                    {
                        $difference.Reverse()
                    }
                    else
                    {
                        $needRefresh = $True
                    }
                }
                elseif ($action -eq [WinSCP.SynchronizationAction]::DownloadNew)
                {
                    $localFilePath =
                        [WinSCP.RemotePath]::TranslateRemotePathToLocal(
                            $difference.Remote.FileName, $remotePath, $localPath)
                    if ($previousFiles -contains $localFilePath)
                    {
                        $difference.Reverse()
                        $needRefresh = $True
                    }
                    else
                    {
                        # noop
                    }
                }
                elseif ($action -eq [WinSCP.SynchronizationAction]::DownloadUpdate)
                {
                    # noop
                }
                elseif ($action -eq [WinSCP.SynchronizationAction]::UploadUpdate)
                {
                    $needRefresh = $True
                }
                else
                {
                    throw "Unexpected difference $action"
                }
 
                Write-Host -NoNewline "$difference ..."
                try
                {
               $transferOptions = New-Object WinSCP.TransferOptions
               $transferOptions.ResumeSupport = New-Object WinSCP.TransferResumeSupport
               $transferOptions.ResumeSupport.State = [WinSCP.TransferResumeSupportState]::Off
               $transferOptions.AddRawSettings("ExcludeHiddenFiles", "1")
                    $transferOptions.FileMask = "| printru.ini, desktop.ini, ntuser.dat, lockfile.lck"
                   
                    
                    
                       $difference.Resolve($session, $transferOptions) | Out-Null
                                       
                    Write-Host -NoNewline " Done."
                }
                finally
                {
                    Write-Host
                }
            }
        }
    }
    finally
    {
        # Disconnect, clean up
        $session.Dispose()
    }
 
    # Refresh the remote directory in WinSCP GUI, if it was changed and -refresh switch was used
    if ($refresh -and $needRefresh)
    {
        Write-Host "Reloading remote directory..."
        & "$env:WINSCP_PATH\WinSCP.exe" "$sessionUrl" /refresh "$remotePath"
    }
 
    Write-Host "Saving current local file list..."
    $localFiles =
        Get-ChildItem -Recurse -Path $localPath |
        Select-Object -ExpandProperty FullName
    Set-Content $listPath $localFiles
 
    Write-Host "Done."
 
    $result = 0
}
catch
{
    Write-Host "Error: $($_.Exception.Message)"
    $result = 1
}
 
# Pause if -pause switch was used
if ($pause)
{
    Write-Host "Press any key to exit..."
    [System.Console]::ReadKey() | Out-Null
}
 
exit $result
I have no session log file.

Reply with quote

Stay_happy
Joined:
Posts:
10

I did it and i managed it to get it running but then i noticed a problem. If there is an error during the sync. and it saves the file list then it will delete everything on the pc that was not sucessfully copied to the server.
So i tried to get my first approach running without the error skipping to avoid this hazard.
And this is the code i posted.

Reply with quote

Advertisement

You can post new topics in this forum