Esempio n. 1
0
        public static ProjectItem FindFileInProject(this Project project, string fileName)
        {
            int  iFound = 0;
            uint itemId = 0;

            EnvDTE.ProjectItem item = null;
            Microsoft.VisualStudio.Shell.Interop.VSDOCUMENTPRIORITY[] pdwPriority = new Microsoft.VisualStudio.Shell.Interop.VSDOCUMENTPRIORITY[1];

            // obtain a reference to the current project as an IVsProject type
            Microsoft.VisualStudio.Shell.Interop.IVsProject VsProject = VsHelper.ToVsProject(project);
            // this locates, and returns a handle to our source file, as a ProjectItem
            VsProject.IsDocumentInProject(fileName, out iFound, pdwPriority, out itemId);

            // if our source file was found in the project (which it should have been)
            if (iFound != 0 && itemId != 0)
            {
                Microsoft.VisualStudio.OLE.Interop.IServiceProvider oleSp = null;
                VsProject.GetItemContext(itemId, out oleSp);
                if (oleSp != null)
                {
                    ServiceProvider sp = new ServiceProvider(oleSp);
                    // convert our handle to a ProjectItem
                    item = sp.GetService(typeof(EnvDTE.ProjectItem)) as EnvDTE.ProjectItem;
                }
                else
                {
                    throw new ApplicationException("Unable to retrieve Visual Studio ProjectItem");
                }
            }
            else
            {
                throw new ApplicationException("Unable to retrieve Visual Studio ProjectItem");
            }
            return(item);
        }
        public void Generate(string inputFilePath, string inputFileContents, string defaultNamespace, out IntPtr outputFileContents, out int output, IVsGeneratorProgress generateProgress)
        {
            try
            {
                if (cancelGenerating)
                {
                    byte[] fileData = File.ReadAllBytes(Path.ChangeExtension(inputFilePath, GetDefaultExtension()));

                    // Return our summary data, so that Visual Studio may write it to disk.
                    outputFileContents = Marshal.AllocCoTaskMem(fileData.Length);

                    Marshal.Copy(fileData, 0, outputFileContents, fileData.Length);

                    output = fileData.Length;

                    return;
                }

                this.inputFileContents = inputFileContents;
                this.inputFilePath     = inputFilePath;
                this.defaultNamespace  = defaultNamespace;

                int         iFound = 0;
                uint        itemId = 0;
                ProjectItem projectItem;

                Microsoft.VisualStudio.Shell.Interop.VSDOCUMENTPRIORITY[] pdwPriority = new Microsoft.VisualStudio.Shell.Interop.VSDOCUMENTPRIORITY[1];

                // Obtain a reference to the current project as an IVsProject type
                Microsoft.VisualStudio.Shell.Interop.IVsProject VsProject = VsHelper.ToVsProject(project);

                // This locates, and returns a handle to our source file, as a ProjectItem
                VsProject.IsDocumentInProject(InputFilePath, out iFound, pdwPriority, out itemId);

                // If our source file was found in the project (which it should have been)
                if (iFound != 0 && itemId != 0)
                {
                    Microsoft.VisualStudio.OLE.Interop.IServiceProvider oleSp = null;

                    VsProject.GetItemContext(itemId, out oleSp);

                    if (oleSp != null)
                    {
                        ServiceProvider sp = new ServiceProvider(oleSp);

                        // Convert our handle to a ProjectItem
                        projectItem = sp.GetService(typeof(ProjectItem)) as ProjectItem;
                    }
                    else
                    {
                        throw new ApplicationException("Unable to retrieve Visual Studio ProjectItem");
                    }
                }
                else
                {
                    throw new ApplicationException("Unable to retrieve Visual Studio ProjectItem");
                }

                oldFileNames.Clear();
                newFileNames.Clear();

                foreach (ProjectItem childItem in projectItem.ProjectItems)
                {
                    oldFileNames.Add(childItem.Name);

                    if (!childItem.Name.EndsWith(".cs"))
                    {
                        childItem.Properties.Item("BuildAction").Value = 0;
                    }
                }

                // Now we can start our work, iterate across all the 'items' in our source file
                foreach (T item in this)
                {
                    // Obtain a name for this target file
                    string fileName = GetFileName(item);
                    // Add it to the tracking cache
                    newFileNames.Add(fileName);
                    // Fully qualify the file on the filesystem
                    string filePath = Path.Combine(Path.GetDirectoryName(inputFilePath), fileName);

                    if (!(item as IChangable).IsChanged && File.Exists(filePath))
                    {
                        continue;
                    }

                    try
                    {
                        bool isNewAdded = !oldFileNames.Contains(fileName);

                        if (!isNewAdded)
                        {
                            // Check out this file.
                            if (project.DTE.SourceControl.IsItemUnderSCC(filePath) &&
                                !project.DTE.SourceControl.IsItemCheckedOut(filePath))
                            {
                                project.DTE.SourceControl.CheckOutItem(filePath);
                            }
                        }

                        // Create the file
                        FileStream fs = File.Create(filePath);

                        try
                        {
                            // Generate our target file content
                            byte[] data = GenerateContent(item);

                            // Write it out to the stream
                            fs.Write(data, 0, data.Length);

                            fs.Close();

                            OnFileGenerated(filePath, isNewAdded);

                            /*
                             * Here you may wish to perform some addition logic
                             * such as, setting a custom tool for the target file if it
                             * is intented to perform its own generation process.
                             * Or, set the target file as an 'Embedded Resource' so that
                             * it is embedded into the final Assembly.
                             *
                             * EnvDTE.Property prop = itm.Properties.Item("CustomTool");
                             *
                             * if (String.IsNullOrEmpty((string)prop.Value) || !String.Equals((string)prop.Value, typeof(AnotherCustomTool).Name))
                             * {
                             *      prop.Value = typeof(AnotherCustomTool).Name;
                             * }
                             */
                        }
                        catch (Exception ex)
                        {
                            fs.Close();

                            OnError(ex);

                            LogException(ex);
                        }
                    }
                    catch (Exception ex)
                    {
                        throw ex;
                    }
                }

                // Perform some clean-up, making sure we delete any old (stale) target-files
                foreach (ProjectItem childItem in projectItem.ProjectItems)
                {
                    if (!(childItem.Name.EndsWith(GetDefaultExtension()) || newFileNames.Contains(childItem.Name)))
                    {
                        // Then delete it
                        childItem.Delete();
                    }
                }

                foreach (var newFileName in newFileNames)
                {
                    if (!oldFileNames.Contains(newFileName))
                    {
                        string fileName = Path.Combine(inputFilePath.Substring(0, inputFilePath.LastIndexOf(Path.DirectorySeparatorChar)), newFileName);

                        // Add the newly generated file to the solution, as a child of the source file...
                        ProjectItem itm = projectItem.ProjectItems.AddFromFile(fileName);

                        // Set buildaction to none
                        if (!newFileName.EndsWith(".cs"))
                        {
                            itm.Properties.Item("BuildAction").Value = 0;
                        }
                    }
                }

                // Generate our summary content for our 'single' file
                byte[] summaryData = GenerateSummaryContent();

                if (summaryData == null)
                {
                    outputFileContents = IntPtr.Zero;

                    output = 0;
                }
                else
                {
                    // Return our summary data, so that Visual Studio may write it to disk.
                    outputFileContents = Marshal.AllocCoTaskMem(summaryData.Length);

                    Marshal.Copy(summaryData, 0, outputFileContents, summaryData.Length);

                    output = summaryData.Length;
                }
            }
            catch (Exception ex)
            {
                OnError(ex);

                LogException(ex);

                outputFileContents = IntPtr.Zero;
                output             = 0;
            }
        }