in Nodejs/Product/Nodejs/SharedProject/ProjectNode.CopyPaste.cs [1007:1231]
private Addition CanAddFileFromProjectReference(string projectRef, string targetFolder, bool fromFolder = false)
{
Utilities.ArgumentNotNullOrEmpty(nameof(projectRef), projectRef);
var solution = this.Project.GetService(typeof(IVsSolution)) as IVsSolution;
Utilities.CheckNotNull(solution);
var reason = new VSUPDATEPROJREFREASON[1];
if (ErrorHandler.Failed(solution.GetItemOfProjref(projectRef, out var hierarchy, out var itemidLoc, out var str, reason)))
{
GetPathAndProjectId(projectRef, out var projectGuid, out var path);
ReportMissingItem(path);
return null;
}
Utilities.CheckNotNull(hierarchy);
// This will throw invalid cast exception if the hierrachy is not a project.
var project = (IVsProject)hierarchy;
var isLink = false;
if (ErrorHandler.Succeeded(((IVsHierarchy)project).GetProperty(itemidLoc, (int)__VSHPROPID2.VSHPROPID_IsLinkFile, out var isLinkValue)))
{
if (isLinkValue is bool)
{
isLink = (bool)isLinkValue;
}
}
ErrorHandler.ThrowOnFailure(project.GetMkDocument(itemidLoc, out var moniker));
if (this.DropEffect == DropEffect.Move && IsBadMove(targetFolder, moniker, true))
{
return null;
}
if (!File.Exists(moniker))
{
Utilities.ShowMessageBox(
this.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;
}
// Check that the source and destination paths aren't the same since we can't move an item to itself.
// If they are in fact the same location, throw an error that copy/move will not work correctly.
if (this.DropEffect == DropEffect.Move && !CommonUtils.IsSamePath(Path.GetDirectoryName(moniker), Path.GetDirectoryName(targetFolder)))
{
try
{
var sourceLinkTarget = NativeMethods.GetAbsolutePathToDirectory(Path.GetDirectoryName(moniker));
string destinationLinkTarget = null;
// if the directory doesn't exist, just skip this. We will create it later.
if (Directory.Exists(targetFolder))
{
try
{
destinationLinkTarget = NativeMethods.GetAbsolutePathToDirectory(targetFolder);
}
catch (FileNotFoundException)
{
// This can occur if the user had a symlink'd directory and deleted the backing directory.
Utilities.ShowMessageBox(
this.Project.Site,
string.Format(
"Unable to find the destination folder."),
null,
OLEMSGICON.OLEMSGICON_CRITICAL,
OLEMSGBUTTON.OLEMSGBUTTON_OK,
OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
return null;
}
}
// If the paths are the same, we can't really move the file...
if (destinationLinkTarget != null && CommonUtils.IsSamePath(sourceLinkTarget, destinationLinkTarget))
{
CannotMoveSameLocation(moniker);
return null;
}
}
catch (Exception ex) when (!ExceptionExtensions.IsCriticalException(ex))
{
return null;
}
}
// Begin the move operation now that we are past pre-checks.
var existingChild = this.Project.FindNodeByFullPath(moniker);
if (isLink)
{
// links we just want to update the link node for...
if (existingChild != null)
{
if (ComUtilities.IsSameComObject(this.Project, project))
{
if (this.DropEffect != DropEffect.Move)
{
Utilities.ShowMessageBox(
this.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
{
Utilities.ShowMessageBox(
this.Project.Site,
string.Format("There is already a link to '{0}'. You cannot have more than one link to the same file in a project.", moniker),
null,
OLEMSGICON.OLEMSGICON_CRITICAL,
OLEMSGBUTTON.OLEMSGBUTTON_OK,
OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
return null;
}
}
return new ReparentLinkedFileAddition(this.Project, targetFolder, moniker);
}
var newPath = Path.Combine(targetFolder, Path.GetFileName(moniker));
if (File.Exists(newPath) &&
CommonUtils.IsSamePath(
NativeMethods.GetAbsolutePathToDirectory(newPath),
NativeMethods.GetAbsolutePathToDirectory(moniker)))
{
newPath = GetCopyName(newPath);
}
var ok = false;
if (this.DropEffect == DropEffect.Move && Utilities.IsSameComObject(project, this.Project))
{
if (existingChild != null && existingChild.ItemNode != null && existingChild.ItemNode.IsExcluded)
{
// https://nodejstools.codeplex.com/workitem/271
// The item is excluded, so we don't need to ask if we can rename it.
ok = true;
}
else
{
ok = this.Project.Tracker.CanRenameItem(moniker, newPath, VSRENAMEFILEFLAGS.VSRENAMEFILEFLAGS_NoFlags);
}
}
else
{
ok = this.Project.Tracker.CanAddItems(
new[] { newPath },
new VSQUERYADDFILEFLAGS[] { VSQUERYADDFILEFLAGS.VSQUERYADDFILEFLAGS_NoFlags });
}
if (ok)
{
if (File.Exists(newPath))
{
if (this.DropEffect == DropEffect.Move &&
Utilities.IsSameComObject(project, this.Project) &&
this.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 (!this.Project.Tracker.CanRemoveItems(new[] { newPath }, new[] { VSQUERYREMOVEFILEFLAGS.VSQUERYREMOVEFILEFLAGS_NoFlags }))
{
return null;
}
}
var overwrite = this.OverwriteAllItems;
if (overwrite == null)
{
if (!PromptOverwriteFile(moniker, out var dialog))
{
return null;
}
overwrite = dialog.ShouldOverwrite;
if (dialog.AllItems)
{
this.OverwriteAllItems = overwrite;
}
}
if (overwrite.Value)
{
return new OverwriteFileAddition(this.Project, targetFolder, this.DropEffect, moniker, Path.GetFileName(newPath), project);
}
else
{
return SkipOverwriteAddition.Instance;
}
}
else if (Directory.Exists(newPath))
{
Utilities.ShowMessageBox(
this.Project.Site,
SR.GetString(SR.DirectoryExists, CommonUtils.GetFileOrDirectoryName(newPath)),
null,
OLEMSGICON.OLEMSGICON_CRITICAL,
OLEMSGBUTTON.OLEMSGBUTTON_OK,
OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
return null;
}
if (newPath.Length >= NativeMethods.MAX_PATH)
{
Utilities.ShowMessageBox(
this.Project.Site,
SR.GetString(SR.PathTooLongShortMessage),
null,
OLEMSGICON.OLEMSGICON_CRITICAL,
OLEMSGBUTTON.OLEMSGBUTTON_OK,
OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
return null;
}
return new FileAddition(this.Project, targetFolder, this.DropEffect, moniker, Path.GetFileName(newPath), project);
}
return null;
}