2017-11-05 20 views
0

C#で書かれたWCFサービスがあります。これは、Win32コンソールアプリケーションの通常の自己ホスト型です。しかし、特別なアップデートのために(これは単純なデスクトップコンピュータではなく、通常のインストーラを使用してプログラムをアップデートするのではなく、特別な組み込みシステムを使用しています)、サービスを実装している実際のタイプをDLL非常に単純なローダ実行用いた反射:C#DLLで実装されたWCFサービス

ServicesType.GetMethod("InstallService").Invoke(null, null); 
ServicesType.GetMethod("StartService").Invoke(null, null); 
:私はどちらかのMSIを経由して、通常はそれをインストールする、または sc.exeを使用して、あるいはこのような自己管理型のコードで、サービスはすべての3つの方法で展開することができます

string DllFilename = Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "myservice.dll"); 
var ServicesDll = Assembly.LoadFrom(DllFilename); 
var ServicesType = ServicesDll.GetType("MyNamespace.MyServices"); 
var Instance = (ServiceBase)Activator.CreateInstance(ServicesType); 
ServiceBase.Run(new ServiceBase[] { Instance }); 

public class MyServices : ServiceBase { 

    //... 

    public static void InstallService() { 
    if (!IsInstalled()) 
     using (AssemblyInstaller installer = GetInstaller()) { 
     var state = new Hashtable(); 
     try { 
      installer.Install(state); 
      installer.Commit(state); 
     } 
     catch { 
      installer.Rollback(state); 
      throw; 
     } 
     } 
    } 

    public static void StartService() { 
    if (IsInstalled()) 
     using (var controller = new ServiceController("MyService")) { 
     if (controller.Status != ServiceControllerStatus.Running) { 
      controller.Start(); // fails here 
      controller.WaitForStatus(ServiceControllerStatus.Running, TimeSpan.FromSeconds(10)); 
     } 
     } 
    } 

    //... 
} 

最初に述べたように、EXEではすべて正常に機能します。しかし、MyServiceタイプがDLLに入ったら、すぐにInstallServiceは正常ですが、StartServiceで失敗します。System.ComponentModel.Win32Exception:%1は有効なWin32アプリケーションではありません。 Windowsはサービス実行可能ファイル(実際にインストールされたEXEファイルではなく、サービスが実装されたDLLとして保存される)が余裕で呼び出されるように実行可能ファイルであることを期待しているようです。

この制限を回避するにはどうすればいいですか、何とか私のローダーEXEであり、依存DLLではなく呼びたいと思っていることを、 ServiceBase(.EXEに住んでいる)とセルフホスティング更新可能な.DLLに住むことを含む別のやって実際の作業から継承された1の薄いラッパー -

+0

* service * dllには、[ServiceMain](https://msdn.microsoft.com/en-us/library/windows/desktop/ms687414(v = vs.85))のマネージドバリアントのエントリポイントが必要です。 .aspx)ですが、dll https://stackoverflow.com/a/28514705/578411に追加するのは面倒です。より良いexeを使用してください。 – rene

+0

EXEとして保存しますが、自由に読み込まれたアセンブリとして消費しますか?うーん、それもやってみなければならない。 –

答えて

0

私はついにRene氏の提案に行きました。サービスの大半はEXEにとどまり、アセンブリとしてローダーにロードされました。幸いにも、アセンブリの読み込みは、EXEとDLLの両方から実行できます。

0

は、2つのクラスにあなたのMyServicesを分割します。最初のものは.ctorの引数として2番目のインスタンスをとり、それに対する開始/停止の呼び出しを委任することができます。

Topshelfをご覧になることもできます。

+0

アイデアをお寄せいただき、ありがとうございます。 –

関連する問題