在新的AppDomain中启动WCF服务以启用影子复制(Windows service托管)



我有一个WCF服务库(MyWCFService),它使用MEF加载插件并由Windows服务(All . net 4.0)托管。我现在正试图在新的AppDomain中运行它,并启用ShadowCopyFiles,希望我可以在运行时更新插件。下面是Windows服务项目中的代码:

Program.cs

 static class Program
    {  
        static void Main()
        {  
            ServiceBase[] ServicesToRun;
            ServicesToRun = new ServiceBase[] 
            { 
               new MyService() 
            };
            ServiceBase.Run(ServicesToRun);
        }
    }

MyService.cs

  public partial class MyService: ServiceBase
    {
        internal static ServiceHost MyServiceHost = null;
        public MyService()
        {
             // this works but is deprecated..
             AppDomain.CurrentDomain.SetShadowCopyFiles();
            //this is not working.. DLLs still get locked. Require for a new AppDomain
            //AppDomain.CurrentDomain.SetupInformation.ShadowCopyFiles = "true";  
            InitializeComponent();
        }   
        protected override void OnStart(string[] args)
        {
            if(MyServiceHost  !=null)
            {
                MyServiceHost.Close();
            }
            try
            {
                MyServiceHost= new ServiceHost(typeof(MyWCFService));         
                MyServiceHost.Open();
            }
            catch(Exception)
            {
            }          
        }
        protected override void OnStop()
        {
            if (MyServiceHost!= null)
            {
                MyServiceHost.Close();
                MyServiceHost= null;
            }
        }       
    }

有什么办法吗?我已经做了很多搜索,但仍然不知道如何使它与我当前的设置工作(或者我只是不能理解…)

我试着在Main()里面创建一个新的AppDomain并使用domain.DoCallBack(new CrossAppDomainDelegate(() => { ServiceBase.Run(ServicesToRun); }))启动服务,但我不能启动它,并一直得到"Error 1053: The service did not respond to the start or control request in a timely fashion"

然后我试图通过在InitializeComponent();之前在MyWCFService.cs中设置AppDomain.CurrentDomain.SetupInformation.ShadowCopyFiles = "true";来启用当前应用域的影子复制,我可以启动服务,但dll仍然被锁定。但是,如果我使用AppDomain.CurrentDomain.SetShadowCopyFiles();(一个已弃用的方法)来启用影子复制,一切都可以工作。

OK,我最终创建了一个继承自MarshalByRefObject的shell/代理类,并从那里启动服务,下面是代码:

ServiceShell.cs

public class ServiceShell:MarshalByRefObject
{
     internal static ServiceHost MyServiceHost = null;
     public void Run()
     {
         if (MyServiceHost != null)
         {
             MyServiceHost.Close();
         }
         try
         {
             MyServiceHost = new ServiceHost(typeof(MyWCFService));
             MyServiceHost.Open();
         }
         catch (Exception)
         {
         }          
     }
     public void Stop()
     {
         if (MyServiceHost!= null)
         {
             MyServiceHost.Close();
             MyServiceHost = null;
         }
     }
}

MyService.cs

public partial class MyService: ServiceBase
{        
    AppDomain domain;
    ServiceShell runner;
    public MyService()
    {   
        var setup = new AppDomainSetup
        {
            ShadowCopyFiles = "true"
        };
        domain = AppDomain.CreateDomain("MyServiceHostDomain", AppDomain.CurrentDomain.Evidence, setup);
        runner = (ServiceShell)domain.CreateInstanceAndUnwrap
            (typeof(ServiceShell).Assembly.FullName, typeof(ServiceShell).FullName);
        InitializeComponent();
    }
    protected override void OnStart(string[] args)
    {          
        runner.Run();
    }
    protected override void OnStop()
    {
        runner.Stop();
        AppDomain.Unload(domain);
    }       
}

相关内容

  • 没有找到相关文章

最新更新