Example #1
0
        ProjectItem _FindItem(string path)
        {
            int  iFound = 0;
            uint itemId = 0;

            EnvDTE.ProjectItem item;
            Microsoft.VisualStudio.Shell.Interop.VSDOCUMENTPRIORITY[] pdwPriority = new Microsoft.VisualStudio.Shell.Interop.VSDOCUMENTPRIORITY[1];
            for (var i = 0; i < _projects.Length; i++)
            {
                Microsoft.VisualStudio.Shell.Interop.IVsProject vsProject = VSUtility.ToVsProject(_projects.GetValue(i) as EnvDTE.Project);
                vsProject.IsDocumentInProject(path, out iFound, pdwPriority, out itemId);
                if (iFound != 0 && itemId != 0)
                {
                    Microsoft.VisualStudio.OLE.Interop.IServiceProvider oleSp = null;
                    vsProject.GetItemContext(itemId, out oleSp);
                    if (null != oleSp)
                    {
                        ServiceProvider sp = new ServiceProvider(oleSp);
                        // convert our handle to a ProjectItem
                        item = sp.GetService(typeof(EnvDTE.ProjectItem)) as EnvDTE.ProjectItem;
                        return(item);
                    }
                }
            }
            return(null);
        }
Example #2
0
        public int Generate(string wszInputFilePath, string bstrInputFileContents,
                            string wszDefaultNamespace, IntPtr[] rgbOutputFileContents,
                            out uint pcbOutput, IVsGeneratorProgress pGenerateProgress)
        {
            string outputfile = null;
            string log        = "";

            try
            {
                if (null == _site)
                {
                    throw new InvalidOperationException("The Rolex custom tool can only be used in a design time environment. Consider using Rolex as a pre-build step instead.");
                }
                wszInputFilePath = Path.GetFullPath(wszInputFilePath);
                var item = _FindItem(wszInputFilePath);
                if (null == item)
                {
                    throw new ApplicationException("Design time environment project item fetch failed.");
                }
                foreach (EnvDTE.ProjectItem childItem in item.ProjectItems)
                {
                    childItem.Delete();
                }
                var proj = item.ContainingProject;
                var pil  = new List <object>(proj.ProjectItems.Count);
                foreach (EnvDTE.ProjectItem pi in proj.ProjectItems)
                {
                    if (pi != item)
                    {
                        pil.Add(pi);
                    }
                }
                var genShared = !VSUtility.HasClassOrStruct(pil, wszDefaultNamespace, "TableTokenizer");
                var dir       = Path.GetDirectoryName(wszInputFilePath);
                var lang      = VSUtility.GetProjectLanguageFromItem(item);
                if (null == lang)
                {
                    lang = "cs";
                }
                outputfile = Path.Combine(dir, Path.GetFileNameWithoutExtension(wszInputFilePath) + "." + lang);
                var args = new List <string>();
                args.Add(wszInputFilePath);
                args.Add("/output");
                args.Add(outputfile);
                if (0 != string.Compare("cs", lang, StringComparison.InvariantCultureIgnoreCase))
                {
                    args.Add("/language");
                    args.Add(lang);
                }
                if (!string.IsNullOrWhiteSpace(wszDefaultNamespace))
                {
                    args.Add("/namespace");
                    args.Add(wszDefaultNamespace);
                }
                if (!genShared)
                {
                    args.Add("/noshared");
                }

                var sw = new StringWriter();
                var ec = global::Rolex.Program.Run(args.ToArray(), TextReader.Null, TextWriter.Null, sw);
                log = sw.ToString();

                var isSuccess = 0 == ec;
                if (isSuccess)
                {
                    EnvDTE.ProjectItem outitm = item.ProjectItems.AddFromFile(outputfile);

                    string ext;
                    DefaultExtension(out ext);
                }
                else
                {
                    pGenerateProgress.GeneratorError(0, 0, "Rolex returned error code: " + ec.ToString(), unchecked ((uint)-1), unchecked ((uint)-1));
                }
            }
            catch (Exception ex)
            {
                pGenerateProgress.GeneratorError(0, 0, "Rolex custom tool failed with: " + ex.Message, unchecked ((uint)-1), unchecked ((uint)-1));
                log += "Rolex custom tool failed with: " + ex.Message;
            }
            finally
            {
                try
                {
                    pGenerateProgress.Progress(2, 2);
                }
                catch { }
            }
            // have used streams here in the past to scale, but even for huge items, this is faster!
            // most likely due to the lack of extra copies (memory/array resizing)
            byte[] bytes  = Encoding.UTF8.GetBytes(log);
            int    length = bytes.Length;

            rgbOutputFileContents[0] = Marshal.AllocCoTaskMem(length);
            Marshal.Copy(bytes, 0, rgbOutputFileContents[0], length);
            pcbOutput = (uint)length;
            return(VSConstants.S_OK);
        }