internal IContract GetContract() { if (_contract != null) { return(_contract); } // in direct connect, the contract has not been created. Create it now. Object hav = _havReference.Target; if (hav == null) { throw new InvalidOperationException(Res.AddInNoLongerAvailable); } // 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(_token.PipelineRootDirectory, AddInStore.ContractsDirName))); permissionSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.Read | FileIOPermissionAccess.PathDiscovery, Path.Combine(_token.PipelineRootDirectory, AddInStore.AddInAdaptersDirName))); permissionSet.Assert(); Assembly.LoadFrom(_token._contract.Location); Assembly addinAdapterAssembly = Assembly.LoadFrom(_token._addinAdapter.Location); CodeAccessPermission.RevertAssert(); // Create the AddIn adapter for the addin ActivationWorker worker = new ActivationWorker(_token); _contract = worker.CreateAddInAdapter(hav, addinAdapterAssembly); return(_contract); }
public IContract Activate(AddInToken pipeline, out ActivationWorker worker) { worker = new ActivationWorker(pipeline); IContract contract = worker.Activate(); return(contract); }
public void Shutdown() { // Disables usage of the add-in, by breaking the pipeline. // Also, if we own the appdomain, we unload it. lock (this) // Ensure multiple threads racing on Shutdown don't collide. { AddInEnvironment environment = _addInEnvironment; if (environment != null) { try { if (_contract != null) { Object hav = _havReference.Target; IDisposable disposableHAV = hav as IDisposable; if (disposableHAV != null) { try { disposableHAV.Dispose(); } catch (AppDomainUnloadedException e) { Log(e.ToString()); } catch (RemotingException re) { Log(re.ToString()); } catch (SerializationException se) { Log(se.ToString()); } } IDisposable disposableContract = _contract as IDisposable; if (disposableContract != null) { try { disposableContract.Dispose(); } catch (AppDomainUnloadedException e) { Log(e.ToString()); } catch (RemotingException re) { Log(re.ToString()); } catch (SerializationException se) { Log(se.ToString()); } } _contract = null; } if (_activationWorker != null) { // Unhook an assembly resolve event in the target appdomain. // However, if one of the adapters implemented IDisposable and cleaned // up the appropriate lifetime tokens, this appdomain may be unloading // already (we launch another thread to do this, so we are guaranteed // to have a benign race condition). We should catch an // AppDomainUnloadedException here. try { _activationWorker.Dispose(); } catch (AppDomainUnloadedException) { } catch (RemotingException) { } catch (SerializationException) { } _activationWorker = null; } } finally { if (_unloadDomainOnExit) { // AppDomain.Unload will block until we have finalized all // objects within the appdomain. Also, this may already // have been unloaded. try { environment.UnloadAppDomain(); } catch (AppDomainUnloadedException) { } catch (RemotingException) { } // Using the transparent proxy will now cause exceptions, // as managed threads are not allowed to enter this appdomain. } } _addInEnvironment = null; // eagerly remove from list lock (_havLock) { Object addin = _havReference.Target; if (addin != null) FindController(addin, true); } // The perf team recommends doing a GC after a large amount of memory has // been dereferenced. We wait for the finalizers to complete first // becase some references in the addin are not released until finalization. // Also, if an addin is buggy and causes the finalizer thread to hang, // waiting here makes it fail deterministically. System.GC.WaitForPendingFinalizers(); System.GC.Collect(); } // end if domain != null else { throw new InvalidOperationException(Res.AppDomainNull); } } }
internal IContract GetContract() { if (_contract != null) return _contract; // in direct connect, the contract has not been created. Create it now. Object hav = _havReference.Target; if (hav == null) throw new InvalidOperationException(Res.AddInNoLongerAvailable); // 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(_token.PipelineRootDirectory, AddInStore.ContractsDirName))); permissionSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.Read | FileIOPermissionAccess.PathDiscovery, Path.Combine(_token.PipelineRootDirectory, AddInStore.AddInAdaptersDirName))); permissionSet.Assert(); Assembly.LoadFrom(_token._contract.Location); Assembly addinAdapterAssembly = Assembly.LoadFrom(_token._addinAdapter.Location); CodeAccessPermission.RevertAssert(); // Create the AddIn adapter for the addin ActivationWorker worker = new ActivationWorker(_token); _contract = worker.CreateAddInAdapter(hav, addinAdapterAssembly); return _contract; }
public IContract Activate(AddInToken pipeline, out ActivationWorker worker) { worker = new ActivationWorker(pipeline); IContract contract = worker.Activate(); return contract; }
private static T ActivateInAppDomain <T>(AddInToken pipeline, AppDomain domain, AddInControllerImpl controller, bool weOwn) { ContractComponent contract = pipeline._contract; HostAdapter hostAdapter = pipeline._hostAdapter; bool usingHostAppDomain = domain == AppDomain.CurrentDomain; //begin direct connect code if (AddInToken.EnableDirectConnect && !weOwn && usingHostAppDomain) { Type havType = typeof(T); TypeInfo havTypeInfo = new TypeInfo(havType); if (pipeline._addinBase.CanDirectConnectTo(havTypeInfo)) { // Connect directly for best performance. // Assert permission to the specific Addin directory only. PermissionSet permissionSet = new PermissionSet(PermissionState.None); permissionSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.Read | FileIOPermissionAccess.PathDiscovery, Path.GetDirectoryName(pipeline._addin.Location))); permissionSet.Assert(); Assembly addInAssembly = Assembly.LoadFrom(pipeline._addin.Location); // 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, "Bypass couldn't create the add-in"); // remember the addin directly as the HAV. Set the contract to null. controller.AssociateWithHostAddinView(addIn, null); return((T)addIn); } } //end direct connect code // Use Activator.CreateInstance instead of AppDomain.CreateInstanceAndUnwrap // because Activator will do the appropriate security asserts in the // remote appdomain. Type t = typeof(ActivationWorker); Object[] args = new Object[] { pipeline }; ObjectHandle objHandle = Activator.CreateInstance(domain, t.Assembly.FullName, t.FullName, false, BindingFlags.Instance | BindingFlags.NonPublic, null, args, null, null); ActivationWorker activationWorker = (ActivationWorker)objHandle.Unwrap(); activationWorker.UsingHostAppDomain = usingHostAppDomain; System.AddIn.Contract.IContract addInContract = null; try { addInContract = activationWorker.Activate(); } catch (Exception ex) { CheckForDuplicateAssemblyProblems(pipeline, ex); throw; } if (weOwn) { domain.SetData(ContractHandle.s_appDomainOwner, addInContract); } controller.ActivationWorker = activationWorker; T hav = AdaptToHost <T>(pipeline, addInContract); controller.AssociateWithHostAddinView(hav, addInContract); return(hav); }
public void Shutdown() { // Disables usage of the add-in, by breaking the pipeline. // Also, if we own the appdomain, we unload it. lock (this) // Ensure multiple threads racing on Shutdown don't collide. { AddInEnvironment environment = _addInEnvironment; if (environment != null) { try { if (_contract != null) { Object hav = _havReference.Target; IDisposable disposableHAV = hav as IDisposable; if (disposableHAV != null) { try { disposableHAV.Dispose(); } catch (AppDomainUnloadedException e) { Log(e.ToString()); } catch (RemotingException re) { Log(re.ToString()); } catch (SerializationException se) { Log(se.ToString()); } } IDisposable disposableContract = _contract as IDisposable; if (disposableContract != null) { try { disposableContract.Dispose(); } catch (AppDomainUnloadedException e) { Log(e.ToString()); } catch (RemotingException re) { Log(re.ToString()); } catch (SerializationException se) { Log(se.ToString()); } } _contract = null; } if (_activationWorker != null) { // Unhook an assembly resolve event in the target appdomain. // However, if one of the adapters implemented IDisposable and cleaned // up the appropriate lifetime tokens, this appdomain may be unloading // already (we launch another thread to do this, so we are guaranteed // to have a benign race condition). We should catch an // AppDomainUnloadedException here. try { _activationWorker.Dispose(); } catch (AppDomainUnloadedException) { } catch (RemotingException) { } catch (SerializationException) { } _activationWorker = null; } } finally { if (_unloadDomainOnExit) { // AppDomain.Unload will block until we have finalized all // objects within the appdomain. Also, this may already // have been unloaded. try { environment.UnloadAppDomain(); } catch (AppDomainUnloadedException) { } catch (RemotingException) { } // Using the transparent proxy will now cause exceptions, // as managed threads are not allowed to enter this appdomain. } } _addInEnvironment = null; // eagerly remove from list lock (_havLock) { Object addin = _havReference.Target; if (addin != null) { FindController(addin, true); } } // The perf team recommends doing a GC after a large amount of memory has // been dereferenced. We wait for the finalizers to complete first // becase some references in the addin are not released until finalization. // Also, if an addin is buggy and causes the finalizer thread to hang, // waiting here makes it fail deterministically. System.GC.WaitForPendingFinalizers(); System.GC.Collect(); } // end if domain != null else { throw new InvalidOperationException(Res.AppDomainNull); } } }