XomlCompilerHelpers.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WF / Common / AuthoringOM / Compiler / XomlCompilerHelpers.cs / 1305376 / XomlCompilerHelpers.cs

                            namespace System.Workflow.ComponentModel.Compiler 
{
    #region Imports

    using System; 
    using System.Collections;
    using System.Collections.Specialized; 
    using System.Collections.Generic; 
    using System.CodeDom;
    using System.ComponentModel; 
    using System.ComponentModel.Design;
    using System.CodeDom.Compiler;
    using System.Reflection;
    using System.Xml; 
    using System.Globalization;
    using System.IO; 
    using System.Text; 
    using System.Diagnostics;
    using System.Text.RegularExpressions; 
    using Microsoft.CSharp;
    using Microsoft.VisualBasic;
    using System.Workflow.ComponentModel.Design;
    using System.Workflow.ComponentModel.Serialization; 
    using Microsoft.Win32;
    using System.ComponentModel.Design.Serialization; 
    using System.Configuration; 
    using System.Runtime.InteropServices;
    using System.Workflow.Interop; 
    using System.Diagnostics.CodeAnalysis;

    #endregion
 
    internal static class XomlCompilerHelper
    { 
        #region Data members 

        internal static object LineNumber = new object(); 
        internal static object ColumnNumber = new object();

        #endregion
 
        #region Main compilation helper
 
        internal static void InternalCompileFromDomBatch(string[] files, string[] codeFiles, WorkflowCompilerParameters parameters, WorkflowCompilerResults results, string localAssemblyPath) 
        {
            // Check all the library paths are valid. 
            foreach (string libraryPath in parameters.LibraryPaths)
            {
                if (!XomlCompilerHelper.CheckPathName(libraryPath))
                { 
                    WorkflowCompilerError libPathError =
                        new WorkflowCompilerError(string.Empty, 0, 0, ErrorNumbers.Error_LibraryPath.ToString(CultureInfo.InvariantCulture), string.Format(CultureInfo.CurrentCulture, SR.GetString(SR.LibraryPathIsInvalid), libraryPath)); 
                    libPathError.IsWarning = true; 
                    results.Errors.Add(libPathError);
                } 
            }

            IList authorizedTypes = null;
            if (parameters.CheckTypes) 
            {
                //If we dont find the list of authorized types then return. 
                authorizedTypes = WorkflowCompilationContext.Current.GetAuthorizedTypes(); 
                if (authorizedTypes == null)
                { 
                    ValidationError error = new ValidationError(SR.GetString(SR.Error_ConfigFileMissingOrInvalid), ErrorNumbers.Error_ConfigFileMissingOrInvalid);
                    results.Errors.Add(CreateXomlCompilerError(error, parameters));
                    return;
                } 
            }
 
            ITypeProvider typeProvider = WorkflowCompilationContext.Current.ServiceProvider.GetService(typeof(ITypeProvider)) as ITypeProvider; 
            ArrayList activities = new ArrayList();
 
            using (PDBReader pdbReader = new PDBReader(localAssemblyPath))
            {
                // Validate all the compiled activities in the assembly.
                foreach (Type type in typeProvider.LocalAssembly.GetTypes()) 
                {
                    if (!TypeProvider.IsAssignable(typeof(Activity), type) || type.IsAbstract) 
                        continue; 

                    // Fetch file name. 
                    string fileName = string.Empty;
                    WorkflowMarkupSourceAttribute[] sourceAttrs = (WorkflowMarkupSourceAttribute[])type.GetCustomAttributes(typeof(WorkflowMarkupSourceAttribute), false);
                    if (sourceAttrs != null && sourceAttrs.Length > 0)
                    { 
                        fileName = sourceAttrs[0].FileName;
                    } 
                    else 
                    {
                        ConstructorInfo ctorMethod = type.GetConstructor(Type.EmptyTypes); 
                        if (ctorMethod != null)
                        {
                            try
                            { 
                                uint line = 0, column = 0;
                                pdbReader.GetSourceLocationForOffset((uint)ctorMethod.MetadataToken, 0, out fileName, out line, out column); 
                            } 
                            catch
                            { 
                                // We don't want errors if the user has written their own custom
                                // activity and simply inherited the constructor
                            }
                        } 

                        // In case of VB, if the ctor is autogenerated the PDB will not have symbol 
                        // information. Use InitializeComponent method as the fallback. Bug 19085. 
                        if (String.IsNullOrEmpty(fileName))
                        { 
                            MethodInfo initializeComponent = type.GetMethod("InitializeComponent", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, Type.EmptyTypes, null);
                            if (initializeComponent != null)
                            {
                                try 
                                {
                                    uint line = 0, column = 0; 
                                    pdbReader.GetSourceLocationForOffset((uint)initializeComponent.MetadataToken, 0, out fileName, out line, out column); 

                                    if (!String.IsNullOrEmpty(fileName)) 
                                    {
                                        if (fileName.EndsWith(".designer.cs", StringComparison.OrdinalIgnoreCase))
                                            fileName = fileName.Substring(0, fileName.Length - ".designer.cs".Length) + ".cs";
                                        else if (fileName.EndsWith(".designer.vb", StringComparison.OrdinalIgnoreCase)) 
                                            fileName = fileName.Substring(0, fileName.Length - ".designer.vb".Length) + ".vb";
                                    } 
                                } 
                                catch
                                { 
                                }
                            }
                        }
                    } 

                    // Create the activity. 
                    Activity activity = null; 
                    try
                    { 
                        try
                        {
                            Activity.ActivityType = type;
                            activity = Activator.CreateInstance(type) as Activity; 
                        }
                        finally 
                        { 
                            Activity.ActivityType = null;
                        } 
                        activity.UserData[UserDataKeys.CustomActivity] = false;
                        if (activity is CompositeActivity)
                        {
                            CompositeActivity compositeActivity = activity as CompositeActivity; 
                            if (compositeActivity.CanModifyActivities)
                                results.Errors.Add(CreateXomlCompilerError(new ValidationError(SR.GetString(SR.Error_Missing_CanModifyProperties_False, activity.GetType().FullName), ErrorNumbers.Error_CustomActivityCantCreate), parameters)); 
                        } 
                        if (sourceAttrs.Length > 0)
                        { 
                            DesignerSerializationManager manager = new DesignerSerializationManager(WorkflowCompilationContext.Current.ServiceProvider);
                            Activity instance2 = null;
                            using (manager.CreateSession())
                            { 
                                WorkflowMarkupSerializationManager xomlSerializationManager = new WorkflowMarkupSerializationManager(manager);
                                xomlSerializationManager.LocalAssembly = parameters.LocalAssembly; 
                                using (XmlReader reader = XmlReader.Create((sourceAttrs[0].FileName))) 
                                    instance2 = new WorkflowMarkupSerializer().Deserialize(xomlSerializationManager, reader) as Activity;
                            } 
                            if (instance2 is CompositeActivity)
                                ActivityMarkupSerializer.ReplaceChildActivities(activity as CompositeActivity, instance2 as CompositeActivity);
                        }
                    } 
                    catch (TargetInvocationException tie)
                    { 
                        // For TypeInitializationException, the message is available at the inner Exception 
                        if (tie.InnerException is TypeInitializationException && tie.InnerException.InnerException != null)
                            results.Errors.Add(CreateXomlCompilerError(new ValidationError(SR.GetString(SR.Error_CustomActivityCantCreate, type.FullName, tie.InnerException.InnerException.ToString()), ErrorNumbers.Error_CustomActivityCantCreate), parameters)); 
                        else if (tie.InnerException.InnerException != null)
                            results.Errors.Add(CreateXomlCompilerError(new ValidationError(tie.InnerException.InnerException.ToString(), ErrorNumbers.Error_CustomActivityCantCreate), parameters));
                        else
                            results.Errors.Add(CreateXomlCompilerError(new ValidationError(SR.GetString(SR.Error_CustomActivityCantCreate, type.FullName, tie.InnerException.ToString()), ErrorNumbers.Error_CustomActivityCantCreate), parameters)); 
                        continue;
                    } 
                    catch (Exception e) 
                    {
                        results.Errors.Add(CreateXomlCompilerError(new ValidationError(SR.GetString(SR.Error_CustomActivityCantCreate, type.FullName, e.ToString()), ErrorNumbers.Error_CustomActivityCantCreate), parameters)); 
                        continue;
                    }

                    // Work around : another set of work arounds. 
                    activity.SetValue(ActivityCodeDomSerializer.MarkupFileNameProperty, fileName);
                    activity.SetValue(WorkflowMarkupSerializer.XClassProperty, type.FullName); 
 
                    // Run the validators.
                    ValidateActivity(activity, parameters, results); 
                    activities.Add(activity);
                }
            }
 
            // Add all type load errors to compiler results.
            foreach (KeyValuePair entry in typeProvider.TypeLoadErrors) 
            { 
                WorkflowCompilerError compilerError = new WorkflowCompilerError(string.Empty, 0, 0, ErrorNumbers.Error_TypeLoad.ToString(CultureInfo.InvariantCulture), entry.Value.Message);
                compilerError.IsWarning = true; 
                results.Errors.Add(compilerError);
            }
            results.CompiledUnit = WorkflowCompilerInternal.GenerateCodeFromFileBatch(files, parameters, results);
 
            WorkflowCompilationContext context = WorkflowCompilationContext.Current;
            if (context == null) 
            { 
                throw new Exception(SR.GetString(SR.Error_MissingCompilationContext));
            } 
            // Fix standard namespaces and root namespace.
            WorkflowMarkupSerializationHelpers.ReapplyRootNamespace(results.CompiledUnit.Namespaces, context.RootNamespace, CompilerHelpers.GetSupportedLanguage(context.Language));
            WorkflowMarkupSerializationHelpers.FixStandardNamespacesAndRootNamespace(results.CompiledUnit.Namespaces, context.RootNamespace, CompilerHelpers.GetSupportedLanguage(context.Language));
            if (!results.Errors.HasErrors) 
            {
                // ask activities to generate code for themselves 
                CodeGenerationManager codeGenerationManager = new CodeGenerationManager(WorkflowCompilationContext.Current.ServiceProvider); 
                codeGenerationManager.Context.Push(results.CompiledUnit.Namespaces);
                foreach (Activity activity in activities) 
                {
                    // Need to call code generators associated with the root activity.
                    if (activity.Parent == null)
                    { 
                        foreach (System.Workflow.ComponentModel.Compiler.ActivityCodeGenerator codeGenerator in codeGenerationManager.GetCodeGenerators(activity.GetType()))
                            codeGenerator.GenerateCode(codeGenerationManager, activity); 
                    } 
                }
 
                // If only ccu needed then return.
                if (!parameters.GenerateCodeCompileUnitOnly || parameters.CheckTypes)
                {
                    // Convert all compile units to source files. 
                    SupportedLanguages language = CompilerHelpers.GetSupportedLanguage(parameters.LanguageToUse);
                    CodeDomProvider codeDomProvider = CompilerHelpers.GetCodeDomProvider(language, parameters.CompilerVersion); 
                    ArrayList ccus = new ArrayList((ICollection)parameters.UserCodeCompileUnits); 
                    ccus.Add(results.CompiledUnit);
 
                    ArrayList sourceFilePaths = new ArrayList();
                    sourceFilePaths.AddRange(codeFiles);
                    sourceFilePaths.AddRange(XomlCompilerHelper.GenerateFiles(codeDomProvider, parameters, (CodeCompileUnit[])ccus.ToArray(typeof(CodeCompileUnit))));
 
                    // Finally give it to Code Compiler.
                    CompilerResults results2 = codeDomProvider.CompileAssemblyFromFile(parameters, (string[])sourceFilePaths.ToArray(typeof(string))); 
                    results.AddCompilerErrorsFromCompilerResults(results2); 
                    results.PathToAssembly = results2.PathToAssembly;
                    results.NativeCompilerReturnValue = results2.NativeCompilerReturnValue; 

                    if (!results.Errors.HasErrors && parameters.CheckTypes)
                    {
                        foreach (string referenceType in MetaDataReader.GetTypeRefNames(results2.CompiledAssembly.Location)) 
                        {
                            bool authorized = false; 
                            foreach (AuthorizedType authorizedType in authorizedTypes) 
                            {
                                if (authorizedType.RegularExpression.IsMatch(referenceType)) 
                                {
                                    authorized = (String.Compare(bool.TrueString, authorizedType.Authorized, StringComparison.OrdinalIgnoreCase) == 0);
                                    if (!authorized)
                                        break; 
                                }
                            } 
                            if (!authorized) 
                            {
                                ValidationError error = new ValidationError(SR.GetString(SR.Error_TypeNotAuthorized, referenceType), ErrorNumbers.Error_TypeNotAuthorized); 
                                results.Errors.Add(CreateXomlCompilerError(error, parameters));
                            }
                        }
                    } 
                    //this line was throwing for the delay sign case. besides, copying PathToAssembly should do the same...
                    if (!results.Errors.HasErrors && !parameters.GenerateCodeCompileUnitOnly && parameters.GenerateInMemory && 
                        (string.IsNullOrEmpty(parameters.CompilerOptions) || !parameters.CompilerOptions.ToLower(CultureInfo.InvariantCulture).Contains("/delaysign"))) 
                        results.CompiledAssembly = results2.CompiledAssembly;
                } 
            }
        }
        #endregion
 
        #region Service Helpers
 
        internal static string ProcessCompilerOptions(string options, out bool noCode, out bool checkTypes) 
        {
            if (string.IsNullOrEmpty(options)) 
            {
                noCode = false;
                checkTypes = false;
            } 
            else
            { 
                string compilerSwitchValue; 

                noCode = ExtractCompilerOptionSwitch(ref options, WorkflowCompilerParameters.NoCodeSwitch, out compilerSwitchValue); 
                checkTypes = ExtractCompilerOptionSwitch(ref options, WorkflowCompilerParameters.CheckTypesSwitch, out compilerSwitchValue);
            }

            return options; 
        }
 
        static bool ExtractCompilerOptionSwitch(ref string options, string compilerSwitch, out string compilerSwitchValue) 
        {
            int switchPos = options.IndexOf(compilerSwitch, StringComparison.OrdinalIgnoreCase); 
            if (switchPos != -1)
            {
                int switchValueStart = switchPos + compilerSwitch.Length;
                int switchValueLength = 0; 
                while ((switchValueStart + switchValueLength < options.Length) && !char.IsWhiteSpace(options[switchValueStart + switchValueLength]))
                { 
                    switchValueLength++; 
                }
                if (switchValueLength > 0) 
                {
                    compilerSwitchValue = options.Substring(switchValueStart, switchValueLength);
                }
                else 
                {
                    compilerSwitchValue = string.Empty; 
                } 
                RemoveCompilerOptionSwitch(ref options, switchPos, compilerSwitch.Length + switchValueLength);
                return true; 
            }
            else
            {
                compilerSwitchValue = string.Empty; 
                return false;
            } 
        } 
        static void RemoveCompilerOptionSwitch(ref string options, int startPos, int length)
        { 
            if ((startPos > 0) && char.IsWhiteSpace(options[startPos - 1]))
            {
                options = options.Remove(startPos - 1, length + 1);
            } 
            else if ((startPos == 0) && (startPos + length + 1 < options.Length) && char.IsWhiteSpace(options[startPos + length + 1]))
            { 
                options = options.Remove(startPos, length + 1); 
            }
            else 
            {
                options = options.Remove(startPos, length);
            }
        } 

        internal static CompilerParameters CloneCompilerParameters(WorkflowCompilerParameters sourceParams) 
        { 
            bool noCode;
            bool checkTypes; 

            CompilerParameters clonedParams = new CompilerParameters();
            clonedParams.CompilerOptions =
                ProcessCompilerOptions(sourceParams.CompilerOptions, out noCode, out checkTypes); 

            foreach (string embeddedResource in sourceParams.EmbeddedResources) 
                clonedParams.EmbeddedResources.Add(embeddedResource); 

            clonedParams.GenerateExecutable = sourceParams.GenerateExecutable; 
            clonedParams.GenerateInMemory = sourceParams.GenerateInMemory;
            clonedParams.IncludeDebugInformation = sourceParams.IncludeDebugInformation;
            foreach (string linkedResource in sourceParams.LinkedResources)
                clonedParams.LinkedResources.Add(linkedResource); 

            clonedParams.MainClass = sourceParams.MainClass; 
            clonedParams.OutputAssembly = sourceParams.OutputAssembly; 
            foreach (string referencedAssembly in sourceParams.ReferencedAssemblies)
                clonedParams.ReferencedAssemblies.Add(referencedAssembly); 

            clonedParams.TreatWarningsAsErrors = sourceParams.TreatWarningsAsErrors;
            clonedParams.UserToken = sourceParams.UserToken;
            clonedParams.WarningLevel = sourceParams.WarningLevel; 
            clonedParams.Win32Resource = sourceParams.Win32Resource;
            return clonedParams; 
        } 

        #endregion 

        #region References helpers

        internal static void FixReferencedAssemblies(WorkflowCompilerParameters parameters, WorkflowCompilerResults results, StringCollection libraryPaths) 
        {
            Debug.Assert(parameters.MultiTargetingInformation == null, "Shouldn't come here if opted to MT support"); 
 
            // First add all WinOE assemblies
            foreach (string assemblyPath in XomlCompilerHelper.StandardAssemblies) 
            {
                bool shouldAdd = true;
                //first check if also user referenced this standard WinOE assemblies
                foreach (string userAssembly in parameters.ReferencedAssemblies) 
                {
                    if (null != userAssembly && userAssembly.Length > 0) 
                    { 
                        string userAssemblyFileName = Path.GetFileName(userAssembly);
                        string standardAssemblyFileName = Path.GetFileName(assemblyPath); 
                        if (null != userAssemblyFileName && null != standardAssemblyFileName && 0 == string.Compare(userAssemblyFileName, standardAssemblyFileName, StringComparison.OrdinalIgnoreCase))
                        {
                            //we will use the user-provided assembly path instead of the standard one
                            shouldAdd = false; 
                            break;
                        } 
                    } 
                }
                if (shouldAdd) 
                    parameters.ReferencedAssemblies.Add(assemblyPath);
            }

            // Resolve all the references. 
            StringCollection resolvedAssemblyReferences = ResolveAssemblyReferences(parameters.ReferencedAssemblies,
                GetCompleteLibraryPaths(libraryPaths), results); 
            parameters.ReferencedAssemblies.Clear(); 
            foreach (string resolvedAssemblyReference in resolvedAssemblyReferences)
            { 
                if (!parameters.ReferencedAssemblies.Contains(resolvedAssemblyReference))
                    parameters.ReferencedAssemblies.Add(resolvedAssemblyReference);
            }
        } 

        private static StringCollection standardAssemblies = null; 
        private static StringCollection StandardAssemblies 
        {
            get 
            {
                if (standardAssemblies == null)
                {
                    StringCollection specialAssemblies = new StringCollection(); 
                    specialAssemblies.Add("System.Workflow.ComponentModel.dll");
                    specialAssemblies.Add("System.Workflow.Runtime.dll"); 
                    specialAssemblies.Add("System.Workflow.Activities.dll"); 
                    specialAssemblies.Add("System.dll");
                    specialAssemblies.Add("System.Transactions.dll"); 
                    specialAssemblies.Add("System.drawing.dll");
                    specialAssemblies.Add("System.Web.dll");
                    specialAssemblies.Add("System.Web.Services.dll");
                    standardAssemblies = specialAssemblies; 
                }
                return standardAssemblies; 
            } 
        }
 
        private static char[] trimCharsArray = null;
        internal static string TrimDirectorySeparatorChar(string dir)
        {
            if (trimCharsArray == null) 
            {
                trimCharsArray = new char[] { Path.DirectorySeparatorChar }; 
            } 
            return dir.TrimEnd(trimCharsArray);
        } 

        private static StringCollection GetCompleteLibraryPaths(StringCollection userLibraryPaths)
        {
            StringCollection libraryPaths = new StringCollection(); 

            // Add the current directory. 
            libraryPaths.Add(Environment.CurrentDirectory); 

            // Add the CLR system directory, for example: "C:\WINDOWS\Microsoft.NET\Framework\v1.2.30703" 
            libraryPaths.Add(TrimDirectorySeparatorChar(System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory()));

            // Add /lib paths.
            string[] stringArray = new String[userLibraryPaths.Count]; 
            userLibraryPaths.CopyTo(stringArray, 0);
            libraryPaths.AddRange(stringArray); 
 
            // Add the LIB environment variable paths.
            string libLibraryPaths = Environment.GetEnvironmentVariable("LIB"); 
            if ((libLibraryPaths != null) && (libLibraryPaths.Length > 0))
            {
                string[] libLibraryPathsArray = Environment.GetEnvironmentVariable("LIB").Split(new char[] { ',', ';' });
                libraryPaths.AddRange(libLibraryPathsArray); 
            }
 
            return libraryPaths; 
        }
 
        private static StringCollection ResolveAssemblyReferences(StringCollection originalReferences, StringCollection libraryPaths, WorkflowCompilerResults results)
        {
            StringCollection resolvedReferences = new StringCollection();
 
            // Resolve listed references.
            foreach (string reference in originalReferences) 
            { 
                string fullReferenceName;
                if (CheckFileNameUsingPaths(reference, libraryPaths, out fullReferenceName)) 
                    resolvedReferences.Add(fullReferenceName);
                else
                {
                    WorkflowCompilerError compilerError = new WorkflowCompilerError(string.Empty, 0, 0, ErrorNumbers.Error_InvalidReferencedAssembly.ToString(CultureInfo.InvariantCulture), SR.GetString(SR.Error_ReferencedAssemblyIsInvalid, reference)); 
                    results.Errors.Add(compilerError);
                } 
            } 

            return resolvedReferences; 
        }

        private static void ResolveReferencedAssemblies(CompilerParameters parameters, CodeCompileUnit cu)
        { 
            if (cu.ReferencedAssemblies.Count > 0)
                foreach (string assemblyName in cu.ReferencedAssemblies) 
                    if (!parameters.ReferencedAssemblies.Contains(assemblyName)) 
                        parameters.ReferencedAssemblies.Add(assemblyName);
        } 

        private static bool CheckFileNameUsingPaths(string fileName, StringCollection paths, out string fullFileName)
        {
            fullFileName = null; 

            string realFileName = fileName.Trim(new char[] { '"' }); 
            FileInfo info = new FileInfo(realFileName); 

            // If some path is specified, it should resolve to the file. 
            if (realFileName.Length != info.Name.Length)
            {
                if (info.Exists)
                    fullFileName = info.FullName; 

                return info.Exists; 
            } 
            else
            { 
                // Just a file name is specified, look under all directories in paths.
                foreach (string path in paths)
                {
                    string trialFileName = path + Path.DirectorySeparatorChar + realFileName; 
                    FileInfo trialInfo = new FileInfo(trialFileName);
                    if (trialInfo.Exists) 
                    { 
                        fullFileName = trialFileName;
                        return true; 
                    }
                }
            }
 
            return false;
        } 
 
        internal static bool CheckPathName(string pathName)
        { 
            string fullPathName = pathName.Trim(new char[] { '"' });
            fullPathName = fullPathName.TrimEnd(new char[] { Path.DirectorySeparatorChar });
            return Directory.Exists(fullPathName);
        } 

        #endregion 
 
        #region Error helpers
 
        internal static WorkflowCompilerError CreateXomlCompilerError(ValidationError error, WorkflowCompilerParameters parameters)
        {
            WorkflowCompilerError compilerError;
            compilerError = new WorkflowCompilerError(GetFileName(error), (int)GetValue(error, XomlCompilerHelper.LineNumber), (int)GetValue(error, XomlCompilerHelper.ColumnNumber), string.Empty, GetPrettifiedErrorText(error)); 

            if (!parameters.TreatWarningsAsErrors) 
                compilerError.IsWarning = error.IsWarning; 

            compilerError.ErrorNumber = "WF" + error.ErrorNumber.ToString(CultureInfo.InvariantCulture); 

            if (error.UserData != null)
            {
                foreach (DictionaryEntry entry in error.UserData) 
                {
                    if (entry.Key == (object)typeof(Activity) && entry.Value is Activity) 
                        compilerError.UserData[entry.Key] = ((Activity)entry.Value).QualifiedName; 
                    else
                        compilerError.UserData[entry.Key] = entry.Value; 
                }
            }
            return compilerError;
        } 

        internal static ValidationErrorCollection MorphIntoFriendlyValidationErrors(IEnumerable errors) 
        { 
            ValidationErrorCollection friendlyErrors = new ValidationErrorCollection();
 
            foreach (ValidationError error in errors)
            {
                if (error == null)
                    continue; 

                if (error.GetType() == typeof(ValidationError)) 
                { 
                    ValidationError error2 = new ValidationError(GetPrettifiedErrorText(error), error.ErrorNumber, error.IsWarning);
                    friendlyErrors.Add(error2); 
                }
                else
                {
                    friendlyErrors.Add(error); 
                }
            } 
 
            return friendlyErrors;
        } 

        private static string GetFileName(ValidationError error)
        {
            Activity activity = error.UserData[typeof(Activity)] as Activity; 
            while (activity != null && activity.Parent != null)
                activity = activity.Parent; 
 
            string fileName = string.Empty;
            if (activity != null) 
                fileName = activity.GetValue(ActivityCodeDomSerializer.MarkupFileNameProperty) as string;

            if (fileName == null)
                fileName = string.Empty; 

            return fileName; 
        } 

        private static string GetPrettifiedErrorText(ValidationError error) 
        {
            string errorText = error.ErrorText;
            Activity activity = error.UserData[typeof(Activity)] as Activity;
            if (activity != null) 
            {
                // get the ID 
                string identifier = (Helpers.GetRootActivity(activity) != activity) ? activity.QualifiedName : activity.GetType().Name; 

                if ((identifier == null) || (identifier.Length == 0)) 
                    identifier = SR.GetString(SR.EmptyValue);

                // prettify error text
                if (error.IsWarning) 
                    errorText = SR.GetString(SR.Warning_ActivityValidation, identifier) + " " + errorText;
                else 
                    errorText = SR.GetString(SR.Error_ActivityValidation, identifier) + " " + errorText; 
            }
            return errorText; 
        }

        private static uint GetValue(ValidationError error, object key)
        { 
            Activity activity = error.UserData[typeof(Activity)] as Activity;
            while (activity != null && activity.Parent != null) 
                activity = activity.Parent; 

            uint value = 0; 
            if (activity != null && activity.UserData[key] != null)
                value = (uint)activity.UserData[key];

            return value; 
        }
 
        internal static bool HasCodeWithin(Activity rootActivity) 
        {
            bool hasCodeWithin = false; 
            Walker documentWalker = new Walker();
            documentWalker.FoundActivity += delegate(Walker walker, WalkerEventArgs e)
            {
                Activity currentActivity = e.CurrentActivity; 
                if (!currentActivity.Enabled)
                { 
                    e.Action = WalkerAction.Skip; 
                    return;
                } 
                CodeTypeMemberCollection codeCollection = currentActivity.GetValue(WorkflowMarkupSerializer.XCodeProperty) as CodeTypeMemberCollection;
                if (codeCollection != null && codeCollection.Count != 0)
                {
                    hasCodeWithin = true; 
                    e.Action = WalkerAction.Abort;
                    return; 
                } 
            };
            documentWalker.Walk(rootActivity as Activity); 
            return hasCodeWithin;
        }

        internal static void ValidateActivity(Activity activity, WorkflowCompilerParameters parameters, WorkflowCompilerResults results) 
        {
            ValidationErrorCollection errors = null; 
            ValidationManager validationManager = new ValidationManager(WorkflowCompilationContext.Current.ServiceProvider); 

            foreach (Validator validator in validationManager.GetValidators(activity.GetType())) 
            {
                // Validate recursively.
                try
                { 
                    errors = validator.Validate(validationManager, activity);
                    foreach (ValidationError error in errors) 
                    { 
                        if (!error.UserData.Contains(typeof(Activity)))
                            error.UserData[typeof(Activity)] = activity; 
                        results.Errors.Add(CreateXomlCompilerError(error, parameters));
                    }
                }
                catch (TargetInvocationException tie) 
                {
                    Exception e = tie.InnerException ?? tie; 
                    ValidationError error = new ValidationError(SR.GetString(SR.Error_ValidatorThrewException, e.GetType().FullName, validator.GetType().FullName, activity.Name, e.ToString()), ErrorNumbers.Error_ValidatorThrewException); 
                    results.Errors.Add(CreateXomlCompilerError(error, parameters));
                } 
                catch (Exception e)
                {
                    ValidationError error = new ValidationError(SR.GetString(SR.Error_ValidatorThrewException, e.GetType().FullName, validator.GetType().FullName, activity.Name, e.ToString()), ErrorNumbers.Error_ValidatorThrewException);
                    results.Errors.Add(CreateXomlCompilerError(error, parameters)); 
                }
            } 
        } 

        #endregion 

        #region Code generation Helpers

        internal static string[] GenerateFiles(CodeDomProvider codeDomProvider, CompilerParameters parameters, CodeCompileUnit[] ccus) 
        {
            CodeGeneratorOptions options = new CodeGeneratorOptions(); 
            options.BracingStyle = "C"; 
            string[] filenames = new string[ccus.Length];
            for (int i = 0; i < ccus.Length; i++) 
            {
                ResolveReferencedAssemblies(parameters, ccus[i]);
                filenames[i] = parameters.TempFiles.AddExtension(i + codeDomProvider.FileExtension);
                Stream temp = new FileStream(filenames[i], FileMode.Create, FileAccess.Write, FileShare.Read); 
                try
                { 
                    using (StreamWriter sw = new StreamWriter(temp, Encoding.UTF8)) 
                    {
                        codeDomProvider.GenerateCodeFromCompileUnit(ccus[i], sw, options); 
                        sw.Flush();
                    }
                }
                finally 
                {
                    temp.Close(); 
                } 
            }
            return filenames; 
        }

        #endregion
    } 

    #region Class MetaDataReader 
 
    // The GUIDs, enums, structs and interface definitions in this class are from
    // cor.h and corhdr.h in the SDK\v2.0\include folder of the .net Framework SDK. 
    internal static class MetaDataReader
    {
        private static class Guids
        { 
            public const string CLSID_MetaDataDispenser = "E5CB7A31-7512-11d2-89CE-0080C792E5D8";
            public const string IID_IMetaDataDispenser = "809C652E-7396-11d2-9771-00A0C9B4D50C"; 
            public const string IID_IMetaDataImport = "7DAC8207-D3AE-4c75-9B67-92801A497D44"; 
            public const string IID_IMetaDataAssemblyImport = "EE62470B-E94B-424e-9B7C-2F00C9249F93";
        } 

        enum MetadataTokenType
        {
            ModuleRef = 0x1a000000, 
            AssemblyRef = 0x23000000
        } 
 
        [StructLayout(LayoutKind.Sequential)]
        struct OsInfo 
        {
            uint osPlatformId;
            uint osMajorVersion;
            uint osMinorVersion; 
        }
 
        [StructLayout(LayoutKind.Sequential)] 
        struct AssemblyMetadata
        { 
            public ushort majorVersion;
            public ushort minorVersion;
            public ushort buildNumber;
            public ushort revisionNumber; 
            [SuppressMessage("Microsoft.Reliability", "CA2006:UseSafeHandleToEncapsulateNativeResources", Justification = "This points to memory and not to a native handle. So leaking will result in a memory leak at worst")]
            public IntPtr locale; 
            public uint localeSize; 
            public IntPtr processorIds;
            public uint processorIdCount; 
            public IntPtr osInfo;
            public uint osInfoCount;
        };
 
        [ComImport(), Guid(Guids.CLSID_MetaDataDispenser)]
        private class MetaDataDispenser 
        { 
        }
 
        [ComImport(), Guid(Guids.IID_IMetaDataDispenser), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        private interface IMetaDataDispenser
        {
            void DefineScope(); 
            int OpenScope([In, MarshalAs(UnmanagedType.LPWStr)]string scopeName, uint openFlags, [In]ref Guid riid, [Out, MarshalAs(UnmanagedType.IUnknown)] out object unknown);
            void OpenScopeOnMemory(); 
 
        }
 
        [ComImport(), Guid(Guids.IID_IMetaDataImport), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        private interface IMetaDataImport
        {
            void CloseEnum([In] IntPtr enumHandle); 
            void CountEnum();
            void ResetEnum(); 
            void EnumTypeDefs(); 
            void EnumInterfaceImpls();
            int EnumTypeRefs([In, Out] ref IntPtr enumHandle, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] rTypeRefs, uint cMax, ref uint typeRefs); 
            void FindTypeDefByName();
            void GetScopeProps();
            void GetModuleFromScope();
            void GetTypeDefProps(); 
            void GetInterfaceImplProps();
            int GetTypeRefProps([In] uint typeRefToken, [Out] out uint resolutionScopeToken, IntPtr typeRefName, uint nameLength, [Out] out uint actualLength); 
            /*....*/ 
        }
 
        [ComImport(), Guid(Guids.IID_IMetaDataAssemblyImport), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        private interface IMetaDataAssemblyImport
        {
            void GetAssemblyProps(); 
            int GetAssemblyRefProps([In] uint assemblyRefToken, [Out] out IntPtr publicKeyOrToken, [Out] out uint sizePublicKeyOrToken, IntPtr assemblyName, [In] uint assemblyNameBufferSize, [Out] out uint assemblyNameSize, [Out] out AssemblyMetadata assemblyMetaData, [Out] out IntPtr hashValueBlob, [Out] out uint hashValueSize, [Out] out uint assemblyRefFlags);
            /*....*/ 
        } 

        private static MetadataTokenType TokenTypeFromToken(uint token) 
        {
            return (MetadataTokenType)(token & 0xff000000);
        }
 
        internal static IEnumerable GetTypeRefNames(string assemblyLocation)
        { 
            IMetaDataDispenser metaDataDispenser = new MetaDataDispenser() as IMetaDataDispenser; 

            if (metaDataDispenser == null) 
            {
                throw new InvalidOperationException(String.Format(SR.GetString(SR.Error_MetaDataInterfaceMissing), assemblyLocation, "IMetaDataDispenser"));
            }
 
            Guid guidMetaDataImport = new Guid(Guids.IID_IMetaDataImport);
            object metaDataImportObj = null; 
 
            NativeMethods.ThrowOnFailure(metaDataDispenser.OpenScope(assemblyLocation, 0, ref guidMetaDataImport, out metaDataImportObj));
            IMetaDataImport metaDataImport = metaDataImportObj as IMetaDataImport; 
            if (metaDataImport == null)
            {
                throw new InvalidOperationException(String.Format(SR.GetString(SR.Error_MetaDataInterfaceMissing), assemblyLocation, "IMetaDataImport"));
            } 

            IntPtr enumHandle = new IntPtr(); 
            uint[] typeRefs = new uint[20]; 
            uint typeRefCount = 0;
 
            try
            {
                do
                { 
                    NativeMethods.ThrowOnFailure((metaDataImport.EnumTypeRefs(ref enumHandle, typeRefs, (uint)typeRefs.Length, ref typeRefCount)));
                    for (int typeRefIndex = 0; typeRefIndex < typeRefCount; typeRefIndex++) 
                    { 
                        IntPtr typeRefNamePtr = IntPtr.Zero;
                        uint typeRefNameLength; 
                        uint resolutionScopeToken;

                        NativeMethods.ThrowOnFailure(metaDataImport.GetTypeRefProps(typeRefs[typeRefIndex], out resolutionScopeToken, typeRefNamePtr, 0, out typeRefNameLength));
                        if (typeRefNameLength > 0) 
                        {
                            string typeRefName = String.Empty; 
                            typeRefNamePtr = Marshal.AllocCoTaskMem((int)(2 * (typeRefNameLength + 1))); 
                            try
                            { 
                                NativeMethods.ThrowOnFailure(metaDataImport.GetTypeRefProps(typeRefs[typeRefIndex], out resolutionScopeToken, typeRefNamePtr, typeRefNameLength, out typeRefNameLength));
                            }
                            finally
                            { 
                                typeRefName = Marshal.PtrToStringUni(typeRefNamePtr);
                                Marshal.FreeCoTaskMem(typeRefNamePtr); 
                            } 

                            IMetaDataAssemblyImport metaDataAssemblyImport = metaDataImportObj as IMetaDataAssemblyImport; 
                            if (metaDataAssemblyImport == null)
                            {
                                throw new InvalidOperationException(String.Format(SR.GetString(SR.Error_MetaDataInterfaceMissing), assemblyLocation, "IMetaDataAssemblyImport"));
                            } 

                            if (TokenTypeFromToken(resolutionScopeToken) == MetadataTokenType.AssemblyRef) 
                            { 
                                AssemblyMetadata assemblyMetadata;
                                IntPtr publicKeyOrToken = IntPtr.Zero; 
                                uint publicKeyOrTokenSize;
                                IntPtr assemblyName = IntPtr.Zero;
                                uint assemblyNameSize;
                                IntPtr hashValueBlob = IntPtr.Zero; 
                                uint hashValueSize;
                                uint assemblyRefFlags; 
 
                                NativeMethods.ThrowOnFailure(metaDataAssemblyImport.GetAssemblyRefProps(resolutionScopeToken, out publicKeyOrToken, out publicKeyOrTokenSize, assemblyName, 0, out assemblyNameSize, out assemblyMetadata, out hashValueBlob, out hashValueSize, out assemblyRefFlags));
 
                                if (assemblyNameSize > 0)
                                    assemblyName = Marshal.AllocCoTaskMem((int)(2 * (assemblyNameSize + 1)));

                                if (assemblyMetadata.localeSize > 0) 
                                    assemblyMetadata.locale = Marshal.AllocCoTaskMem((int)(2 * (assemblyMetadata.localeSize + 1)));
 
                                try 
                                {
                                    if (assemblyNameSize > 0 || assemblyMetadata.localeSize > 0) 
                                    {
                                        NativeMethods.ThrowOnFailure(metaDataAssemblyImport.GetAssemblyRefProps(resolutionScopeToken, out publicKeyOrToken, out publicKeyOrTokenSize, assemblyName, assemblyNameSize, out assemblyNameSize, out assemblyMetadata, out hashValueBlob, out hashValueSize, out assemblyRefFlags));
                                    }
 
                                    String publicKeyString = String.Empty;
                                    for (int pos = 0; pos < publicKeyOrTokenSize; pos++) 
                                    { 
                                        publicKeyString += String.Format("{0}", Marshal.ReadByte(publicKeyOrToken, pos).ToString("x2"));
                                    } 

                                    yield return String.Format("{0}, {1}, Version={2}.{3}.{4}.{5}, Culture={6}, PublicKeyToken={7}", typeRefName, Marshal.PtrToStringUni(assemblyName), assemblyMetadata.majorVersion, assemblyMetadata.minorVersion, assemblyMetadata.buildNumber, assemblyMetadata.revisionNumber, String.IsNullOrEmpty(Marshal.PtrToStringUni(assemblyMetadata.locale)) ? "neutral" : Marshal.PtrToStringUni(assemblyMetadata.locale), String.IsNullOrEmpty(publicKeyString) ? "null" : publicKeyString);
                                }
                                finally 
                                {
                                    if (assemblyName != IntPtr.Zero && assemblyNameSize > 0) 
                                    { 
                                        Marshal.FreeCoTaskMem(assemblyName);
                                        assemblyName = IntPtr.Zero; 
                                    }

                                    if (assemblyMetadata.locale != IntPtr.Zero && assemblyMetadata.localeSize > 0)
                                    { 
                                        Marshal.FreeCoTaskMem(assemblyMetadata.locale);
                                        assemblyMetadata.locale = IntPtr.Zero; 
                                    } 
                                }
                            } 
                        }
                    }
                }
                while (typeRefCount > 0); 
            }
            finally 
            { 
                metaDataImport.CloseEnum(enumHandle);
            } 
            yield break;
        }
    }
 
    #endregion
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK