예제 #1
0
        protected override byte[] GenerateCode(string inputFileContent)
        {
            List <string> newFileNames     = new List <string>();
            string        wszInputFilePath = InputFilePath;

            byte[] returnValue = null;

            int  iFound = 0;
            uint itemId = 0;

            EnvDTE.ProjectItem item;
            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(GetProject());
            // 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
                    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");
            }

            foreach (EnvDTE.ProjectItem childItem in item.ProjectItems)
            {
                if ((childItem.Name.EndsWith(GetDefaultExtension()) /*|| newFileNames.Contains(childItem.Name)*/))
                {
                    // then delete it
                    childItem.Delete();
                }
            }

            // now we can start our work, iterate across all the 'elements' in our source file
            IEnumerable <IterativeElementType> elements = GenerateElements(inputFileContent);

            if (elements != null)
            {
                int count = 0;
                if (typeof(System.Collections.ICollection).IsAssignableFrom(elements.GetEnumerator().GetType()))
                {
                    count = (elements.GetEnumerator() as System.Collections.ICollection).Count;
                }
                int    i             = 0;
                string firstFileName = null;
                foreach (IterativeElementType element in elements)
                {
                    // obtain a name for this target file
                    string fileName = GetFileName(element);

                    // generate our target file content
                    byte[] data = GenerateContent(element);

                    if (returnValue == null)
                    {
                        returnValue   = data;
                        firstFileName = fileName;
                        continue;
                    }

                    // add it to the tracking cache
                    newFileNames.Add(fileName);
                    // fully qualify the file on the filesystem
                    string strFile = Path.Combine(
                        wszInputFilePath.Substring(0, wszInputFilePath.LastIndexOf(Path.DirectorySeparatorChar)),
                        fileName);
                    // create the file
                    bool err = true;
                    try
                    {
                        using (FileStream fs = File.Create(strFile))
                        {
                            // write it out to the stream
                            fs.Write(data, 0, data.Length);
                        }

                        // add the newly generated file to the solution, as a child of the source file...
                        EnvDTE.ProjectItem itm = item.ProjectItems.AddFromFile(strFile);

                        /*
                         * 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");
                         * //// set to embedded resource
                         * itm.Properties.Item("BuildAction").Value = 3;
                         * if (String.IsNullOrEmpty((string)prop.Value) || !String.Equals((string)prop.Value, typeof(AnotherCustomTool).Name))
                         * {
                         *  prop.Value = typeof(AnotherCustomTool).Name;
                         * }
                         */
                        err = false;
                    }
                    finally
                    {
                        if (err && File.Exists(strFile))
                        {
                            File.Delete(strFile);
                        }
                    }

                    if (this.CodeGeneratorProgress != null)
                    {
                        //Report that we are 1/2 done
                        this.CodeGeneratorProgress.Progress((uint)i, (uint)count);
                    }

                    i++;
                }
            }
            //if (i == 1)
            //    _fileName = firstFileName;
            // perform some clean-up, making sure we delete any old (stale) target-files
            //foreach (EnvDTE.ProjectItem childItem in item.ProjectItems)
            //{
            //    if ((childItem.Name.EndsWith(GetDefaultExtension()) /*|| newFileNames.Contains(childItem.Name)*/))
            //        // then delete it
            //        childItem.Delete();
            //}

            return(returnValue);
        }
예제 #2
0
        public int Generate(string wszInputFilePath, string bstrInputFileContents, string wszDefaultNamespace, IntPtr[] rgbOutputFileContents, out uint pcbOutput, IVsGeneratorProgress pGenerateProgress)
        {
            Debug.Assert(rgbOutputFileContents.Length == 1);
            this._inputFileContents = bstrInputFileContents;
            this._inputFilePath     = wszInputFilePath;
            this._defaultNamespace  = wszDefaultNamespace;
            this._newFileNames.Clear();

            int  iFound = 0;
            uint itemId = 0;

            EnvDTE.ProjectItem item;
            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
                    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");
            }

            // now we can start our work, iterate across all the 'elements' in our source file
            foreach (IterativeElementType element in this)
            {
                try {
                    // obtain a name for this target file
                    string fileName = GetFileName(element);
                    // add it to the tracking cache
                    _newFileNames.Add(fileName);
                    // fully qualify the file on the filesystem
                    string strFile = Path.Combine(wszInputFilePath.Substring(0, wszInputFilePath.LastIndexOf(Path.DirectorySeparatorChar)), fileName);
                    // create the file
                    FileStream fs = File.Create(strFile);

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

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

                        fs.Close();

                        // add the newly generated file to the solution, as a child of the source file...
                        EnvDTE.ProjectItem itm = item.ProjectItems.AddFromFile(strFile);

                        /*
                         * 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");
                         * //// set to embedded resource
                         * itm.Properties.Item("BuildAction").Value = 3;
                         * if (String.IsNullOrEmpty((string)prop.Value) || !String.Equals((string)prop.Value, typeof(AnotherCustomTool).Name))
                         * {
                         *  prop.Value = typeof(AnotherCustomTool).Name;
                         * }
                         */
                    }
                    catch (Exception)
                    {
                        fs.Close();
                        if (File.Exists(strFile))
                        {
                            File.Delete(strFile);
                        }
                    }
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }

            // perform some clean-up, making sure we delete any old (stale) target-files
            foreach (EnvDTE.ProjectItem childItem in item.ProjectItems)
            {
                if (!(childItem.Name.EndsWith(GetDefaultExtension()) || _newFileNames.Contains(childItem.Name)))
                {
                    // then delete it
                    childItem.Delete();
                }
            }

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

            if (summaryData == null)
            {
                rgbOutputFileContents[0] = IntPtr.Zero;

                pcbOutput = 0;
            }
            else
            {
                // return our summary data, so that Visual Studio may write it to disk.
                rgbOutputFileContents[0] = Marshal.AllocCoTaskMem(summaryData.Length);

                Marshal.Copy(summaryData, 0, rgbOutputFileContents[0], summaryData.Length);

                pcbOutput = (uint)summaryData.Length;
            }
            return(VSConstants.S_OK);
        }