in Common/Product/SharedProject/ProjectNode.CopyPaste.cs [1246:1381]
public override void DoAddition(ref bool? overwrite) {
string newPath = Path.Combine(TargetFolder, NewFileName);
DirectoryInfo dirInfo = null;
try {
dirInfo = Directory.CreateDirectory(TargetFolder);
} catch (ArgumentException) {
} catch (UnauthorizedAccessException) {
} catch (IOException) {
} catch (NotSupportedException) {
}
if (dirInfo == null) {
//Something went wrong and we failed to create the new directory
// Inform the user and cancel the addition
Utilities.ShowMessageBox(
Project.Site,
SR.GetString(SR.FolderCannotBeCreatedOnDisk, CommonUtils.GetFileOrDirectoryName(TargetFolder)),
null,
OLEMSGICON.OLEMSGICON_CRITICAL,
OLEMSGBUTTON.OLEMSGBUTTON_OK,
OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
return;
}
if (DropEffect == DropEffect.Move && Utilities.IsSameComObject(Project, SourceHierarchy)) {
// we are doing a move, we need to remove the old item, and add the new.
// This also allows us to have better behavior if the user is selectively answering
// no to files within the hierarchy. We can do the rename of the individual items
// which the user opts to move and not touch the ones they don't. With a cross
// hierarchy move if the user answers no to any of the items none of the items
// are removed from the source hierarchy.
var fileNode = Project.FindNodeByFullPath(SourceMoniker);
Debug.Assert(fileNode is FileNode, $"<{fileNode?.GetType().FullName ?? "null"}>");
if (fileNode != null) {
Project.ItemsDraggedOrCutOrCopied.Remove(fileNode); // we don't need to remove the file after Paste
}
if (fileNode != null && File.Exists(newPath)) {
// we checked before starting the copy, but somehow a file has snuck in. Could be a race,
// or the user could have cut and pasted 2 files from different folders into the same folder.
bool shouldOverwrite;
if (overwrite == null) {
OverwriteFileDialog dialog;
if (!PromptOverwriteFile(Path.GetFileName(newPath), out dialog)) {
// user cancelled
fileNode.ExpandItem(EXPANDFLAGS.EXPF_UnCutHighlightItem);
throw new CancelPasteException();
}
if (dialog.AllItems) {
overwrite = dialog.ShouldOverwrite;
}
shouldOverwrite = dialog.ShouldOverwrite;
} else {
shouldOverwrite = overwrite.Value;
}
if (!shouldOverwrite) {
fileNode.ExpandItem(EXPANDFLAGS.EXPF_UnCutHighlightItem);
return;
}
var existingNode = Project.FindNodeByFullPath(newPath);
if (existingNode != null) {
existingNode.Remove(true);
} else {
File.Delete(newPath);
}
}
FileNode file = fileNode as FileNode;
Debug.Assert(file != null, $"<{fileNode?.GetType().FullName ?? "null"}>");
if (file != null) {
file.RenameInStorage(fileNode.Url, newPath);
file.RenameFileNode(fileNode.Url, newPath);
}
Project.Tracker.OnItemRenamed(SourceMoniker, newPath, VSRENAMEFILEFLAGS.VSRENAMEFILEFLAGS_NoFlags);
} else {
// we are copying and adding a new file node
File.Copy(SourceMoniker, newPath, true);
// best effort to reset the ReadOnly attribute
try {
File.SetAttributes(newPath, File.GetAttributes(newPath) & ~FileAttributes.ReadOnly);
} catch (ArgumentException) {
} catch (UnauthorizedAccessException) {
} catch (IOException) {
}
var existing = Project.FindNodeByFullPath(newPath);
if (existing == null) {
var fileNode = Project.CreateFileNode(newPath);
if (String.Equals(TargetFolder, Project.FullPathToChildren, StringComparison.OrdinalIgnoreCase)) {
Project.AddChild(fileNode);
} else {
var targetFolder = Project.CreateFolderNodes(TargetFolder);
//If a race occurrs simply treat the source as a non-included item
IVsHierarchy source = SourceHierarchy as IVsHierarchy;
bool wasMemberItem = true;
if (source != null) {
uint itemId;
if (ErrorHandler.Succeeded(source.ParseCanonicalName(SourceMoniker, out itemId))) {
object nonMember;
if (ErrorHandler.Succeeded(source.GetProperty(itemId, (int)__VSHPROPID.VSHPROPID_IsNonMemberItem, out nonMember))) {
wasMemberItem = !(nonMember as bool? ?? false);
}
}
}
if (wasMemberItem && targetFolder.IsNonMemberItem) {
// dropping/pasting folder into non-member folder, non member folder
// should get included into the project.
ErrorHandler.ThrowOnFailure(targetFolder.IncludeInProjectWithRefresh(false));
}
targetFolder.AddChild(fileNode);
if (!wasMemberItem) {
// added child by default is included,
// non-member copies are not added to the project
ErrorHandler.ThrowOnFailure(fileNode.ExcludeFromProjectWithRefresh());
}
}
Project.tracker.OnItemAdded(fileNode.Url, VSADDFILEFLAGS.VSADDFILEFLAGS_NoFlags);
} else if (existing.IsNonMemberItem) {
// replacing item that already existed, just include it in the project.
existing.IncludeInProjectWithRefresh(false);
}
}
}