diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/Project.cs b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/Project.cs index f756463a05..4d1e4ca94e 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/Project.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/Project.cs @@ -307,5 +307,10 @@ namespace ICSharpCode.PackageManagement.EnvDTE { fileService.OpenFile(fileName); } + + internal bool IsFileFileInsideProjectFolder(string filePath) + { + return FileUtility.IsBaseDirectory(MSBuildProject.Directory, filePath); + } } } diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ProjectItems.cs b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ProjectItems.cs index 6a4347d7a0..1b39f884f5 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ProjectItems.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ProjectItems.cs @@ -34,9 +34,16 @@ namespace ICSharpCode.PackageManagement.EnvDTE public virtual void AddFromFileCopy(string filePath) { string include = GetIncludePathForFileCopy(filePath); - CopyFileIntoProject(filePath, include); - Project.AddFileProjectItemUsingPathRelativeToProject(include); - Project.Save(); + if (IsFileInsideProjectFolder(filePath)) { + ThrowExceptionIfFileDoesNotExist(filePath); + } else { + CopyFileIntoProject(filePath, include); + } + + using (IProjectBrowserUpdater updater = Project.CreateProjectBrowserUpdater()) { + Project.AddFileProjectItemUsingPathRelativeToProject(include); + Project.Save(); + } } /// @@ -53,6 +60,18 @@ namespace ICSharpCode.PackageManagement.EnvDTE return item.GetIncludePath(fileNameWithoutAnyPath); } + bool IsFileInsideProjectFolder(string filePath) + { + return Project.IsFileFileInsideProjectFolder(filePath); + } + + void ThrowExceptionIfFileDoesNotExist(string filePath) + { + if (!fileService.FileExists(filePath)) { + throw new FileNotFoundException("Cannot find file", filePath); + } + } + void ThrowExceptionIfFileExists(string filePath) { if (fileService.FileExists(filePath)) { diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/FileExistsException.cs b/src/AddIns/Misc/PackageManagement/Project/Src/FileExistsException.cs index 47d4d68c02..ccd2b26dd3 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/FileExistsException.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/FileExistsException.cs @@ -6,6 +6,7 @@ using System.IO; namespace ICSharpCode.PackageManagement { + [Serializable] public class FileExistsException : Exception { public FileExistsException(string fileName) diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/ProjectItemsTests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/ProjectItemsTests.cs index 3ab65690e4..44cd009457 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/ProjectItemsTests.cs +++ b/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/ProjectItemsTests.cs @@ -4,7 +4,9 @@ using System; using System.Collections; using System.Collections.Generic; +using System.IO; using System.Linq; + using ICSharpCode.PackageManagement; using ICSharpCode.PackageManagement.EnvDTE; using ICSharpCode.SharpDevelop.Project; @@ -886,5 +888,47 @@ namespace PackageManagement.Tests.EnvDTE Assert.AreEqual(msbuildProject, fileItem.Project); Assert.AreEqual("MainForm.cs", fileItem.DependentUpon); } + + [Test] + public void AddFromFileCopy_AddExistingFileNameInsideProjectFolder_FileIsAddedToProject() + { + CreateProjectItems(); + msbuildProject.FileName = @"d:\projects\myproject\myproject.csproj"; + string fileName = @"d:\projects\myproject\test.cs"; + fakeFileService.ExistingFileNames.Add(fileName); + + projectItems.AddFromFileCopy(fileName); + + string addedFileName = @"d:\projects\myproject\test.cs"; + FileProjectItem fileItem = msbuildProject.FindFile(addedFileName); + Assert.AreEqual("test.cs", fileItem.Include); + } + + [Test] + public void AddFromFileCopy_AddExistingFileNameInsideProjectFolder_ProjectUpdaterIsDisposed() + { + CreateProjectItems(); + IProjectBrowserUpdater projectBrowserUpdater = CreateProjectBrowserUpdater(); + msbuildProject.FileName = @"d:\projects\myproject\myproject.csproj"; + string fileName = @"d:\projects\myproject\test.cs"; + fakeFileService.ExistingFileNames.Add(fileName); + + projectItems.AddFromFileCopy(fileName); + + projectBrowserUpdater.AssertWasCalled(updater => updater.Dispose()); + } + + [Test] + public void AddFromFileCopy_AddNonExistentFileNameInsideProjectFolder_MissingFileExceptionThrown() + { + CreateProjectItems(); + msbuildProject.FileName = @"d:\projects\myproject\myproject.csproj"; + string fileName = @"d:\projects\myproject\test.cs"; + + FileNotFoundException ex = Assert.Throws(() => projectItems.AddFromFileCopy(fileName)); + + Assert.AreEqual("Cannot find file", ex.Message); + Assert.AreEqual(fileName, ex.FileName); + } } }