private static ProjectId MoveProjectFolders(string oldFolderForProjects, string newFolderForProjects,
string projectPath, ProjectId oldProjectId)
{
List<string> rgErrors = new List<string>();
bool fCopy = MustCopyFoldersAndFiles(oldFolderForProjects, newFolderForProjects);
using (ProgressDialogWithTask progressDlg = new ProgressDialogWithTask(s_threadHelper))
{
string[] subDirs = Directory.GetDirectories(oldFolderForProjects);
progressDlg.Maximum = subDirs.Length;
progressDlg.AllowCancel = false;
progressDlg.Title = string.Format(Properties.Resources.ksMovingProjectsCaption, oldFolderForProjects, newFolderForProjects);
// Move all of the files and folders
progressDlg.RunTask(true, (progressDialog, dummy) =>
{
foreach (string subdir in subDirs)
{
try
{
string sub = Path.GetFileName(subdir);
// If the project folder is not known to be ours don't move the folder.
// This is some protection against moving vital folders if the user does something silly like
// making C:\ the project folder. See FWR-3371.
var destDirName = Path.Combine(newFolderForProjects, sub);
if (!IsFieldWorksProjectFolder(subdir))
{
// It might still be a folder which is the name of a remote server,
// and contains local settings for projects on that server.
// Check each of its subfolders, and move/copy the ones that appear to be settings, if any.
bool movedSomething = false;
foreach (string subsubdir in Directory.GetDirectories(subdir))
{
if (!IsFieldWorksSettingsFolder(subsubdir))
continue;
// We found a project folder one level down. This ought not so to be.
// Maybe we are doing some bizarre move into one of our own subfolders, and this
// was already moved earlier in the main loop? Anyway don't move it, it's not just a settings folder.
if (IsFieldWorksProjectFolder(subsubdir))
continue;
movedSomething = true;
var leafName = Path.GetFileName(subsubdir);
var subDirDest = Path.Combine(destDirName, leafName);
Directory.CreateDirectory(destDirName); // may be redundant (will be after first time) but cheap.
if (fCopy)
{
CopyDirectory(subsubdir, subDirDest);
Directory.Delete(subsubdir, true);
}
else
{
Directory.Move(subsubdir, subDirDest);
}
}
// If we moved something and left nothing behind delete the parent folder.
// (We do a fresh GetDirectories just in case bizarrely we are moving INTO one of our own subfolders,
// and thus even though we moved everything something is still there).
if (movedSomething && Directory.GetDirectories(subdir).Length == 0)
Directory.Delete(subdir);
continue; // with more top-level directories in the projects folder.
}
progressDialog.Message = string.Format(Properties.Resources.ksMovingProject, sub);
progressDialog.Step(1);
if (fCopy)
{
// Recursively copy each subfolder.
CopyDirectory(subdir, destDirName);
Directory.Delete(subdir, true);
}
else
{
Directory.Move(subdir, destDirName);
}
}
catch (Exception e)
{
rgErrors.Add(String.Format("{0} - {1}", Path.GetFileNameWithoutExtension(subdir), e.Message));
}
}
return null;
});
}
if (rgErrors.Count > 0)
{
// Show the user any errors that occured while doing the move
StringBuilder bldr = new StringBuilder();
bldr.AppendLine(Properties.Resources.ksCannotMoveProjects);
foreach (var err in rgErrors)
bldr.AppendLine(err);
bldr.Append(Properties.Resources.ksYouCanTryToMoveProjects);
MessageBox.Show(bldr.ToString(), Properties.Resources.ksProblemsMovingProjects);
}
if (MiscUtils.IsUnix)
{
if (projectPath.StartsWith(oldFolderForProjects))
{
// This is perhaps a temporary workaround. On Linux, FwDirectoryFinder.ProjectsDirectory
// isn't returning the updated value, but rather the original value. This seems to
// last for the duration of the program, but if you exit and restart the program, it
// gets the correct (updated) value!?
// (On the other hand, I somewhat prefer this code which is fairly straightforward and
// obvious to depending on calling some static method hidden in the depths of FDO.)
string projFileName = Path.GetFileName(projectPath);
string projName = Path.GetFileNameWithoutExtension(projectPath);
string path = Path.Combine(Path.Combine(newFolderForProjects, projName), projFileName);
return new ProjectId(path, null);
}
}
else
{
if (projectPath.StartsWith(oldFolderForProjects, StringComparison.InvariantCultureIgnoreCase))
{
return new ProjectId(ClientServerServices.Current.Local.IdForLocalProject(
Path.GetFileNameWithoutExtension(projectPath)), null);
}
}
return oldProjectId;
}