none
ProjectItem.AddFromFile only copies file , but does not add to project

    Question

  • Hi all,

    I am trying to create a VS project using C#. I am able to successfully create the same and save it to a location.

    I have a requirement that I am not able to work through. After creating the project, I have to copy from files (from a physical file location) to folder under the project. The file needs to be copied physically as well as get added to the Project also. I am able to traverse the project and find the folder. I use this code :

    Project proj = soln.Projects.Item(1);
                ProjectItems items =  proj.ProjectItems;
    
                foreach (ProjectItem projectItem in items)
                {
                    var i = projectItem.Kind.ToUpper();
                    if (i == DTEConstants.vsProjectItemKindPhysicalFolder)
                    {
                        var i1 = projectItem.Name;
    
                        if (i1 == "<<The Folder Name>>")
                        {
                            projectItem.ProjectItems.AddFromFile(@"<< File to Copy path>>");
                        }
                    }
    
    }


    The file gets copied under the project , but when  I open the project in VS the file is not included in the VS project. I need the file to be included into the project too.

    Regards,

    Girija


    Please mark responses as answered if it helped you.. This helps others... - Girija Shankar Beuria

    Monday, February 10, 2014 12:33 PM

Answers

  • Hi,

    You are not reusing the DTE object, which can be a source of problem if you get a different one.If you want to open the project from a different instance, you need to save the project first in the first instance.

    This works fine for me (using a single instance, with project unsaved):

     private void button1_Click(object sender, EventArgs e)
            {
                
                this.CreateBlankProject(System.IO.Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.Desktop),"ProjCreationFolders"), "SampleJScriptProject");
            }
    
    
            public void CreateBlankProject(string directoryPath, string projectName)
            {
    
                this.ValidateDirectoryExistsElseCreate(directoryPath);
    
                DTE2 dte;
                object obj = null;
                System.Type t = null;
    
                t = System.Type.GetTypeFromProgID("VisualStudio.DTE.12.0", true);
                obj = System.Activator.CreateInstance(t, true);
                dte = (DTE2)obj;
                Solution2 soln = (Solution2)dte.Solution;
                string templatePath;
                string prjPath = directoryPath;
    
                templatePath = soln.GetProjectTemplate("blankwj.zip", "JavaScript");
    
                soln.AddFromTemplate(templatePath, prjPath, projectName, false);
    
                this.AddDefaultFiles(soln);
    
                dte.MainWindow.Visible = true;
                dte.ExecuteCommand("Build.BuildSolution");
            }
    
            private void AddDefaultFiles(Solution2 soln)
            {
                Project proj = soln.Projects.Item(1);
                ProjectItems items = proj.ProjectItems;
    
    
                var existingProjectItemFullName = System.IO.Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "ExistingFile.js");
                System.IO.File.WriteAllText(existingProjectItemFullName, "");
    
                items.AddFromFileCopy(existingProjectItemFullName);
    
            }
    
            public void ValidateDirectoryExistsElseCreate(string path)
            {
                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }
            }



    MZ-Tools: Productivity add-ins for Visual Studio: http://www.mztools.com. My blog about developing add-ins: http://msmvps.com/blogs/carlosq/


    Friday, February 21, 2014 1:18 PM
    Moderator

All replies

  • Hi Girija,

    Thank you for posting here!

    Please pay attention to the remarks of the document about ProjectItems.AddFromFile Method.

    AddFromFile fails if the file to be added is already in the project.

    FileName need not contain a full path as long as the file can be found. How a file is found depends on the programming language. In order to use pathless files in Visual Basic and Visual C#, for example, the files must be in the same directory as the project. If they are not, they are copied over.

    Please check the file path again.

    Best regards,

    Sunny

    Tuesday, February 11, 2014 5:46 AM
    Moderator
  • Hi,

    I have not tested it, but according to the docs (hyperlinked):

    - AddFromFile doesn't copy the file, it adds it to the project

    - AddFromFileCopy copies the file and adds it to the project

    So you may want to use AddFromFileCopy in your scenario.


    MZ-Tools: Productivity add-ins for Visual Studio: http://www.mztools.com. My blog about developing add-ins: http://msmvps.com/blogs/carlosq/

    Tuesday, February 11, 2014 11:57 AM
    Moderator
  • Hi,

    Neither "AddFromFile" nor "AddFromFileCopy" works. I have tried both. The file gets copied to specific location but doesnot get added to the project.

    When I open the project I have to "Show All Files" and click on the particular file and "Add to Project". then only it gets added.

    I want the code to not only copy the file from specified location but also add to project.

    Below is my code, I am trying to create a blank JavaScript project and add some files.

    public void CreateBlankProject(string directoryPath, string projectName, string addFilePath)
            {
    
                this.ValidateDirectoryExistsElseCreate(directoryPath);
    
                DTE2 dte;
                object obj = null;
                System.Type t = null;
    
                t = System.Type.GetTypeFromProgID("VisualStudio.DTE.12.0", true);
                // Create a new instance of the IDE.
                obj = System.Activator.CreateInstance(t, true);
                // Cast the instance to DTE2 and assign to variable dte.
                dte = (DTE2)obj;
                Solution2 soln = (Solution2)dte.Solution;
                string templatePath;
                string prjPath = directoryPath;
                
                templatePath = soln.GetProjectTemplate("blankwj.zip","JavaScript");
    
                // Create a new C# console project using the template obtained 
                // above.
                soln.AddFromTemplate(templatePath, prjPath, projectName, false);
    
    	    Project proj = soln.Projects.Item(1);
                ProjectItems items = proj.ProjectItems;
    		items.AddFromFileCopy(addFilePath);
                        }

    - Girija


    Please mark responses as answered if it helped you.. This helps others... - Girija Shankar Beuria


    Wednesday, February 12, 2014 1:37 PM
  • >> I am trying to create a blank JavaScript project and add some files.

    In order to use pathless files in Visual Basic and Visual C#, for example, the files must be in the same directory as the project. If they are not, they are copied over.

    Saturday, February 15, 2014 12:06 PM
  • Hi Girija,

    Please check the path of the file you want to add. Please make sure it is a full path.

    Best regards,

    Sunny

    Saturday, February 15, 2014 12:14 PM
    Moderator
  • Hi,

    I am passing a full path such as :

    "D:\FilesToCopy\abc.js"

    BUt still it doesnot add to project.

    - Girija


    Please mark responses as answered if it helped you.. This helps others... - Girija Shankar Beuria

    Monday, February 17, 2014 6:25 AM
  • Hi,

    I am unable to reproduce your problem. This add-in works for me (it assumes a saved blank solution and it creates a Javascript project and copies an existing .js file in the "My Documents" folder to the project folder):

    using System;
    using Extensibility;
    using EnvDTE;
    using EnvDTE80;
    
    namespace MyAddin
    {
        public class Connect : IDTExtensibility2
        {
            private DTE2 _applicationObject;
            private AddIn _addInInstance;
    
            public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom)
            {
                _applicationObject = (DTE2)application;
                _addInInstance = (AddIn)addInInst;
    
                switch (connectMode)
                {
                    case ext_ConnectMode.ext_cm_AfterStartup:
    
                        // The add-in has been loaded after Visual Studio was loaded. Since Visual Studio
                        // is fully initialized, we can initialize the add-in
                        InitializeAddIn();
                        break;
    
                    case ext_ConnectMode.ext_cm_Startup:
    
                        // The add-in has been loaded with Visual Studio. Do nothing until Visual Studio 
                        // is fully initialized (the OnStartupComplete method will be called)
                        break;
    
                }
            }
    
            public void OnStartupComplete(ref Array custom)
            {
                InitializeAddIn();
            }
    
            private void InitializeAddIn()
            {
                EnvDTE80.Solution2 solution2;
                EnvDTE.Project project;
                string existingProjectItemFullName;
                string projectTemplateFileFullName;
                string projectFolderFullName;
    
                try
                {
                    solution2 = (EnvDTE80.Solution2)_applicationObject.Solution;
    
                    // Compose the full name of the project folder
                    projectFolderFullName = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(solution2.FileName), "MyProjectSubfolder\\");
    
                    // Get the project template
                    projectTemplateFileFullName = solution2.GetProjectTemplate("blankwj.zip", "JavaScript");
    
                    // Add a Javascript project
                    solution2.AddFromTemplate(projectTemplateFileFullName, projectFolderFullName, "MyJavaScriptProject", false);
    
                    // Create an existing .js file in the "My Documents" folder
                    existingProjectItemFullName = System.IO.Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "ExistingFile.js");
                    System.IO.File.WriteAllText(existingProjectItemFullName, "");
    
                    // Add the existing .js file to the project copying it (rather than linking it from its location)
                    project = _applicationObject.Solution.Projects.Item(1);
                    project.ProjectItems.AddFromFileCopy(existingProjectItemFullName);
    
                }
                catch (Exception ex)
                {
                    System.Windows.Forms.MessageBox.Show(ex.ToString());
                }
            }
    
            public void OnDisconnection(ext_DisconnectMode disconnectMode, ref Array custom)
            {
            }
    
            public void OnAddInsUpdate(ref Array custom)
            {
            }
    
            public void OnBeginShutdown(ref Array custom)
            {
            }
        }
    }


    MZ-Tools: Productivity add-ins for Visual Studio: http://www.mztools.com. My blog about developing add-ins: http://msmvps.com/blogs/carlosq/

    Wednesday, February 19, 2014 3:23 PM
    Moderator
  • HI,

    Thanks for the reply. I have the below code and it doesn't work for me. The only difference I can see between my code and yours is that I am calling  code in a Windows application project and not a VS Addin project. Below is my full code.

    When the code completes the new VS projects opens but I cannot see the "ExistingFile.js" added to my project. I have to do that manually.

    - Girija

    using EnvDTE;
    using EnvDTE80;
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.IO;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                this.CreateBlankProject(@"C:\Users\UserAdmin\Desktop\ProjCreationFolders", "SampleJScriptProject");
            }
    
    
            public void CreateBlankProject(string directoryPath, string projectName)
            {
    
                this.ValidateDirectoryExistsElseCreate(directoryPath);
    
                DTE2 dte;
                object obj = null;
                System.Type t = null;
    
                t = System.Type.GetTypeFromProgID("VisualStudio.DTE.12.0", true);
                obj = System.Activator.CreateInstance(t, true);
                dte = (DTE2)obj;
                Solution2 soln = (Solution2)dte.Solution;
                string templatePath;
                string prjPath = directoryPath;
    
                templatePath = soln.GetProjectTemplate("blankwj.zip", "JavaScript");
    
                soln.AddFromTemplate(templatePath, prjPath, projectName, false);
    
                this.AddDefaultFiles(soln);
    
    
                this.OpenProject(System.IO.Path.Combine(prjPath, projectName + ".jsproj"));
            }
    
            private void AddDefaultFiles(Solution2 soln)
            {
                Project proj = soln.Projects.Item(1);
                ProjectItems items = proj.ProjectItems;
    
    
                var existingProjectItemFullName = System.IO.Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "ExistingFile.js");
                System.IO.File.WriteAllText(existingProjectItemFullName, "");
    
                items.AddFromFileCopy(existingProjectItemFullName);
                
            }
    
            public void OpenProject(string path)
            {
                Type visualStudioType = Type.GetTypeFromProgID("VisualStudio.DTE.12.0");
                DTE2 dte = Activator.CreateInstance(visualStudioType) as DTE2;
                dte.MainWindow.Visible = true;
    
                dte.ExecuteCommand("File.OpenProject", string.Format("\"{0}\"", path));
                dte.ExecuteCommand("Build.BuildSolution");
            }
    
    
            public void ValidateDirectoryExistsElseCreate(string path)
            {
                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }
            }
        }
    }
    


    Please mark responses as answered if it helped you.. This helps others... - Girija Shankar Beuria

    Friday, February 21, 2014 7:00 AM
  • Hi,

    You are not reusing the DTE object, which can be a source of problem if you get a different one.If you want to open the project from a different instance, you need to save the project first in the first instance.

    This works fine for me (using a single instance, with project unsaved):

     private void button1_Click(object sender, EventArgs e)
            {
                
                this.CreateBlankProject(System.IO.Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.Desktop),"ProjCreationFolders"), "SampleJScriptProject");
            }
    
    
            public void CreateBlankProject(string directoryPath, string projectName)
            {
    
                this.ValidateDirectoryExistsElseCreate(directoryPath);
    
                DTE2 dte;
                object obj = null;
                System.Type t = null;
    
                t = System.Type.GetTypeFromProgID("VisualStudio.DTE.12.0", true);
                obj = System.Activator.CreateInstance(t, true);
                dte = (DTE2)obj;
                Solution2 soln = (Solution2)dte.Solution;
                string templatePath;
                string prjPath = directoryPath;
    
                templatePath = soln.GetProjectTemplate("blankwj.zip", "JavaScript");
    
                soln.AddFromTemplate(templatePath, prjPath, projectName, false);
    
                this.AddDefaultFiles(soln);
    
                dte.MainWindow.Visible = true;
                dte.ExecuteCommand("Build.BuildSolution");
            }
    
            private void AddDefaultFiles(Solution2 soln)
            {
                Project proj = soln.Projects.Item(1);
                ProjectItems items = proj.ProjectItems;
    
    
                var existingProjectItemFullName = System.IO.Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "ExistingFile.js");
                System.IO.File.WriteAllText(existingProjectItemFullName, "");
    
                items.AddFromFileCopy(existingProjectItemFullName);
    
            }
    
            public void ValidateDirectoryExistsElseCreate(string path)
            {
                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }
            }



    MZ-Tools: Productivity add-ins for Visual Studio: http://www.mztools.com. My blog about developing add-ins: http://msmvps.com/blogs/carlosq/


    Friday, February 21, 2014 1:18 PM
    Moderator