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;
        }
Exemple #6
0
        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);
                }
            }
        }