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
- ContentElement.cs
- mediaeventargs.cs
- SubMenuStyleCollectionEditor.cs
- CodeSnippetCompileUnit.cs
- RSACryptoServiceProvider.cs
- ContextBase.cs
- _HelperAsyncResults.cs
- ScriptControl.cs
- DoubleKeyFrameCollection.cs
- OutputScopeManager.cs
- ObjectQueryExecutionPlan.cs
- XPathNodeInfoAtom.cs
- HtmlWindow.cs
- XamlBrushSerializer.cs
- StylesEditorDialog.cs
- ButtonBaseDesigner.cs
- XmlWrappingReader.cs
- DataGridViewAccessibleObject.cs
- CommandExpr.cs
- TableLayoutRowStyleCollection.cs
- GridItemCollection.cs
- ArgumentValidation.cs
- XDeferredAxisSource.cs
- Crypto.cs
- PathFigureCollection.cs
- SoapHeaders.cs
- DataObjectMethodAttribute.cs
- DigitShape.cs
- sqlpipe.cs
- ResourceContainer.cs
- PeerApplicationLaunchInfo.cs
- CancelEventArgs.cs
- OdbcConnectionStringbuilder.cs
- RegexMatch.cs
- HttpCookiesSection.cs
- TextUtf8RawTextWriter.cs
- CreateUserWizard.cs
- StringBuilder.cs
- DbExpressionRules.cs
- UnsafeNativeMethods.cs
- FormsAuthenticationUserCollection.cs
- TransportElement.cs
- _UriSyntax.cs
- WebPartDescription.cs
- XmlLanguage.cs
- DefaultTraceListener.cs
- CodeEntryPointMethod.cs
- EnumerableValidator.cs
- controlskin.cs
- ISFTagAndGuidCache.cs
- DesignTable.cs
- BufferedGraphicsContext.cs
- URI.cs
- SqlPersonalizationProvider.cs
- DocumentViewerAutomationPeer.cs
- TryExpression.cs
- DocumentPageViewAutomationPeer.cs
- InvokerUtil.cs
- _TimerThread.cs
- SByte.cs
- InkCanvasInnerCanvas.cs
- Context.cs
- IndexerNameAttribute.cs
- BindingsSection.cs
- SettingsPropertyValue.cs
- WinEventQueueItem.cs
- ReadOnlyTernaryTree.cs
- QilUnary.cs
- ListViewGroupItemCollection.cs
- ConstraintStruct.cs
- DataControlImageButton.cs
- HierarchicalDataTemplate.cs
- ItemCollection.cs
- DataContractSet.cs
- SiteMapHierarchicalDataSourceView.cs
- LoadedEvent.cs
- TextParagraphProperties.cs
- SecurityImpersonationBehavior.cs
- ConnectionManagementSection.cs
- DescendentsWalkerBase.cs
- SelectedGridItemChangedEvent.cs
- ParserHooks.cs
- Context.cs
- CopyOfAction.cs
- SqlComparer.cs
- GcSettings.cs
- CompilationSection.cs
- DesignTimeTemplateParser.cs
- WebPartExportVerb.cs
- ContractListAdapter.cs
- SQLBytes.cs
- SemaphoreSecurity.cs
- EventKeyword.cs
- DecoderFallback.cs
- ItemsPanelTemplate.cs
- DataKey.cs
- SerializeAbsoluteContext.cs
- PropertyCollection.cs
- DPTypeDescriptorContext.cs
- DbExpressionRules.cs