示例#1
0
        /// <summary>
        /// Compiles the project and produces an output assembly
        /// </summary>
        /// <returns>
        /// Full name of the output assembly file.
        /// </returns>
        public static CompileResult Compile(CompileProject project)
        {
            string outputDirectory = string.Empty;
            if (project == null)
            {
                throw new ArgumentNullException(CompileMessages.ProjectNull);
            }

            try
            {
                //Create output directory for the compile project necessary files
                outputDirectory = CreateBuildDirectory();

                //Create necessary files for MSBuild
                CreateProjectFiles(project, outputDirectory);

                // Once all the temporary files are created, we can call MsBuild to compile.
                // NOTE: If you want to dynamic build, the Targect Framework of this project MUST be .NET Framework 4.
                // MUST NOT be the Client Profile, or you cannot reference Microsoft.Build.dll
                using (var projectPropertiesCollection = new ProjectCollection())
                {
                    var globalProperty = new Dictionary<string, string>();
                    var buildRequest = new BuildRequestData(
                        Path.Combine(outputDirectory, project.ProjectName) + ".csproj", globalProperty, null, new[] { "Build" }, null);

                    var buildResult =
                        BuildManager.DefaultBuildManager.Build(new BuildParameters(projectPropertiesCollection),
                                                               buildRequest);

                    if (buildResult == null)
                    {
                        return new CompileResult(BuildResultCode.Failure, outputDirectory, null);
                    }
                    switch (buildResult.OverallResult)
                    {
                        case BuildResultCode.Success:
                            var filePath = Path.Combine(outputDirectory, project.ProjectName) + ".dll";
                            var result = new CompileResult(buildResult.OverallResult, filePath, null);

                            try
                            {
                                File.Delete(Path.Combine(outputDirectory, PrivateKeyName));
                            }
                            catch (Exception) //Failure to delete key doesn't affect the result of the operation
                            {
                            }
                            return result;

                        default:
                            throw new CompileException(CompileMessages.ErrorCompiling, buildResult.Exception);
                    }
                }
            }
            catch (CompileException ex)
            {
                var result = new CompileResult(BuildResultCode.Failure, outputDirectory, ex);
                return result;
            }
            catch (AggregateException ex)
            {
                //More than one exception occured in one of the compile steps
                var result = new CompileResult(BuildResultCode.Failure, outputDirectory, ex);
                return result;
            }
            catch (ArgumentException ex)
            {
                var result = new CompileResult(BuildResultCode.Failure, outputDirectory, ex);
                return result;
            }
            catch (InvalidOperationException ex)
            {
                var result = new CompileResult(BuildResultCode.Failure, outputDirectory, ex);
                return result;
            }
        }
示例#2
0
        /// <summary>
        /// Attempt to warn the user if he is relying on unsigned assemblies in his workflow (an unsupported scenario).
        /// There are cases we won't catch though that the C# compiler will, involving generics like 
        /// Variable of List of List of TypeFromUnsignedAssembly
        /// </summary>
        /// <param name="project">Project for the compile operation</param>
        private static void GetReferencedAssemblies(CompileProject project)
        {
            if (project == null)
            {
                throw new ArgumentNullException(CompileMessages.ProjectNull);
            }

            //Check for conflicts, e.g. references to the same type with two different versions.
            CheckForConflictingVersions(project.ReferencedTypes, project.ReferencedAssemblies, project.ProjectName);

            // Get the references that are not signed. For some purposes like security the tool only acepts signed assemblies.
            var unsigned = (from assemblyItem in project.ReferencedAssemblies
                            where (assemblyItem.GetName().GetPublicKey().IfNotNull(key => key.Length) == 0)
                            select assemblyItem.FullName).ToList();

            if (unsigned.Any())
            {
                string message = string.Format(CompileMessages.UnsignedAssemblies, project.ProjectName,
                                               string.Join(Environment.NewLine, unsigned));

                throw new CompileException(message);
            }
        }
示例#3
0
        /// <summary>
        /// Creates all the necessary files for building an assembly based on a workflow.
        /// </summary>
        /// <param name="project">Project for the compile operation</param>
        /// <param name="path">Path of the output directory</param>
        private static void CreateProjectFiles(CompileProject project, string path)
        {
            if (null == project)
            {
                throw new ArgumentNullException(CompileMessages.ProjectNull);
            }

            if (string.IsNullOrEmpty(path))
            {
                throw new ArgumentNullException(CompileMessages.OutputDirectoryNull);
            }

            try
            {
                //Generate project files
                Parallel.Invoke(() => GenerateVisualStudioProjectFile(project, path),
                                () => GenerateAssemblyInfoFile(project.ProjectName, path, project.ProjectVersion),
                                () => GeneratePrivateKeyFile(path),
                                () => GenerateXamlFile(project.ProjectName, path, project.ProjectXaml));

            }
            catch (PathTooLongException ex)
            {
                //The file path is too long for the OS.
                throw new CompileException(CompileMessages.ProjectFileNameTooLong, ex);
            }
            catch (IOException ex)
            {
                //An I/O error occurred while opening the file.
                throw new CompileException(CompileMessages.ErrorCreatingFiles, ex);
            }
            catch (UnauthorizedAccessException ex)
            {
                //path specified a file that is read-only or this operation is not supported on the current platform or
                //path specified a directory or the caller does not have the required permission.
                throw new CompileException(CompileMessages.ErrorCreatingFiles, ex);
            }
            catch (NotSupportedException ex)
            {
                //path is in an invalid format.
                throw new CompileException(CompileMessages.ErrorCreatingFiles, ex);
            }
            catch (SecurityException ex)
            {
                //The caller does not have the required permission.
                throw new CompileException(CompileMessages.ErrorCreatingFiles, ex);
            }
            catch (AggregateException ex)
            {
                //The caller does not have the required permission.
                throw new CompileException(CompileMessages.ErrorCreatingFiles, ex);
            }
            catch (OutOfMemoryException ex)
            {
                //Not enough memory for creating files or directories
                throw new CompileException(CompileMessages.ErrorCreatingFiles, ex);
            }
        }
示例#4
0
        /// <summary>
        /// Creates a Visual Studio project file (.csproj) based on a workflow, including its dependencies,
        /// to use later in MSBuild
        /// </summary>
        /// <param name="project">Project for the compile operation</param>
        /// <param name="path">Path of the output directory</param>
        private static void GenerateVisualStudioProjectFile(CompileProject project, string path)
        {
            if (project == null)
            {
                throw new ArgumentNullException(CompileMessages.ProjectNull);
            }

            if (path == null)
            {
                throw new ArgumentNullException(CompileMessages.OutputDirectoryNull);
            }

            //We will concatenate several strings for all the content of the project, so we use StringBuilder.
            var projectFileStringBuilder = new StringBuilder();
            var referencesStringBuilder = new StringBuilder();
            const string referenceFormat = "<Reference Include=\"{0}\"><HintPath>{1}</HintPath></Reference>{2}";

            //Get referenced assemblies. We filter dynamic references because they will be resolved automatically by the compiler using reflection,
            //so there is no need to include them in the project file.
            GetReferencedAssemblies(project);

            foreach (Assembly asm in project.ReferencedAssemblies.Where(assembly => !assembly.IsDynamic))
            {
                // Build a Reference Include line for each referenced assembly
                referencesStringBuilder.Append(string.Format(referenceFormat, asm.FullName, asm.Location, Environment.NewLine));
            }

            projectFileStringBuilder.Append(Properties.Resources.WorkflowProjectTemplate);
            projectFileStringBuilder.Replace("[ASSEMBLYNAME]", project.ProjectName);
            projectFileStringBuilder.Replace("[REFERENCE]", referencesStringBuilder.ToString());
            projectFileStringBuilder.Replace("[XAMLFILE]", project.ProjectName + ".xaml");
            projectFileStringBuilder.Replace("[PRODUCTVERSION]", project.ProjectVersion);

            //Create Visual Studio Project File
            File.WriteAllText(path + @"\" + project.ProjectName + ".csproj", projectFileStringBuilder.ToString());
        }
        private static CompileProject GetCompileProject(WorkflowDesigner desinger)
        {
            MultipleAuthorService.UnassignAllTask(desinger);

            CompileProject compileProject = new CompileProject();
            HashSet<Type> referencedTypes = GetReferencedTypes(desinger);
            HashSet<Assembly> referencedAssemblies = GetReferencedAssemblies(desinger, referencedTypes);

            compileProject.ReferencedAssemblies = referencedAssemblies;
            compileProject.ReferencedTypes = referencedTypes;
            compileProject.ProjectXaml = desinger.CompilableXaml();

            return compileProject;
        }