Exemplo n.º 1
0
        /// <summary>
        /// Called by Visual Studio when it needs to generate or 
        /// regenerate the code file from your the custom tool
        /// input file.
        /// </summary>
        /// <param name="wszInputFilePath"></param>
        /// <param name="bstrInputFileContents"></param>
        /// <param name="wszDefaultNamespace"></param>
        /// <param name="rgbOutputFileContents"></param>
        /// <param name="pcbOutput"></param>
        /// <param name="pGenerateProgress"></param>
        /// <returns></returns>
        int IVsSingleFileGenerator.Generate(string wszInputFilePath, string bstrInputFileContents, string wszDefaultNamespace, IntPtr[] rgbOutputFileContents, out uint pcbOutput, IVsGeneratorProgress pGenerateProgress)
        {
            GenerationEventArgs gea = new GenerationEventArgs(
                bstrInputFileContents,
                wszInputFilePath,
                wszDefaultNamespace,
                new ServiceProvider(Site as Microsoft.VisualStudio.OLE.Interop.IServiceProvider)
                    .GetService(typeof(ProjectItem)) as ProjectItem);

            if (OnGenerateCode != null)
            {
                OnGenerateCode(this, gea);
            }

            if (gea.OutputFileExtension.StartsWith("."))
            {
                this.FileExtension = gea.OutputFileExtension;
            }
            else
            {
                this.FileExtension = "." + gea.OutputFileExtension;
            }

            GenerationProgressFacade progressFacade =
                new GenerationProgressFacade(pGenerateProgress);

            foreach (GenerationWarning warning in gea.Warnings)
            {
                progressFacade.GenerateWarning(
                    warning.Message,
                    warning.LineNumber,
                    warning.ColumnNumber);
            }

            foreach (GenerationError error in gea.Errors)
            {
                progressFacade.GenerateError(
                    error.Message,
                    error.LineNumber,
                    error.ColumnNumber);
            }

            byte[] bytes = gea.GetOutputCodeBytes();

            int outputLength = bytes.Length;
            rgbOutputFileContents[0] = Marshal.AllocCoTaskMem(outputLength);
            Marshal.Copy(bytes, 0, rgbOutputFileContents[0], outputLength);
            pcbOutput = (uint)outputLength;

            if (gea.FailOnError && gea.Errors.Count > 0)
            {
                return VSConstants.E_FAIL;
            }
            else
            {
                return VSConstants.S_OK;
            }
        }
Exemplo n.º 2
0
 static void GenerateErrorWithPosition(string line, GenerationEventArgs e)
 {
     Match match = gccErrorFormat.Match(line);
     int row, col;
     if(match.Success && int.TryParse(match.Groups[1].Value, out row)
         && int.TryParse(match.Groups[2].Value, out col)) {
         e.GenerateError(line, row-1, col-1); // note offsets!
     } else {
         e.GenerateError(line);
     }
 }
Exemplo n.º 3
0
        public void GenerationHandler(object s, GenerationEventArgs e)
        {
            // Fail on any error
            e.FailOnError = true;
            
            string tmp = Path.GetTempFileName();
            try
            {
                string[] args = GetProtoGenArgs(e.InputFilePath, tmp, e.OutputFileExtension, e.Namespace);
                bool writeWhatWeDid = true;
                string root = GetInstallPath(null), app = GetInstallPath("protogen.exe");
                if (!File.Exists(app))
                {
                    e.GenerateError("Missing: " + app);
                    return;
                }

                int result;

                ProcessStartInfo psi = new ProcessStartInfo(app);
                psi.CreateNoWindow = true;
                psi.WorkingDirectory = root;
                StringBuilder sb = new StringBuilder();
                foreach (string arg in args)
                {
                    sb.Append("\"" + arg + "\" ");
                }
                psi.Arguments = sb.ToString();
                psi.WindowStyle = ProcessWindowStyle.Hidden;
                using (Process proc = Process.Start(psi))
                {
                    proc.WaitForExit();
                    result = proc.ExitCode;
                }

                /*AppDomain ad = AppDomain.CreateDomain("protogen", null, root, "", false);
                
                try
                {
                    result = ad.ExecuteAssembly(app, null, args);
                    writeWhatWeDid = result != 0;
                }
                finally
                {
                    AppDomain.Unload(ad);
                }*/

                if (writeWhatWeDid)
                {
#if DEBUG2
                    e.GenerateWarning(app);
                    foreach (string arg in args) e.GenerateWarning(arg);
#endif
                }

                using(var lineReader = File.OpenText(tmp))
                {
                    string line;
                    switch(result)
                    {
                        case 0:
                            while((line = lineReader.ReadLine()) != null) {
                                e.OutputCode.AppendLine(line);
                            }
                            break;
                        default:
                            bool hasErrorText = false;
                            while((line = lineReader.ReadLine()) != null) {
                                GenerateErrorWithPosition(line, e);
                                hasErrorText = true;
                            }
                            if(!hasErrorText) {
                                e.GenerateError("Code generation failed with exit-code " + result);
                            }
                            break;
                    }
                }
                #region ensure protobuf-net.dll is in the project:

                try
                {
                    VSProject project = (VSProject)e.ProjectItem.ContainingProject.Object;
                    bool hasRef = project.References.Cast<Reference>()
                        .Any(r => r != null && string.Equals(r.Name, "protobuf-net", StringComparison.InvariantCultureIgnoreCase));

                    if (!hasRef)
                    {
                        string toolPath = GetInstallPath(PBNETDLL);

                        /* REMOVED: copy dll into local project
                        string projectPath = Path.Combine(
                                Path.GetDirectoryName(e.ProjectItem.ContainingProject.FullName),
                                PBNETDLL);
                        // copy it into the project if needed
                        if(!File.Exists(projectPath))
                        {
                            File.Copy(toolPath, projectPath);
                        }
                         */
                        // add the reference (from the install location)
                        Reference dllRef = project.References.Add(toolPath);
                        dllRef.CopyLocal = true;
                    }
                }
                catch (Exception ex)
                {
                    e.GenerateWarning("Failed to add reference to protobuf-net:" + ex.Message);
                }
                #endregion
            }
            finally
            {
                try { File.Delete(tmp); }
                catch (Exception ex) { e.GenerateWarning(ex.Message); }
            }
        }
        public void GenerationHandler(object s, GenerationEventArgs e)
        {
            // Fail on any error
            e.FailOnError = true;

            string tmp = Path.GetTempFileName();

            try
            {
                string[] args = GetProtoGenArgs(e.InputFilePath, tmp, e.OutputFileExtension, e.Namespace);
                bool     writeWhatWeDid = true;
                string   root = GetInstallPath(null), app = GetInstallPath("protogen.exe");
                if (!File.Exists(app))
                {
                    e.GenerateError("Missing: " + app);
                    return;
                }

                int result;

                ProcessStartInfo psi = new ProcessStartInfo(app);
                psi.CreateNoWindow   = true;
                psi.WorkingDirectory = root;
                StringBuilder sb = new StringBuilder();
                foreach (string arg in args)
                {
                    sb.Append("\"" + arg + "\" ");
                }
                psi.Arguments   = sb.ToString();
                psi.WindowStyle = ProcessWindowStyle.Hidden;
                using (Process proc = Process.Start(psi))
                {
                    proc.WaitForExit();
                    result = proc.ExitCode;
                }

                /*AppDomain ad = AppDomain.CreateDomain("protogen", null, root, "", false);
                 *
                 * try
                 * {
                 *  result = ad.ExecuteAssembly(app, null, args);
                 *  writeWhatWeDid = result != 0;
                 * }
                 * finally
                 * {
                 *  AppDomain.Unload(ad);
                 * }*/

                if (writeWhatWeDid)
                {
#if DEBUG2
                    e.GenerateWarning(app);
                    foreach (string arg in args)
                    {
                        e.GenerateWarning(arg);
                    }
#endif
                }

                using (var lineReader = File.OpenText(tmp))
                {
                    string line;
                    switch (result)
                    {
                    case 0:
                        while ((line = lineReader.ReadLine()) != null)
                        {
                            e.OutputCode.AppendLine(line);
                        }
                        break;

                    default:
                        bool hasErrorText = false;
                        while ((line = lineReader.ReadLine()) != null)
                        {
                            GenerateErrorWithPosition(line, e);
                            hasErrorText = true;
                        }
                        if (!hasErrorText)
                        {
                            e.GenerateError("Code generation failed with exit-code " + result);
                        }
                        break;
                    }
                }
                #region ensure protobuf-net.dll is in the project:

                try
                {
                    VSProject project = (VSProject)e.ProjectItem.ContainingProject.Object;
                    bool      hasRef  = project.References.Cast <Reference>()
                                        .Any(r => r != null && string.Equals(r.Name, "protobuf-net", StringComparison.InvariantCultureIgnoreCase));

                    if (!hasRef)
                    {
                        string toolPath = GetInstallPath(PBNETDLL);

                        /* REMOVED: copy dll into local project
                         * string projectPath = Path.Combine(
                         *      Path.GetDirectoryName(e.ProjectItem.ContainingProject.FullName),
                         *      PBNETDLL);
                         * // copy it into the project if needed
                         * if(!File.Exists(projectPath))
                         * {
                         *  File.Copy(toolPath, projectPath);
                         * }
                         */
                        // add the reference (from the install location)
                        Reference dllRef = project.References.Add(toolPath);
                        dllRef.CopyLocal = true;
                    }
                }
                catch (Exception ex)
                {
                    e.GenerateWarning("Failed to add reference to protobuf-net:" + ex.Message);
                }
                #endregion
            }
            finally
            {
                try { File.Delete(tmp); }
                catch (Exception ex) { e.GenerateWarning(ex.Message); }
            }
        }