Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / AddIn / AddIn / System / Addin / Hosting / InspectionWorker.cs / 1305376 / InspectionWorker.cs
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; using System.Security; using System.Security.Permissions; using System.Text; using System.Threading; using System.AddIn.MiniReflection; using System.AddIn.Pipeline; using System.AddIn; using System.Diagnostics.Contracts; namespace System.AddIn.Hosting { [Serializable] internal struct InspectionResults { internal ListComponents; internal Collection Warnings; } internal sealed class InspectionWorker : MarshalByRefObject { private String _assemblyFileName; private String _pipelineRootDirectory; private PipelineComponentType _currentComponentType; private static Assembly SystemAddInInReflectionOnlyContext; private static Assembly SystemAddInContractsInReflectionOnlyContext; [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline", Justification="Initialization needs to be done in this order")] static InspectionWorker() { // Since we're using Reflection-only LoadFrom, we must pre-load // dependent assemblies, such as System.AddIn.dll (this assembly). SystemAddInInReflectionOnlyContext = Assembly.ReflectionOnlyLoad(typeof(AddInStore).Assembly.FullName); SystemAddInContractsInReflectionOnlyContext = Assembly.ReflectionOnlyLoad(typeof(System.AddIn.Contract.IContract).Assembly.FullName); PipelineComponent.SetTypesFromReflectionLoaderContext(SystemAddInInReflectionOnlyContext, SystemAddInContractsInReflectionOnlyContext); } // Soon, this assembly resolve event won't be used during inspection. // But we'll need this exact same code during activation. internal Assembly ResolveAssembly(Object sender, ResolveEventArgs args) { String assemblyRef = args.Name; // I need to look in both the directory structure on disk for add-in // pipeline components, as well as in the GAC for assemblies like // System.dll, which I haven't pre-loaded into the ReflectionOnly // loader context. // LoadFrom respects publisher policy, but ReflectionOnlyLoadFrom doesn't, // but that's OK. // Do I have to look in the GAC _first_ to mimic behavior // at runtime, which would respect policy when calling LoadFrom? // The problem with that is I'll be looking in the GAC for assemblies // that won't exist some portion of the time, meaning we have // to throw and ---- FileNotFoundExceptions. The debugging experience // and performance are horrible. String simpleName = assemblyRef.Substring(0, assemblyRef.IndexOf(',')); if (String.Equals(simpleName, "System.AddIn")) return SystemAddInInReflectionOnlyContext; if (String.Equals(simpleName, "System.AddIn.Contract")) return SystemAddInContractsInReflectionOnlyContext; String rootDir = Path.GetDirectoryName(Path.GetDirectoryName(_assemblyFileName)); if (_currentComponentType == PipelineComponentType.AddIn) rootDir = Path.GetDirectoryName(rootDir); List dirsToLookIn = new List (); switch(_currentComponentType) { case PipelineComponentType.HostAdapter: // Look in contract directory. For loading the HAV, // we can't do that at discovery time since we don't know // which directory contains the HAV. This is why we're // writing our own metadata parser in managed code. // At activation time, the HAV should already be loaded // within the host's AppDomain. dirsToLookIn.Add(Path.Combine(rootDir, AddInStore.ContractsDirName)); break; case PipelineComponentType.Contract: break; case PipelineComponentType.AddInAdapter: // Look in contract directory and addin base directory. dirsToLookIn.Add(Path.Combine(rootDir, AddInStore.ContractsDirName)); dirsToLookIn.Add(Path.Combine(rootDir, AddInStore.AddInBasesDirName)); break; case PipelineComponentType.AddInBase: // look for other assemblies in the same folder dirsToLookIn.Add(Path.Combine(rootDir, AddInStore.AddInBasesDirName)); // @ break; /* case PipelineComponentType.AddIn: // Look in both the add-in's directory and the add-in base's // directory. We do the first by setting the app base for the AppDomain, // but we may not be able to do that if the user created the appdomain. dirsToLookIn.Add(Path.Combine(rootDir, AddInBasesDirName)); dirsToLookIn.Add(Path.GetDirectoryName(_assemblyFileName)); break; */ default: System.Diagnostics.Contracts.Contract.Assert(false, "Fell through switch in the inspection assembly resolve event!"); break; } List potentialFileNames = new List (dirsToLookIn.Count * 2); foreach (String path in dirsToLookIn) { String simpleFileName = Path.Combine(path, simpleName); String dllName = simpleFileName + ".dll"; if (File.Exists(dllName)) potentialFileNames.Add(dllName); else if (File.Exists(simpleFileName + ".exe")) potentialFileNames.Add(simpleFileName + ".exe"); } foreach (String fileName in potentialFileNames) { try { Assembly a = Assembly.ReflectionOnlyLoadFrom(fileName); // We should at least be comparing the public key token // for the two assemblies here. The version numbers may // potentially be different, dependent on publisher policy. if (Utils.AssemblyRefEqualsDef(assemblyRef, a.FullName)) return a; } catch (BadImageFormatException) { } } // Look in the GAC. It may not be there, so we need to catch // FileNotFoundException. // As an optimization, don't probe in the GAC if the public // key token is null, because by definition the assembly // can't be in the GAC. if (!assemblyRef.Contains("PublicKeyToken=null")) { try { return Assembly.ReflectionOnlyLoad(assemblyRef); } catch (FileNotFoundException) {} try { // As a final effort, look in the GAC after appying loader policy. // This lets us resolves references for assemblies built against an older version of the framework. return Assembly.ReflectionOnlyLoad(AppDomain.CurrentDomain.ApplyPolicy(assemblyRef)); } catch (FileNotFoundException) {} } //Console.WriteLine("Couldn't resolve assembly {0} while loading a {1}", simpleName, _currentComponentType); return null; } // Note that Inspect sets state around for the assembly resolve event in a way that isn't currently threadsafe. // // [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification = "Reviewed"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes"), System.Diagnostics.CodeAnalysis.SuppressMessage ("Microsoft.Security", "CA2103:ReviewImperativeSecurity")] [System.Security.SecuritySafeCritical] [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2128:SecurityTransparentCodeShouldNotAssert", Justification = "This is a SecurityRules.Level1 assembly, in which this rule is being incorrectly applied")] internal InspectionResults Inspect(PipelineComponentType componentType, string assemblyFileName, string pipelineRootDirectory) { System.Diagnostics.Contracts.Contract.Requires(assemblyFileName != null); System.Diagnostics.Contracts.Contract.Requires(pipelineRootDirectory != null); _assemblyFileName = assemblyFileName; _pipelineRootDirectory = pipelineRootDirectory; // Set up the assembly resolve event. _currentComponentType = componentType; ResolveEventHandler assemblyResolver = new ResolveEventHandler(ResolveAssembly); AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += assemblyResolver; InspectionResults retval = new InspectionResults(); retval.Components = new List// // (); retval.Warnings = new Collection (); Type[] publicTypes; String assemblyName = null; // Need to assert again here because we are in a new appdomain FileIOPermission permission = new FileIOPermission(FileIOPermissionAccess.PathDiscovery | FileIOPermissionAccess.Read, _pipelineRootDirectory); permission.Assert(); try { // We want to load the assembly WITHOUT REGARD OF PUBLISHER POLICY. // If the directory structure contains v1.0 of a component and v1.1 // exists in the GAC and is a security fix to v1.0, we still want to // inspect v1.0. (The reason is we have other parts of the // pipeline that were likely compiled against v1.0, not v1.1, and // we do type comparisons by comparing the fully qualified assembly // name.) LoadFrom unfortunately respects policy. Assembly's // ReflectionOnlyLoad(byte[]) doesn't. ReflectionOnlyLoadFrom(String) // does respect policy if you've set DEVPATH, but only as a bug. // We don't think setting DEVPATH is interesting. Assembly a = Assembly.ReflectionOnlyLoadFrom(_assemblyFileName); publicTypes = a.GetTypes(); assemblyName = a.FullName; } catch (FileNotFoundException fnf) { retval.Warnings.Add(String.Format(CultureInfo.CurrentCulture, Res.AssemblyLoadFileNotFound, fnf.Message, fnf.FileName)); return retval; } catch (Exception e) { retval.Warnings.Add(String.Format(CultureInfo.CurrentCulture, Res.AssemblyLoadThrew, e.GetType().Name, e.Message, _assemblyFileName)); return retval; } PipelineComponent component = null; String relativeFileName = Utils.MakeRelativePath(_assemblyFileName, _pipelineRootDirectory); Type lastType = null; try { // Iterate over public types, looking for the appropriate custom attributes. foreach (Type type in publicTypes) { component = null; lastType = type; switch (componentType) { case PipelineComponentType.Contract: if (!Utils.HasCustomAttribute(PipelineComponent.ContractAttributeInReflectionLoaderContext, type)) continue; component = new ContractComponent(new TypeInfo(type), relativeFileName); break; case PipelineComponentType.AddInAdapter: if (!Utils.HasCustomAttribute(PipelineComponent.AddInAdapterAttributeInReflectionLoaderContext, type)) continue; component = new AddInAdapter(new TypeInfo(type), relativeFileName); break; case PipelineComponentType.AddInBase: if (Utils.HasCustomAttribute(PipelineComponent.AddInAttributeInReflectionLoaderContext, type)) retval.Warnings.Add(String.Format(CultureInfo.CurrentCulture, Res.AddInInAddInViewFolder, type.Name, _assemblyFileName)); if (!Utils.HasCustomAttribute(PipelineComponent.AddInBaseAttributeInReflectionLoaderContext, type)) continue; TypeInfo[] activatableAs = null; CustomAttributeData cad = Utils.GetCustomAttributeData(PipelineComponent.AddInBaseAttributeInReflectionLoaderContext, type); foreach(CustomAttributeNamedArgument cana in cad.NamedArguments) { if (cana.MemberInfo.Name == "ActivatableAs") { CustomAttributeTypedArgument arg = cana.TypedValue; ReadOnlyCollection types = (ReadOnlyCollection )arg.Value; activatableAs = new TypeInfo[types.Count]; int i = 0; foreach (CustomAttributeTypedArgument subArg in types) { activatableAs[i++] = new TypeInfo((Type)subArg.Value); } } } component = new AddInBase(new TypeInfo(type), activatableAs, relativeFileName, assemblyName); break; default: System.Diagnostics.Contracts.Contract.Assert(false, "Fell through switch - unrecognized componentType in InspectionWorker.Inspect"); break; } // switch // If we found a component, make sure it satisfies all of its constraints, and give our // PipelineComponents a chance to initialize state. if (component != null) { if (component.Validate(type, retval.Warnings)) retval.Components.Add(component); } } // foreach type in the assembly } // try catch (FileNotFoundException fnf) { retval.Warnings.Add(String.Format(CultureInfo.CurrentCulture, Res.AssemblyLoadFileNotFound, fnf.Message, fnf.FileName)); return retval; } catch (NotImplementedException) { retval.Warnings.Add(String.Format(CultureInfo.CurrentCulture, Res.NotImplementedFeatureBadCtorParamOrAssembly, _assemblyFileName, (lastType == null) ? "" : lastType.FullName)); return retval; } catch (Exception e) { retval.Warnings.Add(String.Format(CultureInfo.CurrentCulture, Res.InspectingAssemblyThrew, e.GetType().Name, e.Message, _assemblyFileName)); return retval; } AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve -= assemblyResolver; if (retval.Components.Count == 0 && _currentComponentType != PipelineComponentType.AddIn && _currentComponentType != PipelineComponentType.AddInBase) { retval.Warnings.Add(String.Format(CultureInfo.CurrentCulture, Res.NoAddInModelPartsFound, componentType, _assemblyFileName)); } #if ADDIN_VERBOSE_WARNINGS foreach (PipelineComponent c in retval.Components) retval.Warnings.Add(String.Format(CultureInfo.CurrentCulture, "Found a {0}. Name: {1} Assembly: {2}", componentType, c.SimpleName, c.AssemblySimpleName)); #endif return retval; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- TemplateContentLoader.cs
- WindowsTitleBar.cs
- ProviderSettingsCollection.cs
- ImmutableClientRuntime.cs
- ToolStripTextBox.cs
- DataGridPagerStyle.cs
- TextTreeTextBlock.cs
- WindowsGraphics2.cs
- PrimaryKeyTypeConverter.cs
- TextureBrush.cs
- Token.cs
- xsdvalidator.cs
- DefaultObjectMappingItemCollection.cs
- Crc32.cs
- Dynamic.cs
- RegexGroup.cs
- UriSection.cs
- DockProviderWrapper.cs
- ListComponentEditor.cs
- DynamicRenderer.cs
- QilGenerator.cs
- CommandBinding.cs
- WebDisplayNameAttribute.cs
- IsolationInterop.cs
- BamlTreeMap.cs
- DiscoveryExceptionDictionary.cs
- SafeHandle.cs
- PointCollectionConverter.cs
- WebResourceUtil.cs
- PrintDialogException.cs
- TextEndOfSegment.cs
- SafeArchiveContext.cs
- ScrollData.cs
- RotateTransform3D.cs
- HostedNamedPipeTransportManager.cs
- ParameterCollection.cs
- WebPartDisplayMode.cs
- RestClientProxyHandler.cs
- CalendarTable.cs
- RotateTransform.cs
- XXXInfos.cs
- COSERVERINFO.cs
- ClientUrlResolverWrapper.cs
- QueryExpression.cs
- XmlSchemaAttribute.cs
- CreateParams.cs
- SpecialNameAttribute.cs
- PackUriHelper.cs
- OpacityConverter.cs
- TreeNodeClickEventArgs.cs
- CommonGetThemePartSize.cs
- BufferModeSettings.cs
- XmlCollation.cs
- IsolationInterop.cs
- JavaScriptObjectDeserializer.cs
- BufferedReceiveElement.cs
- UrlMappingsSection.cs
- RSAProtectedConfigurationProvider.cs
- StylusOverProperty.cs
- BasicHttpMessageSecurity.cs
- IPipelineRuntime.cs
- RijndaelManaged.cs
- Scheduling.cs
- VBIdentifierNameEditor.cs
- Action.cs
- ScrollBarAutomationPeer.cs
- ConstrainedDataObject.cs
- SortAction.cs
- Hashtable.cs
- TypeGeneratedEventArgs.cs
- DataGridViewColumn.cs
- ListSortDescription.cs
- MenuItemCollectionEditor.cs
- DCSafeHandle.cs
- BevelBitmapEffect.cs
- LineBreak.cs
- TextRangeProviderWrapper.cs
- ResourceReferenceExpressionConverter.cs
- XmlSerializerOperationBehavior.cs
- FontInfo.cs
- Vector3DCollection.cs
- ButtonChrome.cs
- SvcMapFileLoader.cs
- CompoundFileStreamReference.cs
- Rotation3DAnimationUsingKeyFrames.cs
- TextTreeTextNode.cs
- PrintPreviewDialog.cs
- initElementDictionary.cs
- ImportedPolicyConversionContext.cs
- SslStreamSecurityBindingElement.cs
- IndentedTextWriter.cs
- TypeName.cs
- RectAnimation.cs
- LinkTarget.cs
- ColorConvertedBitmapExtension.cs
- TableRowCollection.cs
- BStrWrapper.cs
- StoreAnnotationsMap.cs
- DataTableTypeConverter.cs
- filewebresponse.cs