1 // Copyright (c) Microsoft Corporation. All rights reserved.
3 // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
4 // WHETHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
5 // WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
6 // THE ENTIRE RISK OF USE OR RESULTS IN CONNECTION WITH THE USE OF THIS CODE
7 // AND INFORMATION REMAINS WITH THE USER.
10 /*********************************************************************
11 * NOTE: A copy of this file exists at: WF\Activities\Common
12 * The two files must be kept in [....]. Any change made here must also
13 * be made to WF\Activities\Common\CompModHelpers.cs
14 *********************************************************************/
15 namespace System.Workflow.ComponentModel.Design
19 using System.Collections;
20 using System.Collections.Generic;
21 using System.ComponentModel;
22 using System.Diagnostics;
23 using System.ComponentModel.Design;
24 using System.ComponentModel.Design.Serialization;
25 using System.Workflow.ComponentModel.Serialization;
27 using System.Runtime.Serialization.Formatters.Binary;
28 using System.Windows.Forms;
30 using System.Drawing.Design;
31 using System.Workflow.ComponentModel;
32 using System.Workflow.ComponentModel.Compiler;
34 using System.Reflection;
36 using System.Globalization;
37 using Microsoft.Win32;
38 using System.Runtime.InteropServices;
39 using System.Diagnostics.CodeAnalysis;
42 internal static class Helpers
44 private static readonly string VSExtensionProductRegistrySubKey = "Visual Studio Ext for Windows Workflow";
47 internal static readonly string ProductRootRegKey = @"SOFTWARE\Microsoft\Net Framework Setup\NDP\v4.0\Setup\Windows Workflow Foundation";
48 internal static readonly string ProductInstallDirectory = GetInstallDirectory(false);
49 internal static readonly string ProductSDKInstallDirectory = GetInstallDirectory(true);
50 internal static readonly string TypeProviderAssemblyRegValueName = "References";
52 private static readonly string ProductRootRegKey30 = @"SOFTWARE\Microsoft\Net Framework Setup\NDP\v3.0\Setup\Windows Workflow Foundation";
53 internal static readonly string ProductInstallDirectory30 = GetInstallDirectory30();
55 private const string ProductCode = "{B644FB52-BB3D-4C43-80EC-57644210536A}";
56 private const string ProductSDKCode = "{C8A7718A-FF6D-4DDC-AE36-BBF968D6799B}";
57 private const string INSTALLPROPERTY_INSTALLLOCATION = "InstallLocation";
59 internal const int FILENAME_MAX = 260; //"stdio.h"
61 [SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison", Justification = "LastIndexOf(\"\\\") not a security issue.")]
62 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
63 internal static string PerUserRegistryKey
67 string keyPath = String.Empty;
68 using (RegistryKey userRegistryKey = Application.UserAppDataRegistry)
70 keyPath = userRegistryKey.ToString().Substring(Registry.CurrentUser.ToString().Length + 1);
71 keyPath = keyPath.Substring(0, keyPath.LastIndexOf("\\"));
72 keyPath += "\\" + VSExtensionProductRegistrySubKey;
78 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
79 private static string TypeProviderRegistryKeyPath
83 return PerUserRegistryKey + "\\TypeProvider";
87 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
88 internal static bool IsFileNameValid(string fileName)
90 int length = Path.GetInvalidPathChars().GetLength(0) + 5;
91 char[] invalidChars = new char[length];
92 Path.GetInvalidPathChars().CopyTo(invalidChars, 0);
93 invalidChars[length - 5] = ':';
94 invalidChars[length - 4] = '?';
95 invalidChars[length - 3] = '*';
96 invalidChars[length - 2] = '/';
97 invalidChars[length - 1] = '\\';
99 return (fileName != null &&
100 fileName.Length != 0 &&
101 fileName.Length <= FILENAME_MAX &&
102 fileName.IndexOfAny(invalidChars) == -1);
105 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
106 internal static bool AreAllActivities(ICollection c)
109 throw new ArgumentNullException("c");
111 foreach (object obj in c)
113 if (!(obj is Activity))
119 // this will return IDictionary, whose keys are parent and value is arraylist of child activities
120 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
121 internal static IDictionary PairUpCommonParentActivities(ICollection activities)
123 if (activities == null)
124 throw new ArgumentNullException("activities");
126 Hashtable commonParentActivities = new Hashtable();
127 foreach (Activity activity in activities)
129 if (activity.Parent != null)
131 ArrayList childActivities = (ArrayList)commonParentActivities[activity.Parent];
132 if (childActivities == null)
134 childActivities = new ArrayList();
135 commonParentActivities.Add(activity.Parent, childActivities);
137 childActivities.Add(activity);
140 return commonParentActivities;
143 // this will remove any activity from the collection whose parent is already there in the collection
144 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
145 internal static Activity[] GetTopLevelActivities(ICollection activities)
147 if (activities == null)
148 throw new ArgumentNullException("activities");
150 List<Activity> filteredActivities = new List<Activity>();
151 foreach (object obj in activities)
153 Activity activity = obj as Activity;
154 if (activity != null)
156 bool foundParent = false;
157 Activity parentActivity = activity.Parent;
158 while (parentActivity != null && !foundParent)
160 foreach (object obj2 in activities)
162 if (obj2 == parentActivity)
168 parentActivity = parentActivity.Parent;
172 filteredActivities.Add(activity);
175 return filteredActivities.ToArray();
178 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
179 internal static Activity[] GetNestedActivities(CompositeActivity compositeActivity)
182 if (compositeActivity == null)
183 throw new ArgumentNullException("compositeActivity");
185 IList<Activity> childActivities = null;
186 ArrayList nestedActivities = new ArrayList();
187 Queue compositeActivities = new Queue();
188 compositeActivities.Enqueue(compositeActivity);
189 while (compositeActivities.Count > 0)
191 CompositeActivity compositeActivity2 = (CompositeActivity)compositeActivities.Dequeue();
192 childActivities = compositeActivity2.Activities;
194 foreach (Activity activity in childActivities)
196 nestedActivities.Add(activity);
197 if (activity is CompositeActivity)
198 compositeActivities.Enqueue(activity);
201 return (Activity[])nestedActivities.ToArray(typeof(Activity));
205 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
206 internal static IList GetIdentifiersInCompositeActivity(CompositeActivity compositeActivity)
208 ArrayList identifiers = new ArrayList();
209 if (compositeActivity != null)
211 identifiers.Add(compositeActivity.Name);
212 IList<Activity> allChildren = GetAllNestedActivities(compositeActivity);
213 foreach (Activity activity in allChildren)
214 identifiers.Add(activity.Name);
216 return ArrayList.ReadOnly(identifiers);
219 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
220 internal static Activity[] GetAllNestedActivities(CompositeActivity compositeActivity)
222 if (compositeActivity == null)
223 throw new ArgumentNullException("compositeActivity");
225 ArrayList nestedActivities = new ArrayList();
227 // Note: GetAllNestedActivities will not check for black box activities.
228 // This is to allow it to be invoked from within the activity's
230 //if(Helpers.IsCustomActivity(compositeActivity))
231 //return (Activity[])nestedActivities.ToArray(typeof(Activity));
233 Queue compositeActivities = new Queue();
234 compositeActivities.Enqueue(compositeActivity);
235 while (compositeActivities.Count > 0)
237 CompositeActivity compositeActivity2 = (CompositeActivity)compositeActivities.Dequeue();
238 if (compositeActivity2 == compositeActivity || !Helpers.IsCustomActivity(compositeActivity2))
240 foreach (Activity activity in compositeActivity2.Activities)
242 nestedActivities.Add(activity);
243 if (activity is CompositeActivity)
244 compositeActivities.Enqueue(activity);
247 foreach (Activity activity in compositeActivity2.EnabledActivities)
249 if (!nestedActivities.Contains(activity))
251 nestedActivities.Add(activity);
252 if (activity is CompositeActivity)
253 compositeActivities.Enqueue(activity);
258 return (Activity[])nestedActivities.ToArray(typeof(Activity));
261 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
262 internal static string MergeNamespaces(string primaryNs, string secondaryNs)
264 string newNs = primaryNs;
265 if (secondaryNs != null && secondaryNs.Length > 0)
267 if (newNs != null && newNs.Length > 0)
268 newNs += ("." + secondaryNs);
274 newNs = string.Empty;
278 internal static Activity GetRootActivity(Activity activity)
280 if (activity == null)
281 throw new ArgumentNullException("activity");
283 while (activity.Parent != null)
284 activity = activity.Parent;
289 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
290 internal static Stream SerializeDesignersToStream(ICollection activities)
292 Stream stateStream = new MemoryStream();
293 BinaryWriter writer = new BinaryWriter(stateStream);
295 Queue<IComponent> serializedComponents = new Queue<IComponent>();
296 foreach (IComponent activity in activities)
297 serializedComponents.Enqueue(activity);
299 while (serializedComponents.Count > 0)
301 IComponent component = serializedComponents.Dequeue();
302 if (component != null && component.Site != null)
304 IDesignerHost designerHost = component.Site.GetService(typeof(IDesignerHost)) as IDesignerHost;
305 if (designerHost == null)
306 throw new InvalidOperationException(
307 SR.GetString(SR.General_MissingService, typeof(IDesignerHost).Name));
309 ActivityDesigner activityDesigner = designerHost.GetDesigner(component) as ActivityDesigner;
310 if (activityDesigner != null)
314 ((IPersistUIState)activityDesigner).SaveViewState(writer);
316 CompositeActivity compositeActivity = component as CompositeActivity;
317 if (compositeActivity != null)
319 foreach (IComponent childActivity in compositeActivity.Activities)
321 serializedComponents.Enqueue(childActivity);
335 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
336 internal static void DeserializeDesignersFromStream(ICollection activities, Stream stateStream)
338 if (stateStream.Length == 0)
341 BinaryReader reader = new BinaryReader(stateStream);
342 stateStream.Seek(0, SeekOrigin.Begin);
344 Queue<IComponent> serializedComponents = new Queue<IComponent>();
345 foreach (IComponent component in activities)
346 serializedComponents.Enqueue(component);
348 while (serializedComponents.Count > 0)
350 IComponent component = serializedComponents.Dequeue();
351 if (component != null && component.Site != null)
353 IDesignerHost designerHost = component.Site.GetService(typeof(IDesignerHost)) as IDesignerHost;
354 if (designerHost == null)
355 throw new InvalidOperationException(
356 SR.GetString(SR.General_MissingService, typeof(IDesignerHost).Name));
358 ActivityDesigner activityDesigner = designerHost.GetDesigner(component) as ActivityDesigner;
359 if (activityDesigner != null)
363 ((IPersistUIState)activityDesigner).LoadViewState(reader);
365 CompositeActivity compositeActivity = component as CompositeActivity;
366 if (compositeActivity != null)
368 foreach (IComponent childActivity in compositeActivity.Activities)
370 serializedComponents.Enqueue(childActivity);
382 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
383 internal static string GetBaseIdentifier(Activity activity)
385 string baseIdentifier = activity.GetType().Name;
386 StringBuilder b = new StringBuilder(baseIdentifier.Length);
387 for (int i = 0; i < baseIdentifier.Length; i++)
389 if (Char.IsUpper(baseIdentifier[i]) && (i == 0 || i == baseIdentifier.Length - 1 || Char.IsUpper(baseIdentifier[i + 1])))
391 b.Append(Char.ToLowerInvariant(baseIdentifier[i]));
395 b.Append(baseIdentifier.Substring(i));
402 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
403 internal static string GetRootNamespace(IServiceProvider serviceProvider)
405 if (serviceProvider == null)
406 throw new ArgumentNullException("serviceProvider");
408 string rootNs = string.Empty;
409 IWorkflowCompilerOptionsService compilerOptionsService = (IWorkflowCompilerOptionsService)serviceProvider.GetService(typeof(IWorkflowCompilerOptionsService));
410 if (compilerOptionsService != null && compilerOptionsService.RootNamespace != null)
411 rootNs = compilerOptionsService.RootNamespace; //e.g. WorkflowApp1
415 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
416 internal static Type GetDataSourceClass(Activity activity, IServiceProvider serviceProvider)
418 if (activity == null)
419 throw new ArgumentNullException("activity");
420 if (serviceProvider == null)
421 throw new ArgumentNullException("serviceProvider");
423 Type activityType = null;
424 string className = null;
425 if (activity == GetRootActivity(activity))
426 className = activity.GetValue(WorkflowMarkupSerializer.XClassProperty) as String;
428 if (!String.IsNullOrEmpty(className))
430 ITypeProvider typeProvider = (ITypeProvider)serviceProvider.GetService(typeof(ITypeProvider));
431 if (typeProvider == null)
432 throw new InvalidOperationException(
433 SR.GetString(SR.General_MissingService, typeof(ITypeProvider).Name));
435 activityType = typeProvider.GetType(className);
439 return activity.GetType();
445 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
446 internal static Activity GetDataSourceActivity(Activity activity, string inputName, out string name)
448 if (activity == null)
449 throw new ArgumentNullException("activity");
450 if (string.IsNullOrEmpty(inputName))
451 throw new ArgumentException("inputName");
454 if (inputName.IndexOf('.') == -1)
457 int indexOfDot = inputName.LastIndexOf('.');
458 string scopeID = inputName.Substring(0, indexOfDot);
459 name = inputName.Substring(indexOfDot + 1);
461 Activity contextActivity = Helpers.ParseActivityForBind(activity, scopeID);
462 if (contextActivity == null)
463 contextActivity = Helpers.ParseActivity(Helpers.GetRootActivity(activity), scopeID);
465 // activity can be either the qualified id of the scope activity or the qualified id of the custom activity.
466 return contextActivity;
469 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
470 internal static void GetNamespaceAndClassName(string fullQualifiedName, out string namespaceName, out string className)
472 namespaceName = String.Empty;
473 className = String.Empty;
475 if (fullQualifiedName == null)
478 int indexOfDot = fullQualifiedName.LastIndexOf('.');
479 if (indexOfDot != -1)
481 namespaceName = fullQualifiedName.Substring(0, indexOfDot);
482 className = fullQualifiedName.Substring(indexOfDot + 1);
486 className = fullQualifiedName;
490 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
491 internal static CodeTypeDeclaration GetCodeNamespaceAndClass(CodeNamespaceCollection namespaces, string namespaceName, string className, out CodeNamespace codeNamespace)
493 codeNamespace = null;
494 foreach (CodeNamespace ns in namespaces)
496 if (ns.Name == namespaceName)
503 CodeTypeDeclaration codeTypeDeclaration = null;
504 if (codeNamespace != null)
506 foreach (CodeTypeDeclaration typeDecl in codeNamespace.Types)
508 if (typeDecl.Name == className)
510 codeTypeDeclaration = typeDecl;
515 return codeTypeDeclaration;
518 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
519 internal static string GetClassName(string fullQualifiedName)
521 if (fullQualifiedName == null)
524 string className = fullQualifiedName;
525 int indexOfDot = fullQualifiedName.LastIndexOf('.');
526 if (indexOfDot != -1)
527 className = fullQualifiedName.Substring(indexOfDot + 1);
532 [DllImport("msi.dll", SetLastError = true, ExactSpelling = true, CharSet = CharSet.Auto)]
533 private static extern int MsiGetProductInfoW(string szProduct, string szProperty, StringBuilder lpValueBuf, ref int pcchValueBuf);
534 private static string GetInstallDirectory(bool getSDKDir)
536 string path = string.Empty;
539 //ERROR_UNKNOWN_PROPERTY 1608L
540 //ERROR_INVALID_PARAMETER 87L
541 int length = FILENAME_MAX + 1;
542 StringBuilder location = new StringBuilder(length);
543 int hr = MsiGetProductInfoW(getSDKDir ? ProductSDKCode : ProductCode, INSTALLPROPERTY_INSTALLLOCATION, location, ref length);
544 int error = Marshal.GetLastWin32Error();
547 path = location.ToString();
551 Debug.WriteLine("Error loading install directory: " + error.ToString(CultureInfo.CurrentCulture));
559 if (string.IsNullOrEmpty(path))
565 using (RegistryKey key = Registry.LocalMachine.OpenSubKey(ProductRootRegKey))
568 path = (string)key.GetValue("InstallDir");
578 if (string.IsNullOrEmpty(path))
579 path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
584 private static string GetInstallDirectory30()
586 string path = string.Empty;
589 //ERROR_UNKNOWN_PROPERTY 1608L
590 //ERROR_INVALID_PARAMETER 87L
591 int length = FILENAME_MAX + 1;
592 StringBuilder location = new StringBuilder(length);
593 int hr = MsiGetProductInfoW(ProductCode, INSTALLPROPERTY_INSTALLLOCATION, location, ref length);
594 int error = Marshal.GetLastWin32Error();
597 path = location.ToString();
601 Debug.WriteLine("Error loading 3.0 install directory: " + error.ToString(CultureInfo.CurrentCulture));
609 if (string.IsNullOrEmpty(path))
613 using (RegistryKey key = Registry.LocalMachine.OpenSubKey(ProductRootRegKey30))
617 path = (string)key.GetValue("InstallDir");
629 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
630 internal static Type GetBaseType(PropertyInfo property, object owner, IServiceProvider serviceProvider)
632 //When we are emitting code for the dynamic properties we might get the propertyinfo as null
634 throw new ArgumentNullException("owner");
636 if (serviceProvider == null)
637 throw new ArgumentNullException("serviceProvider");
639 if (property != null)
641 IDynamicPropertyTypeProvider basetypeProvider = owner as IDynamicPropertyTypeProvider;
642 if (basetypeProvider != null)
644 Type type = basetypeProvider.GetPropertyType(serviceProvider, property.Name);
649 return property.PropertyType;
656 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
657 internal static AccessTypes GetAccessType(PropertyInfo property, object owner, IServiceProvider serviceProvider)
659 //When we are emitting code for the dynamic properties we might get the propertyinfo as null
661 throw new ArgumentNullException("owner");
663 if (serviceProvider == null)
664 throw new ArgumentNullException("serviceProvider");
666 if (property != null)
668 IDynamicPropertyTypeProvider basetypeProvider = owner as IDynamicPropertyTypeProvider;
669 if (basetypeProvider != null)
670 return basetypeProvider.GetAccessType(serviceProvider, property.Name);
673 return AccessTypes.Read;
676 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
677 internal static bool IsChildActivity(CompositeActivity parent, Activity activity)
679 foreach (Activity containedActivity in parent.Activities)
681 if (activity == containedActivity)
684 if (containedActivity is CompositeActivity &&
685 Helpers.IsChildActivity(containedActivity as CompositeActivity, activity))
692 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
693 internal static bool TypesEqual(CodeTypeReference typeLeft, Type typeRight)
695 if (typeRight.IsArray && typeLeft.ArrayRank != typeRight.GetArrayRank()) return false;
697 if (!typeLeft.BaseType.Equals(typeRight.FullName)) return false;
699 if (typeLeft.ArrayRank > 0)
700 return TypesEqual(typeLeft.ArrayElementType, typeRight.GetElementType());
704 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
705 internal static bool TypesEqual(CodeTypeReference typeLeft, CodeTypeReference typeRight)
707 if (typeLeft.ArrayRank != typeRight.ArrayRank) return false;
708 if (!typeLeft.BaseType.Equals(typeRight.BaseType)) return false;
710 if (typeLeft.ArrayRank > 0)
711 return TypesEqual(typeLeft.ArrayElementType, typeRight.ArrayElementType);
715 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
716 internal static DesignerSerializationVisibility GetSerializationVisibility(MemberInfo memberInfo)
719 if (memberInfo == null)
720 throw new ArgumentNullException("memberInfo");
722 DesignerSerializationVisibility designerSerializationVisibility = DesignerSerializationVisibility.Visible;
724 // Calling GetCustomAttributes on PropertyInfo or EventInfo when the inherit parameter of GetCustomAttributes
725 // is true does not walk the type hierarchy. But System.Attribute.GetCustomAttributes causes perf issues.
726 object[] attributes = memberInfo.GetCustomAttributes(typeof(DesignerSerializationVisibilityAttribute), true);
727 if (attributes.Length > 0)
728 designerSerializationVisibility = (attributes[0] as DesignerSerializationVisibilityAttribute).Visibility;
729 else if (Attribute.IsDefined(memberInfo, typeof(DesignerSerializationVisibilityAttribute)))
730 designerSerializationVisibility = (Attribute.GetCustomAttribute(memberInfo, typeof(DesignerSerializationVisibilityAttribute)) as DesignerSerializationVisibilityAttribute).Visibility;
732 return designerSerializationVisibility;
735 // Method parameters must match exactly
737 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
738 internal static MethodInfo GetMethodExactMatch(Type type, string name, BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers)
740 MethodInfo foundMethod = null;
741 MethodInfo[] methods = type.GetMethods(bindingAttr);
742 foreach (MethodInfo method in methods)
744 bool matchName = ((bindingAttr & BindingFlags.IgnoreCase) == BindingFlags.IgnoreCase) ? string.Compare(method.Name, name, StringComparison.OrdinalIgnoreCase) == 0 : string.Compare(method.Name, name, StringComparison.Ordinal) == 0;
747 bool mismatch = false;
750 ParameterInfo[] parameters = method.GetParameters();
751 if (parameters.GetLength(0) == types.Length)
753 for (int index = 0; !mismatch && index < parameters.Length; index++)
754 mismatch = (parameters[index].ParameterType == null) || (!parameters[index].ParameterType.IsAssignableFrom(types[index]));
761 foundMethod = method;
770 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
771 internal static T GetAttributeFromObject<T>(object attributeObject) where T : Attribute
773 if (attributeObject is AttributeInfoAttribute)
774 return (T)((AttributeInfoAttribute)attributeObject).AttributeInfo.CreateAttribute();
776 if (attributeObject is T)
777 return (T)attributeObject;
782 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
783 internal static Type GetDelegateFromEvent(EventInfo eventInfo)
785 if (eventInfo.EventHandlerType != null)
786 return eventInfo.EventHandlerType;
788 return TypeProvider.GetEventHandlerType(eventInfo);
791 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
792 internal static void AddTypeProviderAssembliesFromRegistry(TypeProvider typeProvider, IServiceProvider serviceProvider)
794 if (typeProvider == null)
795 throw new ArgumentNullException("typeProvider");
796 if (serviceProvider == null)
797 throw new ArgumentNullException("serviceProvider");
799 RegistryKey referenceKey = Registry.CurrentUser.OpenSubKey(TypeProviderRegistryKeyPath);
800 if (referenceKey != null)
802 ITypeProviderCreator typeProviderCreator = serviceProvider.GetService(typeof(ITypeProviderCreator)) as ITypeProviderCreator;
803 foreach (string assemblyName in ((string[])referenceKey.GetValue(TypeProviderAssemblyRegValueName)))
807 if (typeProviderCreator != null)
809 bool addAssembly = true;
810 Assembly assembly = typeProviderCreator.GetTransientAssembly(AssemblyName.GetAssemblyName(assemblyName));
811 // Check to see if a copy of the assembly is already added.
812 if (assembly != null)
814 foreach (Type type in assembly.GetTypes())
816 if (typeProvider.GetType(type.AssemblyQualifiedName) != null)
821 typeProvider.AddAssembly(assembly);
825 // AddAssemblyReference should take care of duplicates.
826 typeProvider.AddAssemblyReference(assemblyName);
835 referenceKey.Close();
839 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
840 internal static void UpdateTypeProviderAssembliesRegistry(string assemblyName)
842 RegistryKey referenceKey = Registry.CurrentUser.CreateSubKey(TypeProviderRegistryKeyPath);
843 if (referenceKey != null)
847 ArrayList references = null;
848 if (referenceKey.ValueCount > 0)
849 references = new ArrayList((string[])referenceKey.GetValue(TypeProviderAssemblyRegValueName));
851 references = new ArrayList();
853 if (!references.Contains(assemblyName))
855 references.Add(assemblyName);
856 referenceKey.SetValue(TypeProviderAssemblyRegValueName, ((string[])references.ToArray(typeof(string))));
861 //We eat the exception
865 referenceKey.Close();
870 internal static CompositeActivity GetDeclaringActivity(Activity activity)
872 if (activity == null)
873 throw new ArgumentNullException("activity");
875 CompositeActivity parent = activity.Parent;
876 while (parent != null)
878 // This will be the root
879 if (parent.Parent == null)
882 // Any custom activity found is the declaring activity
883 if (IsCustomActivity(parent))
886 parent = parent.Parent;
891 internal static bool IsActivityLocked(Activity activity)
893 if (activity == null)
894 throw new ArgumentNullException("activity");
896 CompositeActivity parent = activity.Parent;
897 while (parent != null)
899 // If root, not locked
900 if (parent.Parent == null)
903 // Any custom activity found, then locked
904 if (IsCustomActivity(parent))
907 parent = parent.Parent;
913 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
914 internal static Activity GetEnclosingActivity(Activity activity)
916 Activity enclosingActivity;
918 if (IsActivityLocked(activity))
919 enclosingActivity = Helpers.GetDeclaringActivity(activity);
921 enclosingActivity = GetRootActivity(activity);
923 return enclosingActivity;
926 // This function returns all the executable activities including secondary flow activities.
927 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
928 public static IList<Activity> GetAllEnabledActivities(CompositeActivity compositeActivity)
930 if (compositeActivity == null)
931 throw new ArgumentNullException("compositeActivity");
933 List<Activity> allActivities = new List<Activity>(compositeActivity.EnabledActivities);
934 foreach (Activity childActivity in compositeActivity.Activities)
936 if (childActivity.Enabled &&
937 IsFrameworkActivity(childActivity))
938 allActivities.Add(childActivity);
940 return allActivities;
942 public static bool IsFrameworkActivity(Activity activity)
944 return (activity is CancellationHandlerActivity ||
945 activity is CompensationHandlerActivity ||
946 activity is FaultHandlersActivity);
949 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
950 internal static MethodInfo GetInterfaceMethod(Type interfaceType, string methodName)
952 MethodInfo methodInfo = null;
953 string interfaceName = String.Empty;
954 string method = String.Empty;
956 if (methodName.LastIndexOf('.') > 0)
958 interfaceName = methodName.Substring(0, methodName.LastIndexOf('.'));
959 method = methodName.Substring(methodName.LastIndexOf('.') + 1);
962 if (!String.IsNullOrEmpty(interfaceName))
964 foreach (Type inheritedInterface in interfaceType.GetInterfaces())
966 if (String.Compare(inheritedInterface.FullName, interfaceName, StringComparison.Ordinal) == 0)
968 methodInfo = inheritedInterface.GetMethod(method);
975 methodInfo = interfaceType.GetMethod(methodName);
981 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
982 internal static XmlWriter CreateXmlWriter(object output)
984 XmlWriterSettings settings = new XmlWriterSettings();
985 settings.Indent = true;
986 settings.IndentChars = ("\t");
987 settings.OmitXmlDeclaration = true;
988 settings.CloseOutput = true;
990 if (output is string)
991 return XmlWriter.Create(output as string, settings);
992 else if (output is TextWriter)
993 return XmlWriter.Create(output as TextWriter, settings);
996 Debug.Assert(false, "Invalid argument type. 'output' must either be string or TextWriter.");
1001 #region DesignTimeType Support
1002 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
1003 internal static string GetDesignTimeTypeName(object owner, object key)
1005 string typeName = null;
1006 DependencyObject dependencyObject = owner as DependencyObject;
1007 if (dependencyObject != null && key != null)
1009 if (dependencyObject.UserData.Contains(UserDataKeys.DesignTimeTypeNames))
1011 Hashtable typeNames = dependencyObject.UserData[UserDataKeys.DesignTimeTypeNames] as Hashtable;
1012 if (typeNames != null && typeNames.ContainsKey(key))
1013 typeName = typeNames[key] as string;
1019 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
1020 internal static void SetDesignTimeTypeName(object owner, object key, string value)
1022 DependencyObject dependencyObject = owner as DependencyObject;
1023 if (dependencyObject != null && key != null)
1025 if (!dependencyObject.UserData.Contains(UserDataKeys.DesignTimeTypeNames))
1026 dependencyObject.UserData[UserDataKeys.DesignTimeTypeNames] = new Hashtable();
1028 Hashtable typeNames = dependencyObject.UserData[UserDataKeys.DesignTimeTypeNames] as Hashtable;
1029 typeNames[key] = value;
1034 #region Helpers from ExecutableCompModHelpers
1035 // This only works for composite activity.
1036 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
1037 internal static bool IsCustomActivity(CompositeActivity compositeActivity)
1039 if (compositeActivity == null)
1040 throw new ArgumentNullException("compositeActivity");
1042 if (compositeActivity.UserData.Contains(UserDataKeys.CustomActivity))
1044 return (bool)(compositeActivity.UserData[UserDataKeys.CustomActivity]);
1050 CompositeActivity activity = Activator.CreateInstance(compositeActivity.GetType()) as CompositeActivity;
1051 if (activity != null && activity.Activities.Count > 0)
1053 compositeActivity.UserData[UserDataKeys.CustomActivityDefaultName] = activity.Name;
1054 compositeActivity.UserData[UserDataKeys.CustomActivity] = true; //
1064 compositeActivity.UserData[UserDataKeys.CustomActivity] = false; //
1068 [SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison", Justification = "IndexOf(\".\") not a security issue.")]
1069 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
1070 internal static Activity ParseActivity(Activity parsingContext, string activityName)
1072 if (parsingContext == null)
1073 throw new ArgumentNullException("parsingContext");
1074 if (activityName == null)
1075 throw new ArgumentNullException("activityName");
1077 string currentAtivityName = activityName;
1078 string nextActivityName = string.Empty;
1079 int indexOfDot = activityName.IndexOf(".");
1080 if (indexOfDot != -1)
1082 currentAtivityName = activityName.Substring(0, indexOfDot);
1083 nextActivityName = activityName.Substring(indexOfDot + 1);
1084 if (nextActivityName.Length == 0)
1088 Activity currentActivity = GetActivity(parsingContext, currentAtivityName);
1089 if (currentActivity != null)
1091 if (nextActivityName.Length > 0)
1093 if (!(currentActivity is CompositeActivity) || !IsCustomActivity(currentActivity as CompositeActivity))
1094 // current activity must be a custom activity, otherwise there should be no dots in the name.
1097 string[] names = nextActivityName.Split('.');
1098 for (int i = 0; i < names.Length; i++)
1100 Activity nextActivity = GetActivity(currentActivity, names[i]);
1101 if (nextActivity == null || !Helpers.IsActivityLocked(nextActivity))
1104 CompositeActivity declaringActivity = GetDeclaringActivity(nextActivity);
1105 if (currentActivity != declaringActivity)
1108 currentActivity = nextActivity;
1111 return currentActivity;
1115 // This activity should always be unlocked, unless if GetChildActivity() is called from
1116 // within the custom activity's companion class, then we don't have the full qualified ID available
1117 // at that time. We allow this to succeed only if the declaring activity is the same as the declaring
1118 // activity of the context activity passed in.
1119 if (Helpers.IsActivityLocked(currentActivity))//.IsLocked)
1121 if (!IsDeclaringActivityMatchesContext(currentActivity, parsingContext))
1125 return currentActivity;
1132 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
1133 internal static Activity ParseActivityForBind(Activity context, string activityName)
1135 if (context == null)
1136 throw new ArgumentNullException("context");
1137 if (activityName == null)
1138 throw new ArgumentNullException("activityName");
1140 if (string.Equals(activityName, "/Self", StringComparison.Ordinal))
1144 else if (activityName.StartsWith("/Parent", StringComparison.OrdinalIgnoreCase))
1146 Activity activity = context;
1147 string[] paths = activityName.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
1148 for (int i = 0; i < paths.Length && activity != null; i++)
1150 string parent = paths[i].Trim();
1151 activity = (string.Equals(parent, "Parent", StringComparison.OrdinalIgnoreCase)) ? activity.Parent : null;
1155 else if (Helpers.IsActivityLocked(context))
1157 // Look for the matching activity inside the custom activity context first. This is because if a bind
1158 // is coming from a custom activity, it's activity ref ID may not match the qualified ID of the
1160 Activity activity = null;
1161 Activity declaringActivity = Helpers.GetDeclaringActivity(context);
1162 Guid currentContextGuid = GetRuntimeContextGuid(context);
1163 Guid declaringContextGuid = GetRuntimeContextGuid(declaringActivity);
1165 Activity currentContextActivity = context;
1166 Activity parentContextActivity = context.Parent;
1167 Guid parentContextGuid = GetRuntimeContextGuid(parentContextActivity);
1168 while (activity == null && declaringContextGuid != currentContextGuid)
1170 // WinOE Bug 17931: if the context id is different, it means that this activity is running in a child context (such as
1171 // the children of a replicator or a while). we need to resolve the activity within the child context
1172 // first. If we go up to the declaring activity, we'd be finding children of the template instead of
1173 // the actual running instance.
1174 while (parentContextActivity != null && parentContextGuid == currentContextGuid)
1176 currentContextActivity = parentContextActivity;
1177 parentContextActivity = parentContextActivity.Parent;
1178 parentContextGuid = GetRuntimeContextGuid(parentContextActivity);
1181 activity = Helpers.ParseActivity(currentContextActivity, activityName);
1182 currentContextGuid = parentContextGuid;
1185 if (activity == null)
1187 // Check the declaring activity
1188 activity = Helpers.ParseActivity(declaringActivity, activityName);
1191 // Nothing found, let's see if this is bind to the custom activity itself.
1192 if (activity == null)
1194 if (!declaringActivity.UserData.Contains(UserDataKeys.CustomActivityDefaultName))
1196 //we need to activate a new instance of the declaringActivity's type and check if its name equals to the one we are looking for
1197 Activity newCustomActivity = Activator.CreateInstance(declaringActivity.GetType()) as Activity;
1198 declaringActivity.UserData[UserDataKeys.CustomActivityDefaultName] = newCustomActivity.Name;
1201 if (((string)declaringActivity.UserData[UserDataKeys.CustomActivityDefaultName]) == activityName)
1202 activity = declaringActivity;
1205 // if this is a locked activity, its bind reference must be within its declaring activity. We should not try
1206 // to resolve it beyond that scope.
1210 Activity targetActivity = null;
1211 Activity parentActivity = context;
1213 //if it's a custom activity and it has parent, start looking for the target activity at the parent level
1214 //otherwise we'll get children of the custom activity
1215 bool mayLookInside = false; //we may look inside the custom activity if the target is not found outside
1216 CompositeActivity compositeParentActivity = parentActivity as CompositeActivity;
1217 if (compositeParentActivity != null && parentActivity.Parent != null && IsCustomActivity(compositeParentActivity))
1219 mayLookInside = true;
1220 parentActivity = parentActivity.Parent;
1223 while (targetActivity == null && parentActivity != null)
1225 targetActivity = parentActivity.GetActivityByName(activityName, true);
1226 parentActivity = parentActivity.Parent;
1229 if (mayLookInside && targetActivity == null)
1231 //if we have not found an appropriate activity at the parent level, try looking inside
1232 //we dont need to look outside (loop while parent is not null) - it has already been done above
1233 parentActivity = context;
1234 targetActivity = parentActivity.GetActivityByName(activityName, true);
1238 return (targetActivity == null) ? Helpers.ParseActivity(Helpers.GetRootActivity(context), activityName) : targetActivity;
1241 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
1242 private static Guid GetRuntimeContextGuid(Activity currentActivity)
1244 Activity contextActivity = currentActivity;
1245 Guid contextGuid = (Guid)contextActivity.GetValue(Activity.ActivityContextGuidProperty);
1246 while (contextGuid == Guid.Empty && contextActivity.Parent != null)
1248 contextActivity = contextActivity.Parent;
1249 contextGuid = (Guid)contextActivity.GetValue(Activity.ActivityContextGuidProperty);
1254 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
1255 private static bool IsDeclaringActivityMatchesContext(Activity currentActivity, Activity context)
1257 CompositeActivity declaringContext = context as CompositeActivity;
1259 CompositeActivity declaringActivityOfCurrent = Helpers.GetDeclaringActivity(currentActivity);
1261 // If the context activity is locked and it is a primitive activity
1262 // or NOT a custom activity then we need to find its enclosing
1264 if (Helpers.IsActivityLocked(context) &&
1265 (declaringContext == null || !Helpers.IsCustomActivity(declaringContext))
1267 declaringContext = Helpers.GetDeclaringActivity(context);
1269 if (declaringContext == declaringActivityOfCurrent)
1275 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
1276 internal static bool IsAlternateFlowActivity(Activity activity)
1278 if (activity == null)
1281 bool isAlternateFlowActivityAttribute = false;
1282 //dont want to use reflection to check for the alternate flow attribute
1283 //this is a fix for a perf issue - use of reflection in a ui loop
1284 if (!activity.UserData.Contains(typeof(AlternateFlowActivityAttribute)))
1286 isAlternateFlowActivityAttribute = activity.GetType().GetCustomAttributes(typeof(AlternateFlowActivityAttribute), true).Length != 0;
1287 activity.UserData[typeof(AlternateFlowActivityAttribute)] = isAlternateFlowActivityAttribute;
1291 isAlternateFlowActivityAttribute = (bool)activity.UserData[typeof(AlternateFlowActivityAttribute)];
1294 return isAlternateFlowActivityAttribute;
1297 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
1298 private static Activity GetActivity(Activity containerActivity, string id)
1300 if (containerActivity != null)
1302 Queue activities = new Queue();
1303 activities.Enqueue(containerActivity);
1304 while (activities.Count > 0)
1306 Activity activity = (Activity)activities.Dequeue();
1307 if (activity.Enabled)
1309 if (activity.Name == id)
1312 if (activity is CompositeActivity)
1314 foreach (Activity child in ((CompositeActivity)activity).Activities)
1315 activities.Enqueue(child);
1326 #region Class TypeDescriptorContext (SHARED WITH ACTIVITIES, ORCHESTRATIONDESIGNER)
1327 [SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses",
1328 Justification = "Not all assemblies that include this file instantiate the class.")]
1329 internal sealed class TypeDescriptorContext : ITypeDescriptorContext
1331 private IServiceProvider serviceProvider;
1332 private PropertyDescriptor propDesc;
1333 private object instance;
1335 public TypeDescriptorContext(IServiceProvider serviceProvider, PropertyDescriptor propDesc, object instance)
1337 this.serviceProvider = serviceProvider;
1338 this.propDesc = propDesc;
1339 this.instance = instance;
1342 public IContainer Container
1346 return (IContainer)this.serviceProvider.GetService(typeof(IContainer));
1349 public object Instance
1353 return this.instance;
1356 public PropertyDescriptor PropertyDescriptor
1360 return this.propDesc;
1363 public object GetService(Type serviceType)
1365 return this.serviceProvider.GetService(serviceType);
1368 public bool OnComponentChanging()
1370 IComponentChangeService componentChangeService = (IComponentChangeService)this.serviceProvider.GetService(typeof(IComponentChangeService));
1371 if (componentChangeService != null)
1375 componentChangeService.OnComponentChanging(this.instance, this.propDesc);
1377 catch (CheckoutException ce)
1379 if (ce == CheckoutException.Canceled)
1387 public void OnComponentChanged()
1389 IComponentChangeService componentChangeService = (IComponentChangeService)this.serviceProvider.GetService(typeof(IComponentChangeService));
1390 if (componentChangeService != null)
1391 componentChangeService.OnComponentChanged(this.instance, this.propDesc, null, null);
1396 // This class has been added as a fix for bug 18214 in order to
1397 // create an independent code-path for debugger's use of ParseActivity functionality.
1398 // The GetActivity method of this class uses QualifiedName instead of Name property
1399 // for finding activities.
1400 internal static class DebuggerHelpers
1402 [SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison", Justification = "IndexOf(\".\") not a security issue.")]
1403 internal static Activity ParseActivity(Activity parsingContext, string activityName)
1405 if (parsingContext == null)
1406 throw new ArgumentNullException("parsingContext");
1407 if (activityName == null)
1408 throw new ArgumentNullException("activityName");
1410 string currentAtivityName = activityName;
1411 string nextActivityName = string.Empty;
1412 int indexOfDot = activityName.IndexOf(".");
1413 if (indexOfDot != -1)
1415 currentAtivityName = activityName.Substring(0, indexOfDot);
1416 nextActivityName = activityName.Substring(indexOfDot + 1);
1417 if (nextActivityName.Length == 0)
1421 Activity currentActivity = null;
1422 currentActivity = GetActivity(parsingContext, currentAtivityName);
1424 // The check for parsingContext.Parent != null is added here because IsCustomActivity returns true for root activities.
1425 if (currentActivity == null && (parsingContext is CompositeActivity) && parsingContext.Parent != null && Helpers.IsCustomActivity(parsingContext as CompositeActivity))
1426 currentActivity = GetActivity(parsingContext, parsingContext.QualifiedName + "." + currentAtivityName);
1428 if (currentActivity != null)
1430 if (nextActivityName.Length > 0)
1432 if (!(currentActivity is CompositeActivity) || !Helpers.IsCustomActivity(currentActivity as CompositeActivity))
1433 // current activity must be a custom activity, otherwise there should be no dots in the name.
1436 string[] names = nextActivityName.Split('.');
1437 for (int i = 0; i < names.Length; i++)
1439 Activity nextActivity = GetActivity(currentActivity, currentActivity.QualifiedName + "." + names[i]);
1440 if (nextActivity == null || !Helpers.IsActivityLocked(nextActivity))
1443 CompositeActivity declaringActivity = Helpers.GetDeclaringActivity(nextActivity);
1444 if (currentActivity != declaringActivity)
1447 currentActivity = nextActivity;
1450 return currentActivity;
1454 // This activity should always be unlocked, unless if GetChildActivity() is called from
1455 // within the custom activity's companion class, then we don't have the full qualified ID available
1456 // at that time. We allow this to succeed only if the declaring activity is the same as the declaring
1457 // activity of the context activity passed in.
1458 if (Helpers.IsActivityLocked(currentActivity))//.IsLocked)
1460 if (!IsDeclaringActivityMatchesContext(currentActivity, parsingContext))
1464 return currentActivity;
1471 private static Activity GetActivity(Activity containerActivity, string id)
1473 if (containerActivity != null)
1475 Queue activities = new Queue();
1476 activities.Enqueue(containerActivity);
1477 while (activities.Count > 0)
1479 Activity activity = (Activity)activities.Dequeue();
1480 if (activity.Enabled)
1482 if (activity.QualifiedName == id)
1485 if (activity is CompositeActivity)
1487 foreach (Activity child in ((CompositeActivity)activity).Activities)
1488 activities.Enqueue(child);
1496 private static bool IsDeclaringActivityMatchesContext(Activity currentActivity, Activity context)
1498 CompositeActivity declaringContext = context as CompositeActivity;
1500 CompositeActivity declaringActivityOfCurrent = Helpers.GetDeclaringActivity(currentActivity);
1502 // If the context activity is locked and it is a primitive activity
1503 // or NOT a custom activity then we need to find its enclosing
1505 if (Helpers.IsActivityLocked(context) &&
1506 (declaringContext == null || !Helpers.IsCustomActivity(declaringContext))
1508 declaringContext = Helpers.GetDeclaringActivity(context);
1510 if (declaringContext == declaringActivityOfCurrent)