Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / AddIn / AddIn / System / Addin / Hosting / ActivationWorker.cs / 1305376 / ActivationWorker.cs
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== /*============================================================ ** ** Class: ActivationWorker ** ** Purpose: Created in the remote AppDomain, this worker is ** used to start up & shut down the add-in. ** ===========================================================*/ using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Security; using System.Security.Permissions; using System.Diagnostics.Contracts; namespace System.AddIn.Hosting { internal sealed class ActivationWorker : MarshalByRefObject, IDisposable { private AddInToken _pipeline; private ResolveEventHandler _assemblyResolver; private PipelineComponentType _currentComponentType; private bool _usingHostAppDomain; internal ActivationWorker(AddInToken pipeline) { System.Diagnostics.Contracts.Contract.Requires(pipeline != null); System.Diagnostics.Contracts.Contract.Requires(pipeline.PipelineRootDirectory != null); _pipeline = pipeline; } //// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification="Reviewed")] [System.Security.SecuritySafeCritical] public void Dispose() { if (_assemblyResolver != null) { AppDomain.CurrentDomain.AssemblyResolve -= _assemblyResolver; _assemblyResolver = null; } } // Don't let this object time out in Remoting. We need this object to be // alive until we clean up the appdomain, and we want to unhook our assembly // resolve event. public override Object InitializeLifetimeService() { return null; } internal bool UsingHostAppDomain { set { _usingHostAppDomain = value; } } // This method should return System.AddIn.Contract.IContract, instead of Object. This gives // Remoting half a chance at setting up the transparent proxy to contain // the appropriate interface method table. Then, hopefully Reflection // is built to check that interface method table first. (hopefully.) //// // [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2103:ReviewImperativeSecurity", Justification="Reviewed"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification="Reviewed"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods", MessageId = "System.Reflection.Assembly.LoadFrom", Justification="LoadFrom was explicitly designed for addin loading")] [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2128:SecurityTransparentCodeShouldNotAssert", Justification = "This is a SecurityRules.Level1 assembly, in which this rule is being incorrectly applied")] [System.Security.SecuritySafeCritical] internal System.AddIn.Contract.IContract Activate() { // Assert permission to the contracts, AddInSideAdapters, AddInViews and specific Addin directories only. PermissionSet permissionSet = new PermissionSet(PermissionState.None); permissionSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.Read | FileIOPermissionAccess.PathDiscovery, Path.Combine(_pipeline.PipelineRootDirectory, AddInStore.ContractsDirName))); permissionSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.Read | FileIOPermissionAccess.PathDiscovery, Path.Combine(_pipeline.PipelineRootDirectory, AddInStore.AddInAdaptersDirName))); permissionSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.Read | FileIOPermissionAccess.PathDiscovery, Path.Combine(_pipeline.PipelineRootDirectory, AddInStore.AddInBasesDirName))); permissionSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.Read | FileIOPermissionAccess.PathDiscovery, Path.GetDirectoryName(_pipeline._addin.Location))); permissionSet.Assert(); // Let's be very deliberate about loading precisely the components we want, // instead of relying on an assembly resolve event. We may still need the // resolve event, but let's ensure we load the right files from the right // places in the right loader contexts. Assembly.LoadFrom(_pipeline._contract.Location); // only load the AddInBase in the LoadFrom context if there is no copy // of the assembly loaded already in the Load context. Otherwise there would be an InvalidCastException // when returning it to the host in the single appdomain, non direct-connect scenario, when // the HVA assembly is also used as the AddInBase assembly. // Since the reflection call to determine whether the assembly is loaded is expensive, only // do it when we are in the single-appdomain scenario. bool alreadyPresent = false; if (_usingHostAppDomain) alreadyPresent = IsAssemblyLoaded(_pipeline._addinBase._assemblyName); if (!alreadyPresent) Assembly.LoadFrom(_pipeline._addinBase.Location); Assembly addInAssembly = Assembly.LoadFrom(_pipeline._addin.Location); Assembly addinAdapterAssembly = Assembly.LoadFrom(_pipeline._addinAdapter.Location); CodeAccessPermission.RevertAssert(); // Create instances of all the interesting objects. // Either we don't need this here, or it may need to exist for the duration of // the add-in's lifetime. // // The assembly resolve event will be removed when the addin // controller's Shutdown method is run. _assemblyResolver = new ResolveEventHandler(ResolveAssembly); AppDomain.CurrentDomain.AssemblyResolve += _assemblyResolver; // Create the AddIn _currentComponentType = PipelineComponentType.AddIn; Type addinType = addInAssembly.GetType(_pipeline._addin.TypeInfo.FullName, true); Object addIn = addinType.GetConstructor(new Type[0]).Invoke(new Object[0]); System.Diagnostics.Contracts.Contract.Assert(addIn != null, "CreateInstance didn't create the add-in"); return CreateAddInAdapter(addIn, addinAdapterAssembly); } // Return true if the assembly of the given name has already been loaded, perhaps // from a different path. [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")] private static bool IsAssemblyLoaded(String assemblyName) { // Since there is no managed API for finding the GAC path, I // assert path discovery for all local files. FileIOPermission permission = new FileIOPermission(PermissionState.None); permission.AllLocalFiles = FileIOPermissionAccess.PathDiscovery; permission.Assert(); foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) { if (assembly.FullName.Equals(assemblyName, StringComparison.OrdinalIgnoreCase)) { return true; } // Warn if they have the same assembly with different versions. If we don't do this, // they will get an InvalidCastException instead. AssemblyName name1 = new AssemblyName(assemblyName); AssemblyName name2 = assembly.GetName(); if (name1.Name == name2.Name && name1.CultureInfo.Equals(name2.CultureInfo) && Utils.PublicKeyMatches(name1, name2) && name1.Version != name2.Version) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, Res.IncompatibleAddInBaseAssembly, assemblyName)); } } return false; } //// // // [System.Security.SecuritySafeCritical] internal System.AddIn.Contract.IContract CreateAddInAdapter(Object addIn, Assembly addinAdapterAssembly) { System.Diagnostics.Contracts.Contract.Ensures(System.Diagnostics.Contracts.Contract.Result// () != null); // Create the AddIn Adapter System.AddIn.Contract.IContract addInAdapter = null; _currentComponentType = PipelineComponentType.AddInAdapter; Type adapterType = addinAdapterAssembly.GetType(_pipeline._addinAdapter.TypeInfo.FullName, true); Type addInBaseType = Type.GetType(_pipeline._addinBase.TypeInfo.AssemblyQualifiedName, true); AddInActivator.InvokerDelegate myInvokerDelegate = AddInActivator.CreateConsInvoker(adapterType, addIn.GetType()); addInAdapter = (System.AddIn.Contract.IContract)myInvokerDelegate(addIn); System.Diagnostics.Contracts.Contract.Assert(addInAdapter != null, "CreateInstance didn't create the add-in adapter"); return addInAdapter; } // This is necessary if an add-in or an add-in adapter depends on other // assemblies within the same directory. // // [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 Assembly ResolveAssembly(Object sender, ResolveEventArgs args) { System.Diagnostics.Contracts.Contract.Assert(_pipeline != null); String assemblyRef = args.Name; //Console.WriteLine("ResolveAssembly (in add-in's AD) called for {0}", assemblyRef); // Two purposes here: // 1) Ensure that our already-loaded pipeline components get upgraded // from the LoadFrom context to the default loader context. // 2) Any dependencies of our already-loaded pipeline components would // have been loaded in the LoadFrom context, and need to also be // manually upgraded to the default loader context. // We can do both of the above by calling LoadFrom on the appropriate // assemblies on disk, or by walking the list of already-loaded // assemblies, looking for the ones we need to upgrade. // Since we'll have multiple add-ins in the same AD, it may make the // most sense to simply look for an already-loaded assembly instead of // looking in directories on disk, to avoid conflicts. // Check to see if this assembly was already loaded in the // LoadFrom context. If so, upgrade it. Assembly a = Utils.FindLoadedAssemblyRef(assemblyRef); if (a != null) return a; // It wasn't found in memory, so look on disk String rootDir = _pipeline.PipelineRootDirectory; List// dirsToLookIn = new List (); switch (_currentComponentType) { 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.AddIn: dirsToLookIn.Add(Path.Combine(rootDir, AddInStore.AddInBasesDirName)); break; default: System.Diagnostics.Contracts.Contract.Assert(false); throw new InvalidOperationException("Fell through switch in assembly resolve event!"); } // ARROWHEAD START // In the LoadFrom context, assemblies we depend on in the same folder are loaded automatically. // We don't have that behavior in Arrowhead. //String addinFolder = Path.GetDirectoryName(_pipeline._addin.Location); //dirsToLookIn.Add(addinFolder); // ARROWHEAD END // Assert permission to read from addinBase folder (and maybe contracts folder). PermissionSet permissionSet = new PermissionSet(PermissionState.None); foreach (string dir in dirsToLookIn) { permissionSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.Read | FileIOPermissionAccess.PathDiscovery, dir)); } permissionSet.Assert(); return Utils.LoadAssemblyFrom(dirsToLookIn, assemblyRef); //Console.WriteLine("Couldn't resolve assembly {0} while loading a {1}", simpleName, _currentComponentType); } } } // 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
- LayoutUtils.cs
- SchemaTableColumn.cs
- FragmentQuery.cs
- CodeGotoStatement.cs
- PerformanceCounterPermission.cs
- SmiContext.cs
- FormatterServices.cs
- ParserStreamGeometryContext.cs
- DataGridCellClipboardEventArgs.cs
- LinqDataSource.cs
- XmlWrappingWriter.cs
- HostVisual.cs
- MouseButtonEventArgs.cs
- DataGridViewComboBoxColumn.cs
- IntAverageAggregationOperator.cs
- TdsValueSetter.cs
- GeneralTransform3DGroup.cs
- EntityObject.cs
- EntitySqlQueryBuilder.cs
- WinEventQueueItem.cs
- UnsafeNativeMethods.cs
- HostedBindingBehavior.cs
- WebPartMenuStyle.cs
- XmlSchemaAttribute.cs
- ArglessEventHandlerProxy.cs
- UntypedNullExpression.cs
- VariableAction.cs
- RemoteWebConfigurationHostServer.cs
- DataGridTextBox.cs
- IncrementalReadDecoders.cs
- SourceSwitch.cs
- TextTreeDeleteContentUndoUnit.cs
- ButtonField.cs
- GPStream.cs
- DBConcurrencyException.cs
- PersonalizationEntry.cs
- MailAddress.cs
- Debug.cs
- RegisteredArrayDeclaration.cs
- EditorPartCollection.cs
- NotFiniteNumberException.cs
- CodeRegionDirective.cs
- HiddenField.cs
- DesignRelation.cs
- BamlLocalizabilityResolver.cs
- ReflectionUtil.cs
- AuthenticateEventArgs.cs
- ListParagraph.cs
- Ref.cs
- ToolStripSeparator.cs
- DeferredElementTreeState.cs
- SoapIgnoreAttribute.cs
- LayoutSettings.cs
- WebConfigurationManager.cs
- RelationshipConverter.cs
- Enum.cs
- Merger.cs
- SafeNativeMethodsCLR.cs
- TrustLevelCollection.cs
- MultiView.cs
- DataGridViewRowConverter.cs
- BaseTransportHeaders.cs
- ContentPosition.cs
- CommonRemoteMemoryBlock.cs
- RegexInterpreter.cs
- LongValidatorAttribute.cs
- StringConcat.cs
- MatrixAnimationUsingKeyFrames.cs
- PageAction.cs
- Number.cs
- NTAccount.cs
- OracleConnectionStringBuilder.cs
- DateTimeStorage.cs
- StrokeCollectionConverter.cs
- DependentList.cs
- SharedRuntimeState.cs
- DesignerInterfaces.cs
- TdsParserStateObject.cs
- ProtectedConfigurationSection.cs
- Margins.cs
- DataRecordInfo.cs
- RemoteArgument.cs
- DataListItemEventArgs.cs
- SpeechAudioFormatInfo.cs
- ServiceOperationInvoker.cs
- DragStartedEventArgs.cs
- ProxyWebPart.cs
- FastEncoder.cs
- ExpressionEditorAttribute.cs
- BaseTemplateCodeDomTreeGenerator.cs
- UnsignedPublishLicense.cs
- EnumValidator.cs
- PagerSettings.cs
- TreeView.cs
- AutoGeneratedFieldProperties.cs
- mda.cs
- Inflater.cs
- ColorConvertedBitmap.cs
- MimeParameter.cs
- NumericUpDown.cs