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
- SignedXml.cs
- TabControlCancelEvent.cs
- CultureTable.cs
- PageRouteHandler.cs
- mediapermission.cs
- _BaseOverlappedAsyncResult.cs
- Rect3DValueSerializer.cs
- Propagator.JoinPropagator.cs
- Boolean.cs
- arabicshape.cs
- TabControlToolboxItem.cs
- XmlQueryType.cs
- DataServiceQueryProvider.cs
- VisualTreeUtils.cs
- storepermission.cs
- SQLDecimal.cs
- HGlobalSafeHandle.cs
- CompilerParameters.cs
- ExpressionQuoter.cs
- DateTimeValueSerializerContext.cs
- CompilerGlobalScopeAttribute.cs
- DataGridViewRowCancelEventArgs.cs
- FillErrorEventArgs.cs
- ItemsControl.cs
- Highlights.cs
- AsyncOperationManager.cs
- NullReferenceException.cs
- SetterBaseCollection.cs
- RtfControls.cs
- Effect.cs
- XmlWellformedWriter.cs
- DataSourceCacheDurationConverter.cs
- RadioButton.cs
- SigningCredentials.cs
- AdPostCacheSubstitution.cs
- DefaultEventAttribute.cs
- RangeContentEnumerator.cs
- SelectionRangeConverter.cs
- FrameworkElement.cs
- CharacterString.cs
- TcpClientSocketManager.cs
- DocumentGridContextMenu.cs
- DocumentsTrace.cs
- DataGridViewColumnHeaderCell.cs
- BitmapMetadataEnumerator.cs
- BufferAllocator.cs
- WebPartTransformerCollection.cs
- SafeEventLogWriteHandle.cs
- _RequestCacheProtocol.cs
- LinqTreeNodeEvaluator.cs
- TraversalRequest.cs
- PaperSource.cs
- OutputCacheProviderCollection.cs
- ALinqExpressionVisitor.cs
- StaticExtensionConverter.cs
- CSharpCodeProvider.cs
- DocumentScope.cs
- WorkerRequest.cs
- WebPartConnectionsCancelVerb.cs
- SqlClientMetaDataCollectionNames.cs
- FamilyTypefaceCollection.cs
- DataGridViewBand.cs
- IFlowDocumentViewer.cs
- ObservableDictionary.cs
- StoryFragments.cs
- TextEditorParagraphs.cs
- AssemblyResourceLoader.cs
- MetadataCollection.cs
- OdbcFactory.cs
- WCFModelStrings.Designer.cs
- _SingleItemRequestCache.cs
- BindingWorker.cs
- ProcessHostServerConfig.cs
- ControlDesignerState.cs
- OptimisticConcurrencyException.cs
- ExpressionTextBox.xaml.cs
- GregorianCalendarHelper.cs
- XmlTextReaderImplHelpers.cs
- GridViewColumnCollection.cs
- SpecularMaterial.cs
- SelectionProcessor.cs
- DesignerForm.cs
- DynamicValidatorEventArgs.cs
- BamlTreeUpdater.cs
- XsltException.cs
- ActivityScheduledRecord.cs
- control.ime.cs
- RequiredArgumentAttribute.cs
- AdCreatedEventArgs.cs
- DataGridHeaderBorder.cs
- AliasGenerator.cs
- CombinedGeometry.cs
- Stroke.cs
- FillBehavior.cs
- SymmetricKeyWrap.cs
- HtmlControl.cs
- VirtualPath.cs
- MdiWindowListStrip.cs
- Visual3D.cs
- QueryAccessibilityHelpEvent.cs