Differences
This shows you the differences between the selected revisions of the page.
| library_example_moves_files_keeping_directory_structure 2016-04-01 | library_example_moves_files_keeping_directory_structure 2023-11-15 (current) | ||
| Line 5: | Line 5: | ||
| ===== Upload ===== | ===== Upload ===== | ||
| - | |||
| - | //The upload examples rely on ''Session.TranslateLocalPathToRemote'' which will be available in the upcoming WinSCP 5.8.3. You can implement your alternative instead meanwhile.// &future | ||
| ==== C# ==== | ==== C# ==== | ||
| - | Use the ''[[https://msdn.microsoft.com/en-us/library/dd383689.aspx|DirectoryInfo.EnumerateFileSystemInfos]]'' method to walk the source local tree. | + | Use the ''[[dotnet>system.io.directoryinfo.enumeratefilesysteminfos|DirectoryInfo.EnumerateFileSystemInfos]]'' method to walk the source local tree. |
| <code csharp> | <code csharp> | ||
| Line 31: | Line 29: | ||
| UserName = "user", | UserName = "user", | ||
| Password = "mypassword", | Password = "mypassword", | ||
| - | SshHostKeyFingerprint = "ssh-rsa 2048 xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx" | + | SshHostKeyFingerprint = "ssh-rsa 2048 xxxxxxxxxxx..." |
| }; | }; | ||
| Line 43: | Line 41: | ||
| // Enumerate files and directories to upload | // Enumerate files and directories to upload | ||
| - | IEnumerable<FileSystemInfo> fileInfos = new DirectoryInfo(localPath).EnumerateFileSystemInfos("*", SearchOption.AllDirectories); | + | IEnumerable<FileSystemInfo> fileInfos = |
| + | ···················new DirectoryInfo(localPath).EnumerateFileSystemInfos( | ||
| + | ························"*", SearchOption.AllDirectories); | ||
| foreach (FileSystemInfo fileInfo in fileInfos) | foreach (FileSystemInfo fileInfo in fileInfos) | ||
| { | { | ||
| - | string remoteFilePath = session.TranslateLocalPathToRemote(fileInfo.FullName, localPath, remotePath); | + | string remoteFilePath = |
| + | RemotePath.TranslateLocalPathToRemote( | ||
| + | ····························fileInfo.FullName, localPath, remotePath); | ||
| if (fileInfo.Attributes.HasFlag(FileAttributes.Directory)) | if (fileInfo.Attributes.HasFlag(FileAttributes.Directory)) | ||
| Line 59: | Line 61: | ||
| else | else | ||
| { | { | ||
| - | Console.WriteLine(string.Format("Moving file {0}...", fileInfo.FullName)); | + | Console.WriteLine("Moving file {0}...", fileInfo.FullName); |
| // Upload file and remove original | // Upload file and remove original | ||
| session.PutFiles(fileInfo.FullName, remoteFilePath, true).Check(); | session.PutFiles(fileInfo.FullName, remoteFilePath, true).Check(); | ||
| Line 77: | Line 79: | ||
| </code> | </code> | ||
| - | ==== PowerShell ==== | + | ==== [[upload_powershell]] PowerShell ==== |
| + | |||
| + | You can install this script as an [[extension|WinSCP extension]] by using this page URL in the //[[ui_pref_commands#extensions|Add Extension]]// command. | ||
| <code powershell - UploadDeleteKeepStructure.ps1> | <code powershell - UploadDeleteKeepStructure.ps1> | ||
| - | # @name Upload and Delete but Keep &Directory Structure | + | # @name Upload and Delete Files |
| - | # @command powershell.exe -ExecutionPolicy Bypass -File "%EXTENSION_PATH%" -sessionUrl "!S" -remotePath "!/" -localPath "!\" -pause | + | # @command powershell.exe -ExecutionPolicy Bypass -File "%EXTENSION_PATH%" ^ |
| - | # @description Moves files from local directory and its subdirectories to a remote directory, but keeps local directory structure | + | # -sessionUrl "!E" -remotePath "!/" -sessionLogPath "%SessionLogPath%" ^ |
| - | # @version 1 | + | # -pause !& |
| - | # @requires WinSCP 5.8.3 | + | # @description Moves selected local files to a remote directory, ^ |
| + | # but keeps local directory structure | ||
| + | # @flag ApplyToDirectories | ||
| + | # @version 5 | ||
| + | # @homepage ~~SELF~~ | ||
| + | # @require WinSCP 5.16 | ||
| + | # @option SessionLogPath -config sessionlogfile | ||
| + | # @optionspage ~~SELF~~#options | ||
| + | · | ||
| param ( | param ( | ||
| - | # Use Generate URL function to obtain a value for -sessionUrl parameter. | + | # Use Generate Session URL function to obtain a value for -sessionUrl parameter. |
| - | [Parameter(Mandatory)] | + | [Parameter(Mandatory = $True)] |
| - | $sessionUrl = "sftp://user:mypassword;fingerprint=ssh-rsa-xx-xx-xx@example.com/", | + | $sessionUrl = "sftp://user:mypassword;fingerprint=ssh-rsa-xxxxxxxxxxx...@example.com/", |
| - | [Parameter(Mandatory)] | + | [Parameter(Mandatory = $True)] |
| $remotePath, | $remotePath, | ||
| - | [Parameter(Mandatory)] | + | $sessionLogPath = $Null, |
| - | ···$localPath, | + | |
| [Switch] | [Switch] | ||
| - | $pause = $False | + | $pause, |
| + | [Parameter(Mandatory = $True, ValueFromRemainingArguments = $True, Position = 0)] | ||
| + | $localPaths | ||
| ) | ) | ||
| + | · | ||
| try | try | ||
| { | { | ||
| Line 103: | Line 115: | ||
| $assemblyPath = if ($env:WINSCP_PATH) { $env:WINSCP_PATH } else { $PSScriptRoot } | $assemblyPath = if ($env:WINSCP_PATH) { $env:WINSCP_PATH } else { $PSScriptRoot } | ||
| Add-Type -Path (Join-Path $assemblyPath "WinSCPnet.dll") | Add-Type -Path (Join-Path $assemblyPath "WinSCPnet.dll") | ||
| + | · | ||
| # Setup session options from URL | # Setup session options from URL | ||
| $sessionOptions = New-Object WinSCP.SessionOptions | $sessionOptions = New-Object WinSCP.SessionOptions | ||
| $sessionOptions.ParseUrl($sessionUrl) | $sessionOptions.ParseUrl($sessionUrl) | ||
| + | · | ||
| $session = New-Object WinSCP.Session | $session = New-Object WinSCP.Session | ||
| - | $session = (Join-Path $env:TEMP "UploadDeleteKeepStructure.log") | + | |
| try | try | ||
| { | { | ||
| + | $session.SessionLogPath = $sessionLogPath | ||
| + | |||
| # Connect | # Connect | ||
| $session.Open($sessionOptions) | $session.Open($sessionOptions) | ||
| - | + | ||
| - | # Enumerate files and directories to upload | + | foreach ($localPath in $localPaths) |
| - | $files = Get-ChildItem $localPath -Recurse | Select-Object -ExpandProperty FullName | + | |
| - | + | ||
| - | foreach ($localFilePath in $files) | + | |
| { | { | ||
| - | $remoteFilePath = $session.TranslateLocalPathToRemote($localFilePath, $localPath, $remotePath) | + | # If the selected item is file, find all contained files and folders recursively |
| - | + | if (Test-Path $localPath -PathType container) | |
| - | if (Test-Path $localFilePath -PathType container) | + | |
| { | { | ||
| - | # Create remote subdirectory, if it does not exist yet | + | $files = |
| - | if (!($session.FileExists($remoteFilePath))) | + | ···················@($localPath) + |
| - | { | + | (Get-ChildItem $localPath -Recurse | Select-Object -ExpandProperty FullName) |
| - | $session.CreateDirectory($remoteFilePath) | + | |
| - | ···············} | + | |
| } | } | ||
| else | else | ||
| { | { | ||
| - | Write-Host ("Moving file {0} to {1}..." -f $localFilePath, $remoteFilePath) | + | $files = $localPath |
| - | # Upload file and remove original | + | } |
| - | ···············$session.PutFiles($localFilePath, $remoteFilePath, $True).Check() | + | |
| + | $parentLocalPath = Split-Path -Parent (Resolve-Path $localPath) | ||
| + | |||
| + | foreach ($localFilePath in $files) | ||
| + | ············{ | ||
| + | ················$remoteFilePath = | ||
| + | [WinSCP.RemotePath]::TranslateLocalPathToRemote( | ||
| + | $localFilePath, $parentLocalPath, $remotePath) | ||
| + | |||
| + | if (Test-Path $localFilePath -PathType container) | ||
| + | { | ||
| + | # Create remote subdirectory, if it does not exist yet | ||
| + | if (!($session.FileExists($remoteFilePath))) | ||
| + | { | ||
| + | $session.CreateDirectory($remoteFilePath) | ||
| + | } | ||
| + | } | ||
| + | else | ||
| + | { | ||
| + | Write-Host "Moving file $localFilePath to $remoteFilePath..." | ||
| + | ····················# Upload file and remove original | ||
| + | ···················$session.PutFiles($localFilePath, $remoteFilePath, $True).Check() | ||
| + | } | ||
| } | } | ||
| } | } | ||
| + | |||
| + | & "$env:WINSCP_PATH\WinSCP.exe" "$sessionUrl" /refresh "$remotePath" | ||
| } | } | ||
| finally | finally | ||
| Line 144: | Line 175: | ||
| $session.Dispose() | $session.Dispose() | ||
| } | } | ||
| - | + | · | |
| - | exit 0 | + | $result = 0 |
| } | } | ||
| - | catch [Exception] | + | catch |
| { | { | ||
| - | Write-Host $_.Exception.Message | + | Write-Host "Error: $($_.Exception.Message)" |
| - | exit 1 | + | $result = 1 |
| } | } | ||
| + | · | ||
| # Pause if -pause switch was used | # Pause if -pause switch was used | ||
| if ($pause) | if ($pause) | ||
| Line 159: | Line 190: | ||
| [System.Console]::ReadKey() | Out-Null | [System.Console]::ReadKey() | Out-Null | ||
| } | } | ||
| + | |||
| + | exit $result | ||
| </code> | </code> | ||
| - | ===== Download ===== | + | === [[options]] Options === |
| + | |||
| + | In the //Session log file//, you can specify a path to a [[logging|session log file]]. | ||
| + | |||
| + | In the //Keyboard shortcut//, you can specify a [[custom_key_shortcuts|keyboard shortcut]] for the extension. | ||
| + | |||
| + | ===== [[download]] Download ===== | ||
| - | For a download, you can use the code from the [[library_example_recursive_download_custom_error_handling|Recursively download directory tree with custom error handling]] example. | + | For a download, you can use the code from the [[library_example_recursive_download_custom_error_handling#tree_download|Explicit implementation of a file tree download section of Recursively download directory tree with custom error handling]] example. |
| Just pass a ''true'' to the optional ''[[library_session_getfiles#remove|remove]]'' parameter of the ''[[library_session_getfiles|Session.GetFiles]]''. | Just pass a ''true'' to the optional ''[[library_session_getfiles#remove|remove]]'' parameter of the ''[[library_session_getfiles|Session.GetFiles]]''. | ||
| Line 170: | Line 209: | ||
| <code csharp> | <code csharp> | ||
| - | session.GetFiles(session.EscapeFileMask(fileInfo.FullName), localFilePath, true); | + | session.GetFiles(remoteFilePath, localFilePath, true).Check(); |
| </code> | </code> | ||
| Line 176: | Line 215: | ||
| <code powershell> | <code powershell> | ||
| - | $session.GetFiles($session.EscapeFileMask($fileInfo.FullName), $localFilePath, $True) | + | $session.GetFiles($remoteFilePath, $localFilePath, $True).Check() |
| </code> | </code> | ||