This class should contain all the information (extracted from a project file) needed for UI or compilation. The current structure of this class is based on the structure of a c# project file, but it may be enhanced if the necessity arise during the development of other project-readers.
        /// <summary>
        ///     This method is used to get the compiler options to be specified
        ///     in the CompilerParameters for a CodeDomProvider.
        ///     It determines the compiler options based on the settings from the csproj file.
        /// </summary>
        /// <param name="project"></param>
        /// <returns></returns>
        private string GetCompilerOptions(BasicProject project)
        {
            string compilerOptions = string.Empty;

            if (project.Settings.Optimize.ToLowerInvariant() == "true")
            {
                compilerOptions += @"/optimize ";
            }
            return(compilerOptions);
        }
 /// <summary>
 ///     This method is used to get the list of references to be specified in the
 ///     CompilerParameters for a CodeDomProvider.
 ///     It should get the fully qualified names of each reference, but a simple
 ///     name (with the .dll extension)  may be enough in most cases.
 ///     The current implementation appears to "work ok" with
 ///     very simple applications but it has two problems:
 ///     1) It returns the name of the file and not the fully qualified name.
 ///     2) It assumes the name of the file is the assembly title plus the
 ///     ".dll" extension.
 ///     A better implementation is needed.
 /// </summary>
 /// <param name="project"></param>
 /// <returns></returns>
 private string[] GetReferences(BasicProject project)
 {
     //TODO: Correct this code as the name of the file is not guaranteed to be +".dll"!
     string[] resources = new string[project.References.Count];
     for (int i = 0; i < project.References.Count; i++)
     {
         resources[i] = project.References[i] + ".dll";
     }
     return(resources);
 }
        /// <summary>
        ///     The method is used to provide the source code for the CodeDomProvider.
        ///     It reads the content of the source files and returns it.
        /// </summary>
        /// <param name="project"></param>
        /// <returns></returns>
        private string[] ReadSourceFiles(BasicProject project)
        {
            string filename;

            string[] sources = new string[project.SourceFiles.Count];
            for (int i = 0; i < project.SourceFiles.Count; i++)
            {
                filename   = Path.Combine(project.ProjectFolder, project.SourceFiles[i].Location);
                filename   = Path.Combine(filename, project.SourceFiles[i].Name);
                sources[i] = File.ReadAllText(filename);
            }
            return(sources);
        }
Example #4
0
        /// <summary>
        ///   This method compiles the poroject specified as parameter.
        ///   It can only be used for CSharp projects, but can be modified to support
        ///   some other .Net project types.
        /// </summary>
        /// <param name = "project"></param>
        public void Compile(BasicProject project)
        {
            CodeDomProvider             codeProvider;
            CompilerParameters          parameters      = new CompilerParameters();
            Dictionary <string, string> providerOptions = new Dictionary <string, string>();

            string[] sources;
            string   buildMessage;

            providerOptions.Add("CompilerVersion", project.Settings.TargetFrameworkVersion);
            //I use CSharpCodeProvider instead of
            //CodeDomProvider.CreateProvider("CSharp", providerOptions) as it is only
            //available starting with .Net 4.0
            //Also CodeDomProvider.CreateProvider("CSharp") does not allows setting the
            //compiler version
            codeProvider = new CSharpCodeProvider(providerOptions);
            parameters.GenerateExecutable    = IsExe(project);
            parameters.OutputAssembly        = GetOutputFilename(project);
            parameters.WarningLevel          = project.Settings.WarningLevel == "" ? 0 : int.Parse(project.Settings.WarningLevel);
            parameters.TreatWarningsAsErrors = false;
            parameters.GenerateInMemory      = false;
            parameters.CompilerOptions       = GetCompilerOptions(project);
            parameters.ReferencedAssemblies.AddRange(GetReferences(project));
            //parameters.EmbeddedResources.Add("[Resources.resources]");
            sources = ReadSourceFiles(project);
            CompilerResults results = codeProvider.CompileAssemblyFromSource(parameters, sources);

            if (results.Errors.Count > 0)
            {
#if (!ISWIN)
                buildMessage = string.Empty;
                foreach (CompilerError error in results.Errors)
                {
                    buildMessage = buildMessage + "Line number " + error.Line + ", Error Number: " + error.ErrorNumber + ", '" + error.ErrorText + ";" + Environment.NewLine + Environment.NewLine;
                }
#else
                buildMessage = results.Errors.Cast <CompilerError>().Aggregate(string.Empty, (current, CompErr) => current + "Line number " + CompErr.Line + ", Error Number: " + CompErr.ErrorNumber + ", '" + CompErr.ErrorText + ";" + Environment.NewLine + Environment.NewLine);
#endif
                project.BuildOutput = buildMessage;
                MessageBox.Show(buildMessage);
            }
            else
            {
                //CompileSatelliteAssemblies();
                buildMessage        = "Project built successfully!";
                project.BuildOutput = buildMessage;
            }
        }
        /// <summary>
        ///     This method compiles the poroject specified as parameter.
        ///     It can only be used for CSharp projects, but can be modified to support
        ///     some other .Net project types.
        /// </summary>
        /// <param name="project"></param>
        public void Compile(BasicProject project)
        {
            CodeDomProvider codeProvider;
            CompilerParameters parameters = new CompilerParameters();
            Dictionary<string, string> providerOptions = new Dictionary<string, string>();
            string[] sources;
            string buildMessage;
            providerOptions.Add("CompilerVersion", project.Settings.TargetFrameworkVersion);
            //I use CSharpCodeProvider instead of
            //CodeDomProvider.CreateProvider("CSharp", providerOptions) as it is only
            //available starting with .Net 4.0
            //Also CodeDomProvider.CreateProvider("CSharp") does not allows setting the
            //compiler version
            codeProvider = new CSharpCodeProvider(providerOptions);
            parameters.GenerateExecutable = IsExe(project);
            parameters.OutputAssembly = GetOutputFilename(project);
            parameters.WarningLevel = project.Settings.WarningLevel == "" ? 0 : int.Parse(project.Settings.WarningLevel);
            parameters.TreatWarningsAsErrors = false;
            parameters.GenerateInMemory = false;
            parameters.CompilerOptions = GetCompilerOptions(project);
            parameters.ReferencedAssemblies.AddRange(GetReferences(project));
            //parameters.EmbeddedResources.Add("[Resources.resources]");
            sources = ReadSourceFiles(project);
            CompilerResults results = codeProvider.CompileAssemblyFromSource(parameters, sources);
            if (results.Errors.Count > 0)
            {
                buildMessage = results.Errors.Cast<CompilerError>()
                                      .Aggregate(string.Empty,
                                                 (current, CompErr) =>
                                                 current + "Line number " + CompErr.Line + ", Error Number: " +
                                                 CompErr.ErrorNumber + ", '" + CompErr.ErrorText + ";" +
                                                 Environment.NewLine + Environment.NewLine);

                project.BuildOutput = buildMessage;
                MessageBox.Show(buildMessage);
            }
            else
            {
                //CompileSatelliteAssemblies();
                buildMessage = "Project built successfully!";
                project.BuildOutput = buildMessage;
            }
        }
 /// <summary>
 ///     This method is called to read the specified .csproj file and retrieve all
 ///     the data needed for UI or compilation.
 ///     It loads the project file as an XML and then get the value of the
 ///     relevant nodes.
 ///     Note!
 ///     It does not get every information availbale in .csproj. It only retrieves
 ///     the information considered relevant for UI and compilation.
 ///     Attention!
 ///     There may be information in .csproj that are important for the compilation
 ///     and I may be unaware of these or I may deliberately choose to ignore them.
 ///     For example, I decided not to support projects that contain references to
 ///     other projects.
 /// </summary>
 /// <param name="filename">The name (and path) of the .csproj file.</param>
 /// <returns>The data needed for UI and compilation.</returns>
 public BasicProject ReadProject(string filename)
 {
     XmlDocument doc;
     XmlNamespaceManager mgr;
     BasicProject basicProject = null;
     doc = new XmlDocument();
     doc.Load(filename);
     mgr = new XmlNamespaceManager(doc.NameTable);
     mgr.AddNamespace("x", "http://schemas.microsoft.com/developer/msbuild/2003");
     basicProject = new BasicProject
                        {
                            Settings = GetSettings(doc, mgr),
                            References = GetReferences(doc, mgr),
                            ContentFiles = GetContent(doc, mgr),
                            SourceFiles = GetSources(doc, mgr),
                            ResourceFiles = GetResources(doc, mgr),
                            ConfigFiles = GetConfigs(doc, mgr),
                            ProjectFile = filename,
                            ProjectFolder = Path.GetDirectoryName(filename)
                        };
     return basicProject;
 }
        /// <summary>
        ///     This method is called to read the specified .csproj file and retrieve all
        ///     the data needed for UI or compilation.
        ///     It loads the project file as an XML and then get the value of the
        ///     relevant nodes.
        ///     Note!
        ///     It does not get every information availbale in .csproj. It only retrieves
        ///     the information considered relevant for UI and compilation.
        ///     Attention!
        ///     There may be information in .csproj that are important for the compilation
        ///     and I may be unaware of these or I may deliberately choose to ignore them.
        ///     For example, I decided not to support projects that contain references to
        ///     other projects.
        /// </summary>
        /// <param name="filename">The name (and path) of the .csproj file.</param>
        /// <returns>The data needed for UI and compilation.</returns>
        public BasicProject ReadProject(string filename)
        {
            XmlDocument         doc;
            XmlNamespaceManager mgr;
            BasicProject        basicProject = null;

            doc = new XmlDocument();
            doc.Load(filename);
            mgr = new XmlNamespaceManager(doc.NameTable);
            mgr.AddNamespace("x", "http://schemas.microsoft.com/developer/msbuild/2003");
            basicProject = new BasicProject
            {
                Settings      = GetSettings(doc, mgr),
                References    = GetReferences(doc, mgr),
                ContentFiles  = GetContent(doc, mgr),
                SourceFiles   = GetSources(doc, mgr),
                ResourceFiles = GetResources(doc, mgr),
                ConfigFiles   = GetConfigs(doc, mgr),
                ProjectFile   = filename,
                ProjectFolder = Path.GetDirectoryName(filename)
            };
            return(basicProject);
        }
 /// <summary>
 ///     This method is used to get the compiler oprions to be specified
 ///     in the CompilerParameters for a CodeDomProvider.
 ///     It determines the compiler options based on the settings from the csproj file.
 /// </summary>
 /// <param name="project"></param>
 /// <returns></returns>
 private string GetCompilerOptions(BasicProject project)
 {
     string compilerOptions = string.Empty;
     if (project.Settings.Optimize.ToLowerInvariant() == "true")
         compilerOptions += @"/optimize ";
     return compilerOptions;
 }
 /// <summary>
 ///     The method is used to provide the source code for the CodeDomProvider.
 ///     It reads the content of the source files and returns it.
 /// </summary>
 /// <param name="project"></param>
 /// <returns></returns>
 private string[] ReadSourceFiles(BasicProject project)
 {
     string filename;
     string[] sources = new string[project.SourceFiles.Count];
     for (int i = 0; i < project.SourceFiles.Count; i++)
     {
         filename = Path.Combine(project.ProjectFolder, project.SourceFiles[i].Location);
         filename = Path.Combine(filename, project.SourceFiles[i].Name);
         sources[i] = File.ReadAllText(filename);
     }
     return sources;
 }
 /// <summary>
 ///     This method is used to get GenerateExecutable settings to be specified
 ///     in the CompilerParameters for a CodeDomProvider.
 ///     It returns true if the OutputType specified in the csproj file is winexe or exe.
 /// </summary>
 /// <param name="project"></param>
 /// <returns></returns>
 private bool IsExe(BasicProject project)
 {
     return project.Settings.OutputType.ToLowerInvariant() == "winexe"
            | project.Settings.OutputType.ToLowerInvariant() == "exe";
 }
 /// <summary>
 ///     This method is used to get the list of references to be specified in the
 ///     CompilerParameters for a CodeDomProvider.
 ///     It should get the fully qualified names of each reference, but a simple
 ///     name (with the .dll extension)  may be enough in most cases.
 ///     The current implementation appears to "work ok" with
 ///     very simple applications but it has two problems:
 ///     1) It returns the name of the file and not the fully qualified name.
 ///     2) It assumes the name of the file is the assembly title plus the
 ///     ".dll" extension.
 ///     A better implementation is needed.
 /// </summary>
 /// <param name="project"></param>
 /// <returns></returns>
 private string[] GetReferences(BasicProject project)
 {
     //TODO: Correct this code as the name of the file is not guaranted to be +".dll"!
     string[] resources = new string[project.References.Count];
     for (int i = 0; i < project.References.Count; i++)
     {
         resources[i] = project.References[i] + ".dll";
     }
     return resources;
 }
 /// <summary>
 ///     It gets the absolute path to the output folder.
 /// </summary>
 /// <param name="project"></param>
 /// <returns></returns>
 private string GetOutputPath(BasicProject project)
 {
     return Path.Combine(project.ProjectFolder, project.Settings.OutputPath);
 }
 /// <summary>
 ///     This method is used to get OutputAssembly settings to be specified
 ///     in the CompilerParameters for a CodeDomProvider.
 ///     It returns the absolute path where to place the compiled assembly.
 /// </summary>
 /// <param name="project"></param>
 /// <returns></returns>
 private string GetOutputFilename(BasicProject project)
 {
     string filename = project.Settings.AssemblyName + (IsExe(project) ? ".exe" : ".dll");
     return Path.Combine(GetOutputPath(project), filename);
 }
        /// <summary>
        ///     This method is used to get OutputAssembly settings to be specified
        ///     in the CompilerParameters for a CodeDomProvider.
        ///     It returns the absolute path where to place the compiled assembly.
        /// </summary>
        /// <param name="project"></param>
        /// <returns></returns>
        private string GetOutputFilename(BasicProject project)
        {
            string filename = project.Settings.AssemblyName + (IsExe(project) ? ".exe" : ".dll");

            return(Path.Combine(GetOutputPath(project), filename));
        }
 /// <summary>
 ///     It gets the absolute path to the output folder.
 /// </summary>
 /// <param name="project"></param>
 /// <returns></returns>
 private string GetOutputPath(BasicProject project)
 {
     return(Path.Combine(project.ProjectFolder, project.Settings.OutputPath));
 }
 /// <summary>
 ///     This method is used to get GenerateExecutable settings to be specified
 ///     in the CompilerParameters for a CodeDomProvider.
 ///     It returns true if the OutputType specified in the csproj file is winexe or exe.
 /// </summary>
 /// <param name="project"></param>
 /// <returns></returns>
 private bool IsExe(BasicProject project)
 {
     return(project.Settings.OutputType.ToLowerInvariant() == "winexe"
            | project.Settings.OutputType.ToLowerInvariant() == "exe");
 }