diff --git a/.gitignore b/.gitignore
index 3c4efe2..9e56738 100644
--- a/.gitignore
+++ b/.gitignore
@@ -258,4 +258,5 @@ paket-files/
# Python Tools for Visual Studio (PTVS)
__pycache__/
-*.pyc
\ No newline at end of file
+*.pyc
+/.dotnet-home/
diff --git a/SFTPSync.sln b/SFTPSync.sln
index b3cce34..22e1f4a 100644
--- a/SFTPSync.sln
+++ b/SFTPSync.sln
@@ -20,6 +20,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
.github\workflows\build.yml = .github\workflows\build.yml
LICENSE.md = LICENSE.md
README.md = README.md
+ UpdateSubModules.bat = UpdateSubModules.bat
EndProjectSection
EndProject
Global
diff --git a/SFTPSyncLib/RemoteSync.cs b/SFTPSyncLib/RemoteSync.cs
index f6197d5..0ad9906 100644
--- a/SFTPSyncLib/RemoteSync.cs
+++ b/SFTPSyncLib/RemoteSync.cs
@@ -110,6 +110,9 @@ public static async Task RunSharedInitialSyncAsync(
return;
}
+ localRootDirectory = Path.TrimEndingDirectorySeparator(Path.GetFullPath(localRootDirectory));
+ remoteRootDirectory = NormalizeRemoteRootDirectory(remoteRootDirectory);
+
try
{
using (var sftp = new SftpClient(host, username, password))
@@ -282,7 +285,8 @@ public async Task InitialSync(string localPath, string remotePath)
foreach (var item in localDirectories)
{
var directoryName = item.Split(Path.DirectorySeparatorChar).Last();
- await InitialSync(localPath + "\\" + directoryName, remotePath + "/" + directoryName);
+ var nextRemotePath = AppendRemotePath(remotePath, directoryName);
+ await InitialSync(localPath + "\\" + directoryName, nextRemotePath);
}
await SyncDirectoryAsync(_sftp, localPath, remotePath, _searchPattern);
@@ -331,7 +335,7 @@ private static string[] FilteredDirectories(string localRootDirectory, string lo
.OrderBy(path => path, StringComparer.OrdinalIgnoreCase))
{
var directoryName = directory.Split(Path.DirectorySeparatorChar).Last();
- var remotePath = current.RemotePath + "/" + directoryName;
+ var remotePath = AppendRemotePath(current.RemotePath, directoryName);
queue.Enqueue((directory, remotePath));
}
}
@@ -359,12 +363,13 @@ private static async Task CreateDirectoriesInternal(
foreach (var item in localDirectories)
{
var directoryName = item.Split(Path.DirectorySeparatorChar).Last();
+ var targetRemotePath = AppendRemotePath(remotePath, directoryName);
if (!remoteDirectories.ContainsKey(directoryName))
{
- Logger.LogInfo($"Creating remote directory {remotePath}{directoryName}");
- sftp.CreateDirectory(remotePath + "/" + directoryName);
+ Logger.LogInfo($"Creating remote directory {targetRemotePath}");
+ sftp.CreateDirectory(targetRemotePath);
}
- await CreateDirectoriesInternal(sftp, localRootDirectory, localPath + "\\" + directoryName, remotePath + "/" + directoryName, excludedFolders);
+ await CreateDirectoriesInternal(sftp, localRootDirectory, localPath + "\\" + directoryName, targetRemotePath, excludedFolders);
}
}
@@ -421,6 +426,32 @@ private string GetRemotePathForLocal(string localPath)
return _remoteRootDirectory + "/" + relativePath;
}
+ private static string NormalizeRemoteRootDirectory(string remoteRootDirectory)
+ {
+ if (remoteRootDirectory == "/")
+ return "/";
+
+ return remoteRootDirectory.TrimEnd('/', '\\');
+ }
+
+ private static string AppendRemotePath(string remotePath, string segment)
+ {
+ if (string.IsNullOrEmpty(segment))
+ return remotePath;
+
+ var normalizedSegment = segment.Replace('\\', '/').Trim('/');
+ if (normalizedSegment.Length == 0)
+ return remotePath;
+
+ if (remotePath == "/")
+ return "/" + normalizedSegment;
+
+ if (string.IsNullOrEmpty(remotePath))
+ return normalizedSegment;
+
+ return remotePath + "/" + normalizedSegment;
+ }
+
private void EnsureConnected()
{
if (_disposed)
diff --git a/SFTPSyncSetup/Product.wxs b/SFTPSyncSetup/Product.wxs
index 74146a9..70374fe 100644
--- a/SFTPSyncSetup/Product.wxs
+++ b/SFTPSyncSetup/Product.wxs
@@ -5,7 +5,7 @@
Id="*"
Name="SFTPSync"
Language="1033"
- Version="1.7"
+ Version="1.8"
Manufacturer="Synergex International Corporation"
UpgradeCode="6000f870-b811-4e22-b80b-5b8956317d09">
diff --git a/SFTPSyncSetup/SFTPSyncSetup.wixproj b/SFTPSyncSetup/SFTPSyncSetup.wixproj
index 04ec8da..9479027 100644
--- a/SFTPSyncSetup/SFTPSyncSetup.wixproj
+++ b/SFTPSyncSetup/SFTPSyncSetup.wixproj
@@ -6,7 +6,7 @@
3.10
5074cbcb-641b-4a9c-b3bc-8dd0b78810a6
2.0
- SFTPSync-1.7
+ SFTPSync-1.8
Package
SFTPSyncSetup
diff --git a/SFTPSyncUI/SFTPSyncUI.csproj b/SFTPSyncUI/SFTPSyncUI.csproj
index ad38383..64e8fc6 100644
--- a/SFTPSyncUI/SFTPSyncUI.csproj
+++ b/SFTPSyncUI/SFTPSyncUI.csproj
@@ -20,10 +20,10 @@
LICENSE.md
True
Synergex International, Inc.
- 1.7
- 1.7
+ 1.8
+ 1.8
preview
- 1.7
+ 1.8
@@ -36,7 +36,7 @@
PreserveNewest
- PreserveNewest
+ Always
PreserveNewest
diff --git a/SFTPSyncUI/docs/SFTPSync.chm b/SFTPSyncUI/docs/SFTPSync.chm
index 80cc187..5c2152a 100644
Binary files a/SFTPSyncUI/docs/SFTPSync.chm and b/SFTPSyncUI/docs/SFTPSync.chm differ
diff --git a/SFTPSyncUI/docs/SFTPSync_files/CompletedSettingsFile.png b/SFTPSyncUI/docs/SFTPSync_files/CompletedSettingsFile.png
index f71437b..1014e69 100644
Binary files a/SFTPSyncUI/docs/SFTPSync_files/CompletedSettingsFile.png and b/SFTPSyncUI/docs/SFTPSync_files/CompletedSettingsFile.png differ
diff --git a/SFTPSyncUI/docs/SFTPSync_files/EmptySettingsDialog.png b/SFTPSyncUI/docs/SFTPSync_files/EmptySettingsDialog.png
index f914963..d317f7d 100644
Binary files a/SFTPSyncUI/docs/SFTPSync_files/EmptySettingsDialog.png and b/SFTPSyncUI/docs/SFTPSync_files/EmptySettingsDialog.png differ
diff --git a/SFTPSyncUI/docs/SFTPSync_files/SettingsFileContent.png b/SFTPSyncUI/docs/SFTPSync_files/SettingsFileContent.png
index 6c5a7e5..94b7bf3 100644
Binary files a/SFTPSyncUI/docs/SFTPSync_files/SettingsFileContent.png and b/SFTPSyncUI/docs/SFTPSync_files/SettingsFileContent.png differ
diff --git a/UpdateSubModules.bat b/UpdateSubModules.bat
new file mode 100644
index 0000000..ec1b037
--- /dev/null
+++ b/UpdateSubModules.bat
@@ -0,0 +1,10 @@
+@echo off
+pushd %~dp0
+
+rem Keep submodules pinned to the commit recorded by this repo.
+git submodule sync --recursive
+git submodule update --init --recursive --checkout
+
+rem Do not auto-pull submodule branches here; that makes the superproject dirty.
+
+popd