예제 #1
0
        public WorkflowCompilerResults Compile(WorkflowCompilerParameters parameters, params string[] files)
        {
            if (parameters == null)
            {
                throw new ArgumentNullException("parameters");
            }
            if (files == null)
            {
                throw new ArgumentNullException("files");
            }

            string createdDirectoryName = null;
            string createdTempFileName  = null;

            AppDomainSetup setup = AppDomain.CurrentDomain.SetupInformation;

            setup.LoaderOptimization = LoaderOptimization.MultiDomainHost;
            AppDomain compilerDomain = AppDomain.CreateDomain("CompilerDomain", null, setup);

            bool   generateInMemory       = false;
            string originalOutputAssembly = parameters.OutputAssembly;

            try
            {
                if (parameters.GenerateInMemory)
                {
                    generateInMemory            = true;
                    parameters.GenerateInMemory = false;

                    if (string.IsNullOrEmpty(parameters.OutputAssembly))
                    {
                        // We need to remember the filename generated by Path.GetTempFileName so we can clean it up.
                        createdTempFileName       = Path.GetTempFileName();
                        parameters.OutputAssembly = createdTempFileName + ".dll";
                    }
                    else
                    {
                        int tries = 0;
                        while (true)
                        {
                            try
                            {
                                tries++;
                                createdDirectoryName = Path.GetTempPath() + "\\" + Guid.NewGuid();
                                DirectoryInfo info = Directory.CreateDirectory(createdDirectoryName);
                                parameters.OutputAssembly = info.FullName + "\\" + parameters.OutputAssembly;
                                break;
                            }
                            catch
                            {
                                // If we have tried 10 times without success, give up. Something must be wrong
                                // with what gets returned by GetTempPath or we have exceeded max_path by appending
                                // the GUID.
                                if (tries >= 10)
                                {
                                    throw;
                                }
                            }
                        }
                    }
                }

                WorkflowCompilerInternal compiler = (WorkflowCompilerInternal)compilerDomain.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName, typeof(WorkflowCompilerInternal).FullName);
                WorkflowCompilerResults  results  = compiler.Compile(parameters, files);

                if (generateInMemory && !results.Errors.HasErrors)
                {
                    results.CompiledAssembly = Assembly.Load(File.ReadAllBytes(results.PathToAssembly));
                    results.PathToAssembly   = null;
                }

                return(results);
            }
            finally
            {
                string outputAssembly = parameters.OutputAssembly;

                if (generateInMemory)
                {
                    parameters.GenerateInMemory = true;
                    parameters.OutputAssembly   = originalOutputAssembly;
                }

                AppDomain.Unload(compilerDomain);

                // The temp file must be deleted after the app domain is unloaded, or else it will
                // be "busy", causing the delete to throw an access exception.
                if (generateInMemory)
                {
                    try
                    {
                        // There will always be an outputAssemblyName to delete.
                        File.Delete(outputAssembly);

                        // If we created a temp file name with Path.GetTempFileName, we need to delete it here.
                        if (createdTempFileName != null)
                        {
                            File.Delete(createdTempFileName);
                        }

                        // If we created a directory, delete it.
                        if (createdDirectoryName != null)
                        {
                            Directory.Delete(createdDirectoryName, true);
                        }
                    }
                    catch
                    { }
                }
            }
        }
예제 #2
0
        public WorkflowCompilerResults Compile(WorkflowCompilerParameters parameters, params string[] files)
        {
            if (parameters == null)
            {
                throw new ArgumentNullException("parameters");
            }
            if (files == null)
            {
                throw new ArgumentNullException("files");
            }

            AppDomainSetup setup = AppDomain.CurrentDomain.SetupInformation;

            setup.LoaderOptimization = LoaderOptimization.MultiDomainHost;
            AppDomain compilerDomain = AppDomain.CreateDomain("CompilerDomain", null, setup);

            bool   generateInMemory       = false;
            string originalOutputAssembly = parameters.OutputAssembly;

            try
            {
                if (parameters.GenerateInMemory)
                {
                    generateInMemory            = true;
                    parameters.GenerateInMemory = false;

                    if (string.IsNullOrEmpty(parameters.OutputAssembly))
                    {
                        parameters.OutputAssembly = Path.GetTempFileName() + ".dll";
                    }
                    else
                    {
                        while (true)
                        {
                            try
                            {
                                DirectoryInfo info = Directory.CreateDirectory(Path.GetTempPath() + "\\" + Guid.NewGuid());
                                parameters.OutputAssembly = info.FullName + "\\" + parameters.OutputAssembly;
                                break;
                            }
                            catch
                            {
                            }
                        }
                    }
                }

                WorkflowCompilerInternal compiler = (WorkflowCompilerInternal)compilerDomain.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName, typeof(WorkflowCompilerInternal).FullName);
                WorkflowCompilerResults  results  = compiler.Compile(parameters, files);

                if (generateInMemory && !results.Errors.HasErrors)
                {
                    results.CompiledAssembly = Assembly.Load(File.ReadAllBytes(results.PathToAssembly));
                    results.PathToAssembly   = null;

                    // Delete the file and directory.
                    try
                    {
                        File.Delete(parameters.OutputAssembly);
                        Directory.Delete(Path.GetDirectoryName(parameters.OutputAssembly), true);
                    }
                    catch
                    { }
                }

                return(results);
            }
            finally
            {
                string outputAssembly = parameters.OutputAssembly;

                if (generateInMemory)
                {
                    parameters.GenerateInMemory = true;
                    parameters.OutputAssembly   = originalOutputAssembly;
                }

                AppDomain.Unload(compilerDomain);

                // The temp file must be deleted after the app domain is unloaded, or else it will
                // be "busy", causing the delete to throw an access exception.
                if (generateInMemory)
                {
                    try
                    {
                        File.Delete(outputAssembly);
                        Directory.Delete(Path.GetDirectoryName(outputAssembly), true);
                    }
                    catch
                    { }
                }
            }
        }