Example #1
0
        /// <summary>
        /// Move item within the project from one location to where it already exists, skipping the move.
        /// </summary>
        private void MoveDuplicateFileNameSkipMove(MoveDelegate mover)
        {
            foreach (var projectType in ProjectTypes)
            {
                var testDef = new ProjectDefinition("MoveDuplicateFileName",
                                                    projectType,
                                                    ItemGroup(
                                                        Folder("Folder"),
                                                        Content("textfile.txt", "root"),
                                                        Content("Folder\\textfile.txt", "Folder")
                                                        )
                                                    );

                using (var solution = testDef.Generate().ToVs()) {
                    mover(
                        solution.FindItem("MoveDuplicateFileName", "Folder"),
                        solution.FindItem("MoveDuplicateFileName", "textfile.txt")
                        );

                    using (var dialog = OverwriteFileDialog.Wait(solution.App)) {
                        dialog.No();
                    }

                    solution.App.WaitForDialogDismissed();

                    solution.AssertFileExistsWithContent("root", "MoveDuplicateFileName", "textfile.txt");
                    solution.AssertFileExistsWithContent("Folder", "MoveDuplicateFileName", "Folder", "textfile.txt");
                }
            }
        }
Example #2
0
        public static OverwriteFileDialog Wait(VisualStudioApp app)
        {
            var hwnd = app.WaitForDialog();

            Assert.AreNotEqual(IntPtr.Zero, hwnd, "Did not find OverwriteFileDialog");
            var element = AutomationElement.FromHandle(hwnd);

            try
            {
                Assert.IsNotNull(element.FindFirst(
                                     TreeScope.Descendants,
                                     new PropertyCondition(AutomationElement.AutomationIdProperty, "_allItems")
                                     ), "Not correct dialog - missing '_allItems'");
                Assert.IsNotNull(element.FindFirst(
                                     TreeScope.Descendants,
                                     new PropertyCondition(AutomationElement.AutomationIdProperty, "_yes")
                                     ), "Not correct dialog - missing '_yes'");

                OverwriteFileDialog res = new OverwriteFileDialog(app, element);
                element = null;
                return(res);
            }
            finally
            {
                if (element != null)
                {
                    AutomationWrapper.DumpElement(element);
                }
            }
        }
Example #3
0
        /// <summary>
        /// Cut 2 items, paste where they exist, skip pasting the 1st one but paste the 2nd.
        ///
        /// The 1st item shouldn't be removed from the parent hierarchy, the 2nd should, and only the 2nd item should be overwritten.
        /// </summary>
        private void MoveDuplicateFileNamesCrossProjectSkipOne(MoveDelegate mover)
        {
            foreach (var projectType in ProjectTypes)
            {
                var projectDefs = new[] {
                    new ProjectDefinition("MoveDuplicateFileName",
                                          projectType,
                                          ItemGroup(
                                              Content("textfile1.txt", "textfile1 - lang"),
                                              Content("textfile2.txt", "textfile2 - lang")
                                              )
                                          ),
                    new ProjectDefinition("MoveDuplicateFileName2",
                                          projectType,
                                          ItemGroup(
                                              Folder("Folder"),
                                              Content("textfile1.txt", "textfile1 - 2"),
                                              Content("textfile2.txt", "textfile2 - 2")
                                              )
                                          )
                };

                using (var solution = SolutionFile.Generate("MoveDuplicateFileName", projectDefs).ToVs()) {
                    var item1 = solution.FindItem("MoveDuplicateFileName", "textfile1.txt");
                    var item2 = solution.FindItem("MoveDuplicateFileName", "textfile2.txt");
                    mover(
                        solution.FindItem("MoveDuplicateFileName2"),
                        item1,
                        item2
                        );

                    using (var dialog = OverwriteFileDialog.Wait(solution.App)) {
                        dialog.No();
                    }

                    System.Threading.Thread.Sleep(1000);

                    using (var dialog = OverwriteFileDialog.Wait(solution.App)) {
                        dialog.Yes();
                    }

                    solution.App.WaitForDialogDismissed();

                    solution.AssertFileExistsWithContent("textfile1 - lang", "MoveDuplicateFileName", "textfile1.txt");
                    solution.AssertFileExistsWithContent("textfile2 - lang", "MoveDuplicateFileName", "textfile2.txt");
                    solution.AssertFileExistsWithContent("textfile1 - 2", "MoveDuplicateFileName2", "textfile1.txt");
                    solution.AssertFileExistsWithContent("textfile2 - lang", "MoveDuplicateFileName2", "textfile2.txt");
                }
            }
        }
Example #4
0
        /// <summary>
        /// Cut 2 items, paste where they exist, skip pasting the 1st one but paste the 2nd.
        ///
        /// The 1st item shouldn't be removed from the parent hierarchy, the 2nd should, and only the 2nd item should be overwritten.
        /// </summary>
        private void MoveDuplicateFileNamesFoldersSkipOne(MoveDelegate mover)
        {
            foreach (var projectType in ProjectTypes)
            {
                var testDef = new ProjectDefinition("MoveDuplicateFileName",
                                                    projectType,
                                                    ItemGroup(
                                                        Folder("Source"),
                                                        Content("Source\\textfile1.txt", "source1"),
                                                        Content("Source\\textfile2.txt", "source2"),

                                                        Folder("Target"),
                                                        Content("Target\\textfile1.txt", "target1"),
                                                        Content("Target\\textfile2.txt", "target2")
                                                        )
                                                    );

                using (var solution = testDef.Generate().ToVs()) {
                    mover(
                        solution.FindItem("MoveDuplicateFileName", "Target"),
                        solution.FindItem("MoveDuplicateFileName", "Source", "textfile1.txt"),
                        solution.FindItem("MoveDuplicateFileName", "Source", "textfile2.txt")
                        );

                    using (var dialog = OverwriteFileDialog.Wait(solution.App)) {
                        dialog.No();
                    }

                    System.Threading.Thread.Sleep(1000);

                    using (var dialog = OverwriteFileDialog.Wait(solution.App)) {
                        dialog.Yes();
                    }

                    solution.App.WaitForDialogDismissed();

                    solution.AssertFileExistsWithContent("source1", "MoveDuplicateFileName", "Source", "textfile1.txt");
                    solution.AssertFileDoesntExist("MoveDuplicateFileName", "textfile2.txt");
                    solution.AssertFileExistsWithContent("target1", "MoveDuplicateFileName", "Target", "textfile1.txt");
                    solution.AssertFileExistsWithContent("source2", "MoveDuplicateFileName", "Target", "textfile2.txt");
                }
            }
        }
Example #5
0
        //backup files
        public static void BackupFiles(string sFolderPath)
        {
            var dontAskAgain  = false;
            var yesNo         = false;
            var deleteBackups = false;
            var iStep         = 0;

            RefreshInfo(sFolderPath, false, false);

            MainForm.Log_WriteLine("-----");
            MainForm.Log_WriteLine("Starting backup of " + backupList.Count + " files");
            MainForm.Log_WriteLine("-----");

            foreach (var s in backupList)
            {
                var sBackupFile  = s.Replace(".ddsified", "");
                var sDDSToDelete = Path.ChangeExtension(sBackupFile, "dds");

                if (File.Exists(sDDSToDelete))
                {
                    File.Delete(sDDSToDelete);
                }

                if (File.Exists(sBackupFile))
                {
                    if (!dontAskAgain)
                    {
                        var dialog = new OverwriteFileDialog();

                        yesNo = (dialog.CustomShowDialog(sBackupFile, out dontAskAgain, ref deleteBackups) == DialogResult.Yes);
                    }

                    if (yesNo)
                    {
                        File.Delete(sBackupFile);
                        File.Move(s, sBackupFile);

                        MainForm.Log_WriteLine("Reverting " + sDDSToDelete + " to " + sBackupFile);
                    }
                    else
                    {
                        if (deleteBackups)
                        {
                            File.Delete(s);
                        }

                        MainForm.Log_WriteLine("Skipping backup of " + sBackupFile);
                    }
                }
                else
                {
                    File.Move(s, sBackupFile);
                    MainForm.Log_WriteLine("Reverting " + sDDSToDelete + " to " + sBackupFile);
                }

                iStep += 1;

                MainForm.ReportProgress(Convert.ToInt32((iStep / backupList.Count) * 100), "Reverting " + Path.GetFileName(sBackupFile) + ", file " + iStep + "\\" + backupList.Count);
                MainForm.Log_WriteLine("---");
                Application.DoEvents();
            }

            MainForm.Log_WriteLine("-----");
            MainForm.Log_WriteLine("Backup done! " + backupList.Count + " files processed.");
            MainForm.Log_WriteLine("-----");
        }
            /// <summary>
            /// Tests to see if we can add the folder to the project.  Returns true if it's ok, false if it's not.
            /// </summary>
            /// <param name="folderToAdd">Project reference (from data object) using the format: {Guid}|project|folderPath</param>
            /// <param name="targetNode">Node to add the new folder to</param>
            private Addition CanAddFolderFromProjectReference(string folderToAdd) {
                Utilities.ArgumentNotNullOrEmpty(folderToAdd, "folderToAdd");

                var targetFolderNode = TargetNode.GetDragTargetHandlerNode();

                string folder;
                IVsHierarchy sourceHierarchy;
                GetPathAndHierarchy(folderToAdd, out folder, out sourceHierarchy);

                // Ensure we don't end up in an endless recursion
                if (Utilities.IsSameComObject(Project, sourceHierarchy)) {
                    if (String.Equals(folder, targetFolderNode.FullPathToChildren, StringComparison.OrdinalIgnoreCase)) {
                        if (DropEffect == DropEffect.Move &&
                            IsBadMove(targetFolderNode.FullPathToChildren, folder, false)) {
                            return null;
                        }
                    }

                    if (targetFolderNode.FullPathToChildren.StartsWith(folder, StringComparison.OrdinalIgnoreCase) &&
                        !String.Equals(targetFolderNode.FullPathToChildren, folder, StringComparison.OrdinalIgnoreCase)) {
                        // dragging a folder into a child, that's not allowed
                        Utilities.ShowMessageBox(
                            Project.Site,
                            SR.GetString(SR.CannotMoveIntoSubfolder, CommonUtils.GetFileOrDirectoryName(folder)),
                            null,
                            OLEMSGICON.OLEMSGICON_CRITICAL,
                            OLEMSGBUTTON.OLEMSGBUTTON_OK,
                            OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
                        return null;
                    }
                }

                var targetPath = Path.Combine(targetFolderNode.FullPathToChildren, CommonUtils.GetFileOrDirectoryName(folder));
                if (File.Exists(targetPath)) {
                    Utilities.ShowMessageBox(
                       Project.Site,
                       SR.GetString(SR.CannotAddFileExists, CommonUtils.GetFileOrDirectoryName(folder)),
                       null,
                       OLEMSGICON.OLEMSGICON_CRITICAL,
                       OLEMSGBUTTON.OLEMSGBUTTON_OK,
                       OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
                    return null;
                }

                if (Directory.Exists(targetPath)) {
                    if (DropEffect == DropEffect.Move) {
                        if (targetPath == folderToAdd) {
                            CannotMoveSameLocation(folderToAdd);
                        } else {
                            Utilities.ShowMessageBox(
                               Project.Site,
                               SR.GetString(SR.CannotMoveFolderExists, CommonUtils.GetFileOrDirectoryName(folder)),
                               null,
                               OLEMSGICON.OLEMSGICON_CRITICAL,
                               OLEMSGBUTTON.OLEMSGBUTTON_OK,
                               OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
                        }
                        return null;
                    }

                    var dialog = new OverwriteFileDialog(
                        SR.GetString(SR.OverwriteFilesInExistingFolder, CommonUtils.GetFileOrDirectoryName(folder)),
                        false
                    );
                    dialog.Owner = Application.Current.MainWindow;
                    var res = dialog.ShowDialog();
                    if (res == null) {
                        // cancel, abort the whole copy
                        return null;
                    } else if (!dialog.ShouldOverwrite) {
                        // no, don't copy the folder
                        return SkipOverwriteAddition.Instance;
                    }
                    // otherwise yes, and we'll prompt about the files.
                }

                string targetFileName = CommonUtils.GetFileOrDirectoryName(folder);
                if (Utilities.IsSameComObject(Project, sourceHierarchy) &&
                    String.Equals(targetFolderNode.FullPathToChildren, folder, StringComparison.OrdinalIgnoreCase)) {
                    // copying a folder onto its self, make a copy
                    targetFileName = GetCopyName(targetFolderNode.FullPathToChildren);
                }

                List<Addition> additions = new List<Addition>();
                uint folderId;
                if (ErrorHandler.Failed(sourceHierarchy.ParseCanonicalName(folder, out folderId))) {
                    // the folder may have been deleted between the copy & paste
                    ReportMissingItem(folder);
                    return null;
                }

                if (Path.Combine(targetFolderNode.FullPathToChildren, targetFileName).Length >= NativeMethods.MAX_FOLDER_PATH) {
                    Utilities.ShowMessageBox(
                        Project.Site,
                        SR.GetString(SR.FolderPathTooLongShortMessage),
                        null,
                        OLEMSGICON.OLEMSGICON_CRITICAL,
                        OLEMSGBUTTON.OLEMSGBUTTON_OK,
                        OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
                    return null;
                }

                if (!WalkSourceProjectAndAdd(sourceHierarchy, folderId, targetFolderNode.FullPathToChildren, false, additions, targetFileName)) {
                    return null;
                }

                if (additions.Count == 1) {
                    return (FolderAddition)additions[0];
                }

                Debug.Assert(additions.Count == 0);
                return null;
            }
            /// <summary>
            /// Prompts if the file should be overwriten.  Returns false if the user cancels, true if the user answered yes/no
            /// </summary>
            /// <param name="filename"></param>
            /// <param name="dialog"></param>
            /// <returns></returns>
            private static bool PromptOverwriteFile(string filename, out OverwriteFileDialog dialog) {
                dialog = new OverwriteFileDialog(SR.GetString(SR.FileAlreadyExists, Path.GetFileName(filename)), true);
                dialog.Owner = Application.Current.MainWindow;
                bool? dialogResult = dialog.ShowDialog();

                if (dialogResult != null && !dialogResult.Value) {
                    // user cancelled
                    return false;
                }
                return true;
            }
            /// <summary>
            /// Adds an item from a project refererence to target node.
            /// </summary>
            /// <param name="projectRef"></param>
            /// <param name="targetNode"></param>
            private Addition CanAddFileFromProjectReference(string projectRef, string targetFolder, bool fromFolder = false) {
                Utilities.ArgumentNotNullOrEmpty("projectRef", projectRef);

                IVsSolution solution = Project.GetService(typeof(IVsSolution)) as IVsSolution;
                Utilities.CheckNotNull(solution);

                uint itemidLoc;
                IVsHierarchy hierarchy;
                string str;
                VSUPDATEPROJREFREASON[] reason = new VSUPDATEPROJREFREASON[1];
                if (ErrorHandler.Failed(solution.GetItemOfProjref(projectRef, out hierarchy, out itemidLoc, out str, reason))) {
                    // the file may have been deleted between the copy & paste
                    string path;
                    Guid projectGuid;
                    GetPathAndProjectId(projectRef, out projectGuid, out path);
                    ReportMissingItem(path);
                    return null;
                }

                Utilities.CheckNotNull(hierarchy);

                // This will throw invalid cast exception if the hierrachy is not a project.
                IVsProject project = (IVsProject)hierarchy;

                string moniker;
                ErrorHandler.ThrowOnFailure(project.GetMkDocument(itemidLoc, out moniker));

                if (DropEffect == DropEffect.Move && IsBadMove(targetFolder, moniker, true)) {
                    return null;
                }

                if (!File.Exists(moniker)) {
                    VsShellUtilities.ShowMessageBox(
                            Project.Site,
                            String.Format("The item '{0}' does not exist in the project directory. It may have been moved, renamed or deleted.", Path.GetFileName(moniker)),
                            null,
                            OLEMSGICON.OLEMSGICON_CRITICAL,
                            OLEMSGBUTTON.OLEMSGBUTTON_OK,
                            OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
                    return null;
                }

                string newPath = Path.Combine(targetFolder, Path.GetFileName(moniker));
                var existingChild = Project.FindNodeByFullPath(moniker);
                if (existingChild != null && existingChild.IsLinkFile) {
                    if (DropEffect == DropEffect.Move) {
                        // moving a link file, just update it's location in the hierarchy
                        return new ReparentLinkedFileAddition(Project, targetFolder, moniker);
                    } else {
                        // 
                        VsShellUtilities.ShowMessageBox(
                                Project.Site,
                                String.Format("Cannot copy linked files within the same project. You cannot have more than one link to the same file in a project."),
                                null,
                                OLEMSGICON.OLEMSGICON_CRITICAL,
                                OLEMSGBUTTON.OLEMSGBUTTON_OK,
                                OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
                        return null;
                    }
                } else if (File.Exists(newPath) && CommonUtils.IsSamePath(newPath, moniker)) {
                    newPath = GetCopyName(newPath);
                }

                bool ok = false;
                if (DropEffect == DropEffect.Move && Utilities.IsSameComObject(project, Project)) {
                    ok = Project.Tracker.CanRenameItem(moniker, newPath, VSRENAMEFILEFLAGS.VSRENAMEFILEFLAGS_NoFlags);
                } else {
                    ok = Project.Tracker.CanAddItems(
                        new[] { newPath },
                        new VSQUERYADDFILEFLAGS[] { VSQUERYADDFILEFLAGS.VSQUERYADDFILEFLAGS_NoFlags });
                }

                if (ok) {
                    if (File.Exists(newPath)) {
                        if (DropEffect == DropEffect.Move &&
                            Utilities.IsSameComObject(project, Project) &&
                            Project.FindNodeByFullPath(newPath) != null) {
                            // if we're overwriting an item, we're moving it, make sure that's ok.
                            // OverwriteFileAddition will handle the remove from the hierarchy
                            if (!Project.Tracker.CanRemoveItems(new[] { newPath }, new[] { VSQUERYREMOVEFILEFLAGS.VSQUERYREMOVEFILEFLAGS_NoFlags })) {
                                return null;
                            }
                        }
                        bool? overwrite = OverwriteAllItems;

                        if (overwrite == null) {
                            var dialog = new OverwriteFileDialog(String.Format("A file with the name '{0}' already exists.  Do you want to replace it?", Path.GetFileName(moniker)), true);
                            dialog.Owner = Application.Current.MainWindow;
                            bool? dialogResult = dialog.ShowDialog();

                            if (dialogResult != null && !dialogResult.Value) {
                                // user cancelled
                                return null;
                            }

                            overwrite = dialog.ShouldOverwrite;

                            if (dialog.AllItems) {
                                OverwriteAllItems = overwrite;
                            }
                        }

                        if (overwrite.Value) {
                            return new OverwriteFileAddition(Project, targetFolder, DropEffect, moniker, Path.GetFileName(newPath), project);
                        } else {
                            return NopAddition.Instance;
                        }
                    }

                    if (newPath.Length >= NativeMethods.MAX_PATH) {
                        VsShellUtilities.ShowMessageBox(
                            Project.Site,
                            "The filename is too long.",
                            null,
                            OLEMSGICON.OLEMSGICON_CRITICAL,
                            OLEMSGBUTTON.OLEMSGBUTTON_OK,
                            OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
                        return null;
                    }
                    return new FileAddition(Project, targetFolder, DropEffect, moniker, Path.GetFileName(newPath), project);
                }
                return null;
            }
            /// <summary>
            /// Tests to see if we can add the folder to the project.  Returns true if it's ok, false if it's not.
            /// </summary>
            /// <param name="folderToAdd">Project reference (from data object) using the format: {Guid}|project|folderPath</param>
            /// <param name="targetNode">Node to add the new folder to</param>
            private Addition CanAddFolderFromProjectReference(string folderToAdd) {
                Utilities.ArgumentNotNullOrEmpty(folderToAdd, "folderToAdd");

                var targetFolderNode = TargetNode.GetDragTargetHandlerNode();

                string folder;
                IVsHierarchy sourceHierarchy;
                GetPathAndHierarchy(folderToAdd, out folder, out sourceHierarchy);

                // Ensure we don't end up in an endless recursion
                if (Utilities.IsSameComObject(Project, sourceHierarchy)) {
                    if (String.Equals(folder, targetFolderNode.FullPathToChildren, StringComparison.OrdinalIgnoreCase)) {
                        if (DropEffect == DropEffect.Move &&
                            IsBadMove(targetFolderNode.FullPathToChildren, folder, false)) {
                            return null;
                        }
                    }

                    if (targetFolderNode.FullPathToChildren.StartsWith(folder, StringComparison.OrdinalIgnoreCase) &&
                        !String.Equals(targetFolderNode.FullPathToChildren, folder, StringComparison.OrdinalIgnoreCase)) {
                        // dragging a folder into a child, that's not allowed
                        VsShellUtilities.ShowMessageBox(
                            Project.Site,
                            String.Format("Cannot move '{0}'. The destination folder is a subfolder of the source folder.", Path.GetFileName(CommonUtils.TrimEndSeparator(folder))),
                            null,
                            OLEMSGICON.OLEMSGICON_CRITICAL,
                            OLEMSGBUTTON.OLEMSGBUTTON_OK,
                            OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
                        return null;
                    }
                }

                var targetPath = Path.Combine(targetFolderNode.FullPathToChildren, Path.GetFileName(CommonUtils.TrimEndSeparator(folder)));
                if (File.Exists(targetPath)) {
                    VsShellUtilities.ShowMessageBox(
                       Project.Site,
                       String.Format("Unable to add '{0}'. A file with that name already exists.", Path.GetFileName(CommonUtils.TrimEndSeparator(folder))),
                       null,
                       OLEMSGICON.OLEMSGICON_CRITICAL,
                       OLEMSGBUTTON.OLEMSGBUTTON_OK,
                       OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
                    return null;
                }

                if (Directory.Exists(targetPath)) {
                    if (DropEffect == DropEffect.Move) {
                        if (targetPath == folderToAdd) {
                            CannotMoveSameLocation(folderToAdd);
                        } else {
                            VsShellUtilities.ShowMessageBox(
                               Project.Site,
                               String.Format("Cannot move the folder '{0}'. A folder with that name already exists in the destination directory.", Path.GetFileName(CommonUtils.TrimEndSeparator(folder))),
                               null,
                               OLEMSGICON.OLEMSGICON_CRITICAL,
                               OLEMSGBUTTON.OLEMSGBUTTON_OK,
                               OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
                        }
                        return null;
                    }

                    var dialog = new OverwriteFileDialog(String.Format(
@"This folder already contains a folder called '{0}'

If the files in the existing folder have the same names as files in the 
folder you are copying, do you want to replace the existing files?", Path.GetFileName(CommonUtils.TrimEndSeparator(folder))), false);
                    dialog.Owner = Application.Current.MainWindow;
                    var res = dialog.ShowDialog();
                    if (res == null) {
                        // cancel, abort the whole copy
                        return null;
                    } else if (!dialog.ShouldOverwrite) {
                        // no, don't copy the folder
                        return NopAddition.Instance;
                    }
                    // otherwise yes, and we'll prompt about the files.
                }

                string targetFileName = Path.GetFileName(CommonUtils.TrimEndSeparator(folder));
                if (Utilities.IsSameComObject(Project, sourceHierarchy) &&
                    String.Equals(targetFolderNode.FullPathToChildren, folder, StringComparison.OrdinalIgnoreCase)) {
                    // copying a folder onto its self, make a copy
                    targetFileName = GetCopyName(targetFolderNode.FullPathToChildren);
                }

                List<Addition> additions = new List<Addition>();
                uint folderId;
                if (ErrorHandler.Failed(sourceHierarchy.ParseCanonicalName(folder, out folderId))) {
                    // the folder may have been deleted between the copy & paste
                    ReportMissingItem(folder);
                    return null;
                }
                
                if (Path.Combine(targetFolderNode.FullPathToChildren, targetFileName).Length >= NativeMethods.MAX_FOLDER_PATH) {
                    VsShellUtilities.ShowMessageBox(
                        Project.Site,
                        "The folder name is too long.",
                        null,
                        OLEMSGICON.OLEMSGICON_CRITICAL,
                        OLEMSGBUTTON.OLEMSGBUTTON_OK,
                        OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
                    return null;
                }

                if (!WalkSourceProjectAndAdd(sourceHierarchy, folderId, targetFolderNode.FullPathToChildren, false, additions, targetFileName)) {
                    return null;
                }

                if (additions.Count == 1) {
                    return (FolderAddition)additions[0];
                }

                Debug.Assert(additions.Count == 0);
                return null;
            }