/// <summary>
        /// Check an plugin to see if it has the same public key token and valid strong name
        /// </summary>
        /// <param name='pluginInfo'>Plugin information structure</param>
        /// <returns>true if the plugin was signed with a key that has launcher and has valid strong name, false otherwise</returns>
        public static bool VerifyPlugin(PluginInfo pluginInfo)
        {
            bool fWasVerified = false;
            bool verified = NativeMethods.StrongNameSignatureVerificationEx(pluginInfo.AssemblyPath, true, out fWasVerified);
            if (!verified || pluginInfo.AssemblyToken == null) {
                return false;
            }

            byte[] expectedToken = Assembly.GetAssembly(typeof(PluginManager)).GetName().GetPublicKeyToken();
            try {
                if (pluginInfo.AssemblyToken.Length != expectedToken.Length) {
                    return false;
                }
                for (int i = 0; i < pluginInfo.AssemblyToken.Length; i++) {
                    if (pluginInfo.AssemblyToken[i] != expectedToken[i]) {
                        return false;
                    }
                }
                return true;
            } catch (FileNotFoundException) {
                return false;
            } catch (BadImageFormatException) {
                return false;
            }
        }
 private PluginContainer(IPlugin Plugin, PluginInfo Info, RuntimeStatus Status, AppDomain Domain, Exception FailException)
 {
     this.Name = Plugin.Name;
     this.Author = Plugin.Author;
     this.Plugin = Plugin;
     this.Info = Info;
     this.Status = Status;
     this.Domain = Domain;
     this.FailException = FailException;
 }
        private bool LoadPlugin(PluginInfo info)
        {
            bool verified = VerifyPlugin(info);
            LOGGER.Info(string.Format("Plugin loading: TypeName={0}, Verified={1}, Path={2}", info.TypeName, verified, info.AssemblyPath));

            AppDomainSetup domainSetup = new AppDomainSetup();
            domainSetup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
            domainSetup.PrivateBinPath = @"Plugins;bin";

            PermissionSet permissions;
            if (!verified) {
                permissions = new PermissionSet(PermissionState.None);

                permissions.AddPermission(new UIPermission(UIPermissionWindow.AllWindows, UIPermissionClipboard.NoClipboard));
                permissions.AddPermission(new WebPermission(PermissionState.Unrestricted));
                permissions.AddPermission(new WebBrowserPermission(PermissionState.Unrestricted));
                permissions.AddPermission(new ReflectionPermission(ReflectionPermissionFlag.NoFlags));

                permissions.AddPermission(new SecurityPermission(
                  SecurityPermissionFlag.Execution |
                  SecurityPermissionFlag.SerializationFormatter |
                  SecurityPermissionFlag.Assertion));

                permissions.AddPermission(new FileIOPermission(
                  FileIOPermissionAccess.PathDiscovery |
                  FileIOPermissionAccess.Read,
                  new string[] {
                  AppDomain.CurrentDomain.BaseDirectory,
                  EnvironmentManager.ResourcesPath,
                  }));

                permissions.AddPermission(new FileIOPermission(
                  FileIOPermissionAccess.PathDiscovery |
                  FileIOPermissionAccess.Write |
                  FileIOPermissionAccess.Read,
                  EnvironmentManager.Resources3rdPath));

                // debug = REMOVE
                //permissions.AddPermission(new ReflectionPermission(PermissionState.Unrestricted));
                //permissions.AddPermission(new SecurityPermission(PermissionState.Unrestricted));
            } else {
                permissions = new PermissionSet(PermissionState.Unrestricted);
            }

            AppDomain domain = AppDomain.CreateDomain(
              string.Format("PluginDomain [{0}]", Path.GetFileNameWithoutExtension(info.AssemblyPath)),
              null,
              domainSetup,
              permissions);
            domain.SetData("DataDirectory", EnvironmentManager.AppDataPath);

            PluginContainer container = null;
            string pluginName = null;
            IPlugin Instance = null;
            try {
                Instance = (IPlugin)domain.CreateInstanceFromAndUnwrap(info.AssemblyPath, info.TypeName);
                pluginName = Instance.Name;

                if (Plugins.TryGetValue(pluginName, out container)) {
                    if (container.Status == PluginContainer.RuntimeStatus.ACTIVE) {
                        AppDomain.Unload(domain);
                        return false;
                    }
                }
                try {
                    Instance.OnActivate(PluginHost);
                } catch (Exception) {
                    Instance.OnStop(PluginHost);
                }
                container = new PluginContainer(Instance, info, PluginContainer.RuntimeStatus.ACTIVE, domain);
            } catch (Exception e) {
                AppDomain.Unload(domain);
                if (pluginName != null && Instance != null) {
                    container = new PluginContainer(Instance, info, PluginContainer.RuntimeStatus.FAILED, e);
                }
                return false;
            }
            return Plugins.AddOrUpdate(pluginName, container, (key, oldValue) => container) != null;
        }
 public PluginContainer(IPlugin Plugin, PluginInfo Info, RuntimeStatus Status, Exception FailException)
     : this(Plugin, Info, Status, null, FailException)
 {
 }
 public PluginContainer(IPlugin Plugin, PluginInfo Info, RuntimeStatus Status, AppDomain Domain)
     : this(Plugin, Info, Status, Domain, null)
 {
 }