Example #1
0
        // 'parentItem' can be either a Project or ProjectItem
        private static async Task <EnvDTE.ProjectItem> GetOrCreateFolderAsync(
            EnvDTE.Project envDTEProject,
            object parentItem,
            string fullPath,
            string folderRelativePath,
            string folderName,
            bool createIfNotExists)
        {
            Debug.Assert(ThreadHelper.CheckAccess());

            if (parentItem == null)
            {
                return(null);
            }

            EnvDTE.ProjectItem subFolder;

            EnvDTE.ProjectItems envDTEProjectItems = GetProjectItems(parentItem);
            if (TryGetFolder(envDTEProjectItems, folderName, out subFolder))
            {
                // Get the sub folder
                return(subFolder);
            }
            if (createIfNotExists)
            {
                // The JS Metro project system has a bug whereby calling AddFolder() to an existing folder that
                // does not belong to the project will throw. To work around that, we have to manually include
                // it into our project.
                if (EnvDTEProjectInfoUtility.IsJavaScriptProject(envDTEProject) &&
                    Directory.Exists(fullPath))
                {
                    bool succeeded = await IncludeExistingFolderToProjectAsync(envDTEProject, folderRelativePath);

                    if (succeeded)
                    {
                        // IMPORTANT: after including the folder into project, we need to get
                        // a new EnvDTEProjecItems snapshot from the parent item. Otherwise, reusing
                        // the old snapshot from above won't have access to the added folder.
                        envDTEProjectItems = GetProjectItems(parentItem);
                        if (TryGetFolder(envDTEProjectItems, folderName, out subFolder))
                        {
                            // Get the sub folder
                            return(subFolder);
                        }
                    }
                    return(null);
                }

                try
                {
                    return(envDTEProjectItems.AddFromDirectory(fullPath));
                }
                catch (NotImplementedException)
                {
                    // This is the case for F#'s project system, we can't add from directory so we fall back
                    // to this impl
                    return(envDTEProjectItems.AddFolder(folderName));
                }
            }

            return(null);
        }