Exemple #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);
        }
Exemple #2
0
        public int Generate(string wszInputFilePath, string bstrInputFileContents,
                            string wszDefaultNamespace, IntPtr[] rgbOutputFileContents,
                            out uint pcbOutput, IVsGeneratorProgress pGenerateProgress)
        {
            string outp = "";
            string errp = "";

            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.");
                }
                if (0 != string.Compare("cs", VSUtility.GetProjectLanguageFromItem(item), StringComparison.InvariantCultureIgnoreCase))
                {
                    throw new NotSupportedException("The Rolex generator only supports C# projects");
                }
                var dir         = Path.GetDirectoryName(wszInputFilePath);
                var scannerFile = Path.GetFileNameWithoutExtension(wszInputFilePath) + ".cs";
                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, "Token");
                pGenerateProgress.Progress(0, 2);
                ProcessStartInfo psi = new ProcessStartInfo();
                psi.FileName        = "rolex";
                psi.CreateNoWindow  = true;
                psi.UseShellExecute = false;
                psi.Arguments       = "\"" + wszInputFilePath.Replace("\"", "\"\"") + "\"";
                psi.Arguments      += " /output -";//\"" + Path.Combine(dir, scannerFile).Replace("\"", "\"\"") + "\"";
                psi.Arguments      += " /namespace \"" + wszDefaultNamespace + "\"";
                if (!genShared)
                {
                    psi.Arguments += " /noshared";
                }
                psi.RedirectStandardOutput = true;
                psi.RedirectStandardError  = true;

                var isSuccess = false;
                using (var proc = new Process())
                {
                    proc.StartInfo = psi;
                    proc.Start();
                    outp = proc.StandardOutput.ReadToEnd().TrimEnd();
                    errp = proc.StandardError.ReadToEnd().TrimEnd();
                    if (!proc.HasExited)
                    {
                        proc.WaitForExit();
                    }
                    isSuccess = 0 == proc.ExitCode;
                }

                var outputPath = Path.Combine(dir, scannerFile);
                pGenerateProgress.Progress(1, 2);
                if (!isSuccess)
                {
                    _DumpErrors(errp, pGenerateProgress);
                    //pGenerateProgress.GeneratorError(0, 0, "Rolex failed: " + errp, unchecked((uint)-1), unchecked((uint)-1));
                }
                else
                {
                    // 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(outp);
                    int    length = bytes.Length;
                    rgbOutputFileContents[0] = Marshal.AllocCoTaskMem(length);
                    Marshal.Copy(bytes, 0, rgbOutputFileContents[0], length);
                    pcbOutput = (uint)length;
                    return(VSConstants.S_OK);
                }
            }
            catch (Exception ex)
            {
                pGenerateProgress.GeneratorError(0, 0, "Rolex custom tool failed with: " + ex.Message, unchecked ((uint)-1), unchecked ((uint)-1));
                errp += "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)
            pcbOutput = (uint)0;
            return(VSConstants.S_OK);
        }