// Get the attached workflow symbol and remove it from the root.
        WorkflowSymbol GetAttachedWorkflowSymbol()
        {
            object         rootInstance = this.GetRootInstance();
            WorkflowSymbol wfSymbol     = null;

            if (rootInstance != null)
            {
                Activity documentRootElement = GetRootWorkflowElement(rootInstance);
                if (documentRootElement != null)
                {
                    string symbolString;
                    if (AttachablePropertyServices.TryGetProperty <string>(documentRootElement, DebugSymbol.SymbolName, out symbolString))
                    {
                        try
                        {
                            wfSymbol = WorkflowSymbol.Decode(symbolString);
                            // Change the name to the currently loaded file.
                            wfSymbol.FileName = this.Context.Items.GetValue <WorkflowFileItem>().LoadedFile;
                        }
                        catch (Exception ex)
                        {
                            if (Fx.IsFatal(ex))
                            {
                                throw;
                            }
                        }
                        finally
                        {
                            AttachablePropertyServices.RemoveProperty(documentRootElement, DebugSymbol.SymbolName);
                        }
                    }
                }
            }
            return(wfSymbol);
        }
Esempio n. 2
0
        public void Load(string fileName)
        {
            if (string.IsNullOrEmpty(fileName))
            {
                throw FxTrace.Exception.AsError(new ArgumentNullException("fileName"));
            }

            DesignerConfigurationService service = this.Context.Services.GetService <DesignerConfigurationService>();

            service.SetDefaultOfLoadingFromUntrustedSourceEnabled();
            if (!service.LoadingFromUntrustedSourceEnabled && !IsFromUnrestrictedPath(fileName))
            {
                throw FxTrace.Exception.AsError(new SecurityException(string.Format(CultureInfo.CurrentUICulture, SR.UntrustedSourceDetected, fileName)));
            }

            try
            {
                IDocumentPersistenceService documentPersistenceService = this.Context.Services.GetService <IDocumentPersistenceService>();
                if (documentPersistenceService != null)
                {
                    this.Load(documentPersistenceService.Load(fileName));
                }
                else
                {
                    using (StreamReader fileStream = new StreamReader(fileName))
                    {
                        this.loadedFile = fileName;
                        WorkflowFileItem fileItem = new WorkflowFileItem();
                        fileItem.LoadedFile = fileName;
                        this.context.Items.SetValue(fileItem);
                        this.Text = fileStream.ReadToEnd();
                        this.Load();
                    }
                }
            }
            catch (Exception e)
            {
                if (Fx.IsFatal(e))
                {
                    throw;
                }
                else
                {
                    this.Context.Items.SetValue(new ErrorItem()
                    {
                        Message = e.Message, Details = e.ToString()
                    });
                }
            }
            if (!this.IsInErrorState())
            {
                this.lastWorkflowSymbol = GetAttachedWorkflowSymbol();
                if (this.debuggerService != null)
                {
                    this.debuggerService.InvalidateSourceLocationMapping(fileName);
                }
            }
        }
        Dictionary <object, SourceLocation> GetErrorInformation(Activity activity)
        {
            Dictionary <object, SourceLocation> sourceLocations = null;

            Activity implementationRoot     = null;
            IEnumerable <Activity> children = WorkflowInspectionServices.GetActivities(activity);

            foreach (Activity child in children)
            {
                // Check if the child is the root of the activity's implementation
                // When an activity is an implementation child of another activity, the IDSpace for
                // the implementation child is different than it's parent activity and parent's public
                // children. The IDs for activities in the root activity's IDSpace are 1, 2
                // etc and for the root implementation child it is 1.1 and for its implementation
                // child it is 1.1.1 and so on.
                // As the activity can have just one implementation root, we just check
                // for '.' to identify the root of the implementation.
                if (child.Id.Contains("."))
                {
                    implementationRoot = child;
                    break;
                }
            }

            if (implementationRoot == null)
            {
                return(sourceLocations);
            }

            // We use the workflow debug symbol to get the line and column number information for a
            // erroneous activity.
            // We do not rely on the workflow debug symbol to get the file name. This is to enable cases
            // where the xaml was hand written outside of the workflow designer. The hand written xaml
            // file will not have the workflow debug symbol unless it was saved in the workflow designer.
            string symbolString = DebugSymbol.GetSymbol(implementationRoot) as String;

            if (!string.IsNullOrEmpty(symbolString))
            {
                try
                {
                    WorkflowSymbol wfSymbol = WorkflowSymbol.Decode(symbolString);
                    if (wfSymbol != null)
                    {
                        sourceLocations = SourceLocationProvider.GetSourceLocations(activity, wfSymbol);
                    }
                }
                catch (Exception e)
                {
                    if (Fx.IsFatal(e))
                    {
                        throw;
                    }
                    // Ignore invalid symbol.
                }
            }
            return(sourceLocations);
        }
Esempio n. 4
0
        static internal Dictionary <object, SourceLocation> GetSourceLocations(Activity rootActivity, out string sourcePath, out bool isTemporaryFile, out byte[] checksum)
        {
            isTemporaryFile = false;
            checksum        = null;
            string symbolString = DebugSymbol.GetSymbol(rootActivity) as String;

            if (string.IsNullOrEmpty(symbolString) && rootActivity.Children != null && rootActivity.Children.Count > 0)
            { // In case of actual root is wrapped either in x:Class activity or CorrelationScope
                Activity body             = rootActivity.Children[0];
                string   bodySymbolString = DebugSymbol.GetSymbol(body) as String;
                if (!string.IsNullOrEmpty(bodySymbolString))
                {
                    rootActivity = body;
                    symbolString = bodySymbolString;
                }
            }

            if (!string.IsNullOrEmpty(symbolString))
            {
                try
                {
                    WorkflowSymbol wfSymbol = WorkflowSymbol.Decode(symbolString);
                    if (wfSymbol != null)
                    {
                        sourcePath = wfSymbol.FileName;
                        checksum   = wfSymbol.GetChecksum();
                        // rootActivity is the activity with the attached symbol string.
                        // rootActivity.RootActivity is the workflow root activity.
                        // if they are not the same, then it must be compiled XAML, because loose XAML (i.e. XAMLX) always have the symbol attached at the root.
                        if (rootActivity.RootActivity != rootActivity)
                        {
                            Fx.Assert(rootActivity.Parent != null, "Compiled XAML implementation always have a parent.");
                            rootActivity = rootActivity.Parent;
                        }
                        return(GetSourceLocations(rootActivity, wfSymbol, translateInternalActivityToOrigin: false));
                    }
                }
                catch (SerializationException)
                {
                    // Ignore invalid symbol.
                }
            }

            sourcePath = XamlDebuggerXmlReader.GetFileName(rootActivity) as string;
            Dictionary <object, SourceLocation> mapping;
            Assembly localAssembly;

            //bool permissionRevertNeeded = false;

            // This may not be the local assembly since it may not be the real root for x:Class
            localAssembly = rootActivity.GetType().Assembly;

            if (rootActivity.Parent != null)
            {
                localAssembly = rootActivity.Parent.GetType().Assembly;
            }

            if (rootActivity.Children != null && rootActivity.Children.Count > 0)
            { // In case of actual root is wrapped either in x:Class activity or CorrelationScope
                Activity body           = rootActivity.Children[0];
                string   bodySourcePath = XamlDebuggerXmlReader.GetFileName(body) as string;
                if (!string.IsNullOrEmpty(bodySourcePath))
                {
                    rootActivity = body;
                    sourcePath   = bodySourcePath;
                }
            }

            try
            {
                Fx.Assert(!string.IsNullOrEmpty(sourcePath), "If sourcePath is null, it should have been short-circuited before reaching here.");

                SourceLocation tempSourceLocation;
                Activity       tempRootActivity;

                checksum = SymbolHelper.CalculateChecksum(sourcePath);

                if (TryGetSourceLocation(rootActivity, sourcePath, checksum, out tempSourceLocation)) // already has source location.
                {
                    tempRootActivity = rootActivity;
                }
                else
                {
                    byte[] buffer;

#if NET45
                    // Need to store the file in memory temporary so don't have to re-read the file twice
                    // for XamlDebugXmlReader's BracketLocator.
                    // If there is a debugger attached, Assert FileIOPermission for Read access to the specific file.
                    if (System.Diagnostics.Debugger.IsAttached)
                    {
                        permissionRevertNeeded = true;
                        FileIOPermission permission = new FileIOPermission(FileIOPermissionAccess.Read, sourcePath);
                        permission.Assert();
                    }
#endif

                    try
                    {
                        FileInfo fi = new FileInfo(sourcePath);
                        buffer = new byte[fi.Length];

                        using (FileStream fs = new FileStream(sourcePath, FileMode.Open, FileAccess.Read))
                        {
                            fs.Read(buffer, 0, buffer.Length);
                        }
                    }
                    finally
                    {
#if NET45
                        // If we Asserted FileIOPermission, revert it.
                        if (permissionRevertNeeded)
                        {
                            CodeAccessPermission.RevertAssert();
                            permissionRevertNeeded = false;
                        }
#endif
                    }

                    object deserializedObject = Deserialize(buffer, localAssembly);
                    IDebuggableWorkflowTree debuggableWorkflowTree = deserializedObject as IDebuggableWorkflowTree;
                    if (debuggableWorkflowTree != null)
                    { // Declarative Service and x:Class case
                        tempRootActivity = debuggableWorkflowTree.GetWorkflowRoot();
                    }
                    else
                    { // Loose XAML case.
                        tempRootActivity = deserializedObject as Activity;
                    }

                    Fx.Assert(tempRootActivity != null, "Unexpected workflow xaml file");
                }

                mapping = new Dictionary <object, SourceLocation>();
                if (tempRootActivity != null)
                {
                    CollectMapping(rootActivity, tempRootActivity, mapping, sourcePath, checksum);
                }
            }
            catch (Exception)
            {
                //// Only eat the exception if we were running in partial trust.
                //if (!PartialTrustHelpers.AppDomainFullyTrusted)
                //{
                //    // Eat the exception and return an empty dictionary.
                //    return new Dictionary<object, SourceLocation>();
                //}
                //else
                //{
                throw;
                //}
            }

            return(mapping);
        }
Esempio n. 5
0
        // For most of the time, we need source location for object that appear on XAML.
        // During debugging, however, we must not transform the internal activity to their origin to make sure it stop when the internal activity is about the execute
        // Therefore, in debugger scenario, translateInternalActivityToOrigin will be set to false.
        internal static Dictionary <object, SourceLocation> GetSourceLocations(Activity rootActivity, WorkflowSymbol symbol, bool translateInternalActivityToOrigin)
        {
            Activity workflowRoot = rootActivity.RootActivity ?? rootActivity;

            if (!workflowRoot.IsMetadataFullyCached)
            {
                IList <ValidationError> validationErrors = null;
                ActivityUtilities.CacheRootMetadata(workflowRoot, new ActivityLocationReferenceEnvironment(), ProcessActivityTreeOptions.ValidationOptions, null, ref validationErrors);
            }

            Dictionary <object, SourceLocation> newMapping = new Dictionary <object, SourceLocation>();

            // Make sure the qid we are using to TryGetElementFromRoot
            // are shifted appropriately such that the first digit that QID is
            // the same as the last digit of the rootActivity.QualifiedId.

            int[] rootIdArray = rootActivity.QualifiedId.AsIDArray();
            int   idOffset    = rootIdArray[rootIdArray.Length - 1] - 1;

            foreach (ActivitySymbol actSym in symbol.Symbols)
            {
                QualifiedId qid = new QualifiedId(actSym.QualifiedId);
                if (idOffset != 0)
                {
                    int[] idArray = qid.AsIDArray();
                    idArray[0] += idOffset;
                    qid         = new QualifiedId(idArray);
                }
                Activity activity;
                if (QualifiedId.TryGetElementFromRoot(rootActivity, qid, out activity))
                {
                    object origin = activity;
                    if (translateInternalActivityToOrigin && activity.Origin != null)
                    {
                        origin = activity.Origin;
                    }

                    newMapping.Add(origin,
                                   new SourceLocation(symbol.FileName, symbol.GetChecksum(), actSym.StartLine, actSym.StartColumn, actSym.EndLine, actSym.EndColumn));
                }
            }
            return(newMapping);
        }
Esempio n. 6
0
 public static Dictionary <object, SourceLocation> GetSourceLocations(Activity rootActivity, WorkflowSymbol symbol)
 {
     return(GetSourceLocations(rootActivity, symbol, translateInternalActivityToOrigin: true));
 }
Esempio n. 7
0
        // This supports loading objects instead of xaml into the designer
        public void Load(object instance)
        {
            if (isLoaded)
            {
                throw FxTrace.Exception.AsError(new InvalidOperationException(SR.WorkflowDesignerLoadShouldBeCalledOnlyOnce));
            }

            isLoaded = true;

            if (instance == null)
            {
                throw FxTrace.Exception.AsError(new ArgumentNullException("instance"));
            }

            DesignerConfigurationService configurationService = this.context.Services.GetService <DesignerConfigurationService>();

            configurationService.ApplyDefaultPreference();

            // Because we want AutoConnect/AutoSplit to be on even in Dev10 if PU1 is installed.
            // But we cannot know whether PU1 is installed or not, we decide to enable these 2 features for all Dev10.
            if (configurationService.WorkflowDesignerHostId == WorkflowDesignerHostId.Dev10)
            {
                configurationService.AutoConnectEnabled = true;
                configurationService.AutoSplitEnabled   = true;
            }

            configurationService.IsWorkflowLoaded = true;
            configurationService.Validate();

            if (this.PreviewLoad != null)
            {
                this.PreviewLoad(this, new PreviewLoadEventArgs(instance, this.context));
            }

            if (configurationService.TargetFrameworkName.IsLessThan45())
            {
                TargetFrameworkPropertyFilter.FilterOut45Properties();
            }

            modelTreeManager = new ModelTreeManager(this.context);
            modelTreeManager.Load(instance);
            this.context.Services.Publish(typeof(ModelTreeManager), modelTreeManager);
            viewManager = GetViewManager(this.modelTreeManager.Root);
            this.context.Services.Publish <ModelSearchService>(this.ModelSearchService);
            view.Children.Add((UIElement)viewManager.View);

            modelTreeManager.EditingScopeCompleted += new EventHandler <EditingScopeEventArgs>(OnEditingScopeCompleted);

            this.view.Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle,
                                             new Action(() => { this.perfEventProvider.WorkflowDesignerApplicationIdleAfterLoad(); }));

            //Subscribe to the ViewStateChanged event of ViewStateService to show document dirty. It would be published in the call to GetViewManager().
            WorkflowViewStateService wfViewStateService = this.Context.Services.GetService(typeof(ViewStateService)) as WorkflowViewStateService;

            if (wfViewStateService != null)
            {
                wfViewStateService.UndoableViewStateChanged += new ViewStateChangedEventHandler(OnViewStateChanged);
            }
            this.isModelChanged = false;
            if (!this.IsInErrorState())
            {
                this.lastWorkflowSymbol = GetAttachedWorkflowSymbol();
            }
        }
Esempio n. 8
0
        public void Load()
        {
            this.perfEventProvider.WorkflowDesignerLoadStart();
            if (!string.IsNullOrEmpty(this.text))
            {
                try
                {
                    this.perfEventProvider.WorkflowDesignerDeserializeStart();

                    IList <XamlLoadErrorInfo>           loadErrors;
                    Dictionary <object, SourceLocation> sourceLocations;
                    object deserializedObject = DeserializeString(this.text, out loadErrors, out sourceLocations);

                    this.perfEventProvider.WorkflowDesignerDeserializeEnd();

                    if (deserializedObject != null)
                    {
                        this.Load(deserializedObject);
                        this.ValidationService.ValidateWorkflow(ValidationReason.Load);
                    }
                    else
                    {
                        StringBuilder details = new StringBuilder();
                        foreach (XamlLoadErrorInfo error in loadErrors)
                        {
                            details.AppendLine(error.Message);
                        }
                        this.Context.Items.SetValue(new ErrorItem()
                        {
                            Message = SR.SeeErrorWindow, Details = details.ToString()
                        });
                    }
                    if (loadErrors != null)
                    {
                        RaiseLoadErrors(loadErrors);
                    }
                    this.isModelChanged = false;
                }
                catch (Exception e)
                {
                    this.Context.Items.SetValue(new ErrorItem()
                    {
                        Message = e.Message, Details = e.ToString()
                    });
                    RaiseLoadError(e);
                }
            }
            else
            {
                this.Context.Items.SetValue(new ErrorItem()
                {
                    Message = string.Empty, Details = string.Empty
                });
            }
            if (this.IsInErrorState())
            {
                // Clear workflow symbol in case ErrorState changes during validation
                this.lastWorkflowSymbol = null;
            }
            this.perfEventProvider.WorkflowDesignerLoadComplete();
        }
        private void UpdateDebugSymbol(ClassData classData, XamlBuildTypeGenerationExtensionContext buildContext)
        {
            string path = Path.GetFullPath(classData.FileName);

            try
            {
                using (XamlReader reader = classData.EmbeddedResourceXaml.GetReader())
                {
                    XamlNodeList newList = new XamlNodeList(reader.SchemaContext);
                    using (XamlWriter writer = newList.Writer)
                    {
                        bool nodesAvailable = reader.Read();
                        while (nodesAvailable)
                        {
                            if (reader.NodeType == XamlNodeType.StartMember)
                            {
                                writer.WriteNode(reader);
                                if (reader.Member.DeclaringType != null &&
                                    reader.Member.DeclaringType.UnderlyingType != null &&
                                    string.CompareOrdinal(reader.Member.DeclaringType.UnderlyingType.FullName, debugSymbolTypeFullName) == 0)
                                {
                                    reader.Read();
                                    string symbolString = reader.Value as string;
                                    if (!string.IsNullOrEmpty(symbolString))
                                    {
                                        WorkflowSymbol symbol = WorkflowSymbol.Decode(symbolString);
                                        symbol.FileName = path;
                                        symbol.CalculateChecksum();
                                        writer.WriteValue(symbol.Encode());
                                    }
                                    else
                                    {
                                        writer.WriteValue(reader.Value);
                                    }
                                }

                                nodesAvailable = reader.Read();
                            }
                            else
                            {
                                writer.WriteNode(reader);
                                nodesAvailable = reader.Read();
                            }
                        }
                    }

                    classData.EmbeddedResourceXaml = newList;
                }
            }
            catch (Exception e)
            {
                if (Fx.IsFatal(e))
                {
                    throw;
                }

                buildContext.XamlBuildLogger.LogMessage(
                    MessageImportance.High,
                    SR.DebugBuildExtensionExceptionPrefix(
                        typeof(DebugBuildExtension).Name,
                        path,
                        e.Message));
            }
        }