Запустите службу WCF в новом домене приложений, чтобы включить теневое копирование (служба Windows размещена)
У меня есть сервисная библиотека 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;
}
}
}
Есть ли способ сделать это? Я провел большой поиск, но все еще не знаю, как заставить его работать с моими текущими настройками (или я просто не могу понять...)
Я пытался создать новый AppDomain
внутри Main()
и использовал domain.DoCallBack(new CrossAppDomainDelegate(() => { ServiceBase.Run(ServicesToRun); }))
чтобы начать обслуживание, но я не могу запустить его и продолжать получать "Error 1053: The service did not respond to the start or control request in a timely fashion"
,
А затем я попытался включить теневое копирование для текущего домена приложения, установив AppDomain.CurrentDomain.SetupInformation.ShadowCopyFiles = "true";
в MyWCFService.cs
как раз перед InitializeComponent();
Я могу запустить службу, но библиотеки все еще заблокированы. однако, если я использую AppDomain.CurrentDomain.SetShadowCopyFiles();
(устаревший метод), чтобы включить теневую копию, все работает. Я больше сбит с толку.
1 ответ
ОК, я закончил с созданием класса shell/proxy, унаследованного от MarshalByRefObject
и запустить службу оттуда, и вот код:
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);
}
}