2016-05-04 3 views
0

C#(バージョン3.5)でWMIプロバイダを作成しようとしています。それは私がGACにインストールすることができ、パイプを介して実行中のサービスと通信するDLLです。サービス上のカスタムアップデータメカニズムのため、installutil.exeを使用する代わりに、プログラムでWMIリポジトリにプロバイダを登録および登録解除したいと考えています。WMI:InstrumentationManager.RegisterAssemblyを介してWMIリポジトリにアセンブリを登録

私の問題を特定し、一度に解決するために、私はサンプルプロバイダーであるhttps://msdn.microsoft.com/en-us/library/cc268228.aspxから始めました。私はそれをDLLとして構築し、GAC(gacutil.exe)に挿入し、InstallUtil.exe経由でWMIリポジトリに登録することができます。 PowerShellを使ってクエリを正しく実行すると、wbemtest.exeを使用するとその名前空間の下にクラスが表示されます。

しかし、InstrumentationManager.RegisterAssemblyを使用して作成した別のアプリケーションを使用すると、アセンブリをWMIリポジトリに登録しようとして失敗しました。

以下は上記のサンプルに基づいてDLLをプログラムでインストールしようとしています。この方法でプロバイダーDLLを実装する方法を示すサンプルの指示や指示に感謝します。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Reflection; 
using System.IO; 
using System.Management.Instrumentation; 
using System.Configuration.Install; 
//using System.EnterpriseServices.Internal; 

namespace wmi_register_tool 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      bool installing = true; 
      string asmPath = ""; 

      if (!ParseInput(args, ref installing, ref asmPath)) 
      { 
       PrintUsage(); 
       return; 
      } 

      Assembly myAssem = Assembly.Load(File.ReadAllBytes(asmPath)); 
      Console.WriteLine(myAssem.FullName); 
      Console.WriteLine("Types contained in " + asmPath + " assembly"); 


      foreach (Type oType in myAssem.GetTypes()) 
      { 
       Console.WriteLine("\t" + oType.Name); 
      } 
      //Publish p = new Publish(); 
      //p.RegisterAssembly(myAssem); 

      AssemblyInstaller wmi_installer = new AssemblyInstaller(myAssem, null); 
      Console.WriteLine("--------------> Starting AssemblyInstaller.Install()"); 
      wmi_installer.Install(null); 
      Console.WriteLine("--------------> Done with AssemblyInstaller.Install()"); 
      Console.WriteLine("--------------> Starting AssemblyInstaller.Commit()"); 
      wmi_installer.Commit(null); 
      Console.WriteLine("--------------> Done with AssemblyInstaller.Commit()"); 

      try 
      { 
       Console.WriteLine("--------------> Starting Instrumentation.RegisterAssembly()"); 
       //Instrumentation.RegisterAssembly(myAssem); 
       InstrumentationManager.RegisterAssembly(myAssem); 
       Console.WriteLine("--------------> Done with Instrumentation.RegisterAssembly()"); 
      } 
      catch (Exception e) 
      { 
       Console.WriteLine("Exception Caught: {0}", e); 
       Console.WriteLine("Exception Message: " + e.Message); 
      } 
     } 

     static bool ParseInput(string[] args, ref bool installing, ref string asmPath) 
     { 
      if (args.Length < 2 || args[0].Equals("/h") || args[0].Equals("-h")) 
      { 
       return false; 
      } 

      asmPath = args[1]; 

      if (args[0].Equals("-i")) 
      { 
       installing = true; 
       return true; 
      } 
      else if(args.Equals("-u")) 
      { 
       installing = false; 
       return true; 
      } 
      return false; 
     } 

     static void PrintUsage() 
     { 
      System.Console.WriteLine("wmi_register_tool.exe \n\t-i <filename>\n\t-u <filename>"); 
     } 
    } 
} 

私は成功したように表示され、次の出力を得るが、RegisterAssemblyが正常に挿入されていてはなりませんので、私は、WMIリポジトリに何かを見つけることはありません。

C:\wmi_testing>"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\gacutil.exe" /i WmiServic 
eHost.dll 
Microsoft (R) .NET Global Assembly Cache Utility. Version 3.5.30729.1 
Copyright (c) Microsoft Corporation. All rights reserved. 

Assembly successfully added to the cache 

C:\wmi_testing>wmi_register_tool.exe -i WmiServiceHost.dll 
WmiServiceHost, Version=1.0.0.3, Culture=neutral, PublicKeyToken=3cd934646523c30c 
Types contained in WmiServiceHost.dll assembly 
     SERVICE_STATUS_PROCESS 
     SCM_ACCESS 
     SERVICE_ACCESS 
     SC_STATUS_TYPE 
     ServiceHandle 
     SCM 
     MyInstall 
     Win32_Process 
     WIN32ServiceHost 
     <EnumerateServiceHosts>d__0 
--------------> Starting AssemblyInstaller.Install() 
Installing assembly 'C:\Windows\assembly\GAC_MSIL\WmiServiceHost\1.0.0.3__3cd934646523c30c\WmiServiceHost.dll'. 
Affected parameters are: 
    assemblypath = C:\Windows\assembly\GAC_MSIL\WmiServiceHost\1.0.0.3__3cd934646523c30c\WmiServiceHost.dll 
    logfile = C:\Windows\assembly\GAC_MSIL\WmiServiceHost\1.0.0.3__3cd934646523c30c\WmiServiceHost.InstallLog 
Installing WMI Schema: Started 
Registering assembly: WmiServiceHost_SN_3cd934646523c30c_Version_1.0.0.3 
Ensuring that namespace exists: root\MicrosoftWmiNet 
Ensuring that class exists: root\MicrosoftWmiNet:WMINET_Instrumentation 
Ensuring that class exists: CREATING root\MicrosoftWmiNet:WMINET_Instrumentation 
Ensuring that class exists: root\MicrosoftWmiNet:WMINET_InstrumentedNamespaces 
Ensuring that class exists: CREATING root\MicrosoftWmiNet:WMINET_InstrumentedNamespaces 
Ensuring that class exists: root\MicrosoftWmiNet:WMINET_Naming 
Ensuring that class exists: CREATING root\MicrosoftWmiNet:WMINET_Naming 
Ensuring that namespace exists: root\default 
Ensuring that class exists: root\default:WMINET_Instrumentation 
Ensuring that class exists: CREATING root\default:WMINET_Instrumentation 
Ensuring that class exists: root\default:WMINET_InstrumentedAssembly 
Ensuring that class exists: CREATING root\default:WMINET_InstrumentedAssembly 
Ensuring that class exists: root\default:MSFT_DecoupledProvider 
Ensuring that class exists: CREATING root\default:MSFT_DecoupledProvider 
Ensuring that class exists: root\default:WMINET_ManagedAssemblyProvider 
Ensuring that class exists: CREATING root\default:WMINET_ManagedAssemblyProvider 
Installing WMI Schema: Finished 
--------------> Done with AssemblyInstaller.Install() 
--------------> Starting AssemblyInstaller.Commit() 
See the contents of the log file for the C:\Windows\assembly\GAC_MSIL\WmiServiceHost\1.0.0.3__3cd934646523c30c\WmiServic 
eHost.dll assembly's progress. 
The file is located at C:\Windows\assembly\GAC_MSIL\WmiServiceHost\1.0.0.3__3cd934646523c30c\WmiServiceHost.InstallLog. 
Committing assembly 'C:\Windows\assembly\GAC_MSIL\WmiServiceHost\1.0.0.3__3cd934646523c30c\WmiServiceHost.dll'. 
Affected parameters are: 
    assemblypath = C:\Windows\assembly\GAC_MSIL\WmiServiceHost\1.0.0.3__3cd934646523c30c\WmiServiceHost.dll 
    logfile = C:\Windows\assembly\GAC_MSIL\WmiServiceHost\1.0.0.3__3cd934646523c30c\WmiServiceHost.InstallLog 
    logtoconsole = 
--------------> Done with AssemblyInstaller.Commit() 
--------------> Starting Instrumentation.RegisterAssembly() 
--------------> Done with Instrumentation.RegisterAssembly() 

C:\wmi_testing> 

編集:私は次のコードでInstrumentation.RegisterAssemblyを交換しようと、再び、それは例外なく完了に走ったが、それは物事が順調に行っていたことを示すコンソールに、より多くの情報をプリントアウトします。最終的に結果は同じで、wbemtest.exeを使用してWMIリポジトリで自分のネームスペースを見つけることができませんでした。

string[] installArgs = new String[] { 
    "//logfile=", 
    "//LogToConsole=false", 
    "//ShowCallStack", 
    myAssem.Location, 
}; 
System.Configuration.Install. 
ManagedInstallerClass.InstallHelper(installArgs); 

答えて

0

私はRegisterAssembly関数を使用して作業を行ってみましたが、潜在的な依存関係を検索しながら目標を達成したという事実を忘れました。 AssemblyInstaller.InstallおよびAssemblyInstaller.Commit関数は、プロバイダをWMIリポジトリに正常に挿入していました。私は、RegisterAssemblyがそれを削除していたかどうか、またはエントリを台無しにしているのかどうか、あるいは私がWMIリポジトリを継続的なテストで混乱させていたのかどうかは確かではありませんが、 AssemblyInstaller.Commitの後に例外が発生し、RegisterAssemblyの前に、私のプロバイダがWMIリポジトリに正しく挿入されていることがわかり、powershellを使用してクエリを実行することができました。

GACにDLLを手動で配置した後、WMIリポジトリに正常にインストールされた主なものは以下のとおりです。

static void Main(string[] args) 
    { 
     bool installing = true; 
     string asmPath = ""; 

     if (!ParseInput(args, ref installing, ref asmPath)) 
     { 
      PrintUsage(); 
      return; 
     } 

     Assembly myAssem = Assembly.Load(File.ReadAllBytes(asmPath)); 
     Console.WriteLine(myAssem.FullName); 

     AssemblyInstaller wmi_installer = new AssemblyInstaller(myAssem, null); 
     wmi_installer.Install(null); 
     wmi_installer.Commit(null); 
    } 

完全性のために、試しにアセンブリをインストールできるかどうかをアンインストールして確認する別のバージョンを追加します。

static void Main(string[] args) 
    { 
     bool installing = true; 
     bool installable = false; 
     string asmPath = ""; 

     if (!ParseInput(args, ref installing, ref asmPath)) 
     { 
      PrintUsage(); 
      return; 
     } 

     IDictionary mySavedState = new Hashtable(); 

     Assembly myAssem = Assembly.Load(File.ReadAllBytes(asmPath)); 
     Console.WriteLine(myAssem.FullName); 

     AssemblyInstaller wmi_installer = new AssemblyInstaller(myAssem, null); 

     if (installing) 
     { 
      try 
      { 
       AssemblyInstaller.CheckIfInstallable(asmPath); 
       installable = true; 
      } 
      catch (Exception) 
      { 
       installable = false; 
      } 

      if (installable) 
      { 
       mySavedState.Clear(); 
       try 
       { 
        wmi_installer.Install(mySavedState); 
        wmi_installer.Commit(mySavedState); 
       } 
       catch (Exception) 
       { 
        wmi_installer.Rollback(mySavedState); 
       } 
      } 
     } 
     else 
     { 
      try 
      { 
       wmi_installer.Uninstall(null); 
      } 
      catch (Exception e) 
      { 
       Console.WriteLine("Uninstall failed due to: " + e.Message); 
      } 
     } 
    } 
関連する問題