[.Net] TransactedInstaller

.Net/.Net 2013. 4. 22. 17:23

TransactedInstaller : http://msdn.microsoft.com/query/dev10.query?appId=Dev10IDEF1&l=KO-KR&k=k(SYSTEM.CONFIGURATION.INSTALL.TRANSACTEDINSTALLER);k(SOLUTIONITEMSPROJECT);k(SOLUTIONITEMSPROJECT);k(TargetFrameworkMoniker-%22.NETFRAMEWORK%2cVERSION%3dV4.0%22);k(DevLang-CSHARP)&rd=true 


InstallContext : http://msdn.microsoft.com/query/dev10.query?appId=Dev10IDEF1&l=KO-KR&k=k(%22SYSTEM.CONFIGURATION.INSTALL.INSTALLCONTEXT.%23CTOR%22);k(SOLUTIONITEMSPROJECT);k(SOLUTIONITEMSPROJECT);k(TargetFrameworkMoniker-%22.NETFRAMEWORK%2cVERSION%3dV4.0%22);k(DevLang-CSHARP)&rd=true


TransactedInstaller 를 사용하면은 Installutil.exe(설치 관리자 도구)의 구현과 유사한 구현을 제공 할수 있다.



ArrayList myOptions = new ArrayList();
String myOption;
bool toUnInstall = false;
bool toPrintHelp = false;
TransactedInstaller myTransactedInstaller = new TransactedInstaller();
AssemblyInstaller myAssemblyInstaller;
InstallContext myInstallContext;

try
{
   for(int i = 0; i < args.Length; i++)
   {
      // Process the arguments.
      if(args[i].StartsWith("/") || args[i].StartsWith("-"))
      {
         myOption = args[i].Substring(1);
         // Determine whether the option is to 'uninstall' an assembly.
         if(String.Compare(myOption, "u", true) == 0 ||
            String.Compare(myOption, "uninstall", true) == 0)
         {
            toUnInstall = true;
            continue;
         }
         // Determine whether the option is for printing help information.
         if(String.Compare(myOption, "?", true) == 0 ||
            String.Compare(myOption, "help", true) == 0)
         {
            toPrintHelp = true;
            continue;
         }
         // Add the option encountered to the list of all options
         // encountered for the current assembly.
         myOptions.Add(myOption);
      }
      else
      {
         // Determine whether the assembly file exists.
         if(!File.Exists(args[i]))
         {
            // If assembly file doesn't exist then print error.
            Console.WriteLine("\nError : {0} - Assembly file doesn't exist.",
               args[i]);
            return;
         }

         // Create a instance of 'AssemblyInstaller' that installs the given assembly.
         myAssemblyInstaller = 
            new AssemblyInstaller(args[i], 
            (string[]) myOptions.ToArray(typeof(string)));
         // Add the instance of 'AssemblyInstaller' to the 'TransactedInstaller'.  
         myTransactedInstaller.Installers.Add(myAssemblyInstaller);
      }
   }
   // If user requested help or didn't provide any assemblies to install
   // then print help message.
   if(toPrintHelp || myTransactedInstaller.Installers.Count == 0)
   {
      PrintHelpMessage();
      return;
   }

   // Create a instance of 'InstallContext' with the options specified.
   myInstallContext = 
      new InstallContext("Install.log", 
      (string[]) myOptions.ToArray(typeof(string)));
   myTransactedInstaller.Context = myInstallContext;

   // Install or Uninstall an assembly depending on the option provided.
   if(!toUnInstall)
      myTransactedInstaller.Install(new Hashtable());
   else
      myTransactedInstaller.Uninstall(null);
}
catch(Exception e)
{
   Console.WriteLine("\nException raised : {0}", e.Message);
}


참고 : http://www.devpia.com/Maeul/Contents/Detail.aspx?BoardID=18&MAEULNO=8&no=1971&page=2 

 

MFC C++쓸땐 Self 서비스 등록 코드를 썼는데

 

C#에서는 InstallUtil.exe를 써야 하는데

 

InstallUtil.exe이 패스에 안걸려 있으면 찾아서 써야 하니 귀찮기도 하구 해서

 

아침에 삽질 삽질 하다가..  거의 포기하려는 순간에 찾았네요.

 

서비스로 만드는 법은 뭐 간단하니 아실거구.

 

서비스 인스톨러도 추가해 놓으심 되구요..

 

그 다음에 Main을 아래와 같이 넣어서 고쳐 쓰심 됩니다.

 

 

/install 과 /uninstall 로 서비스에 넣었다 뺏다 합니다.

ServiceMain은 내가 만든 서비스 실행 클래스 일 뿐이구요

추가 하셔서 일반에서 서비스를 선택하시면 됩니다.

 

[STAThread]
static void Main(string[] args)
{
    if (args.Length == 1)
    {
 try
 {
     using (TransactedInstaller ti = new TransactedInstaller())
     {
  using (ProjectInstaller pi = new ProjectInstaller())
  {
      ti.Installers.Add(pi);
      string[] cmdline = { string.Format("/assemblypath={0}", System.Reflection.Assembly.GetExecutingAssembly().Location) };
      pi.Context = new InstallContext(null, cmdline);
      if (args[0].ToLower() == "/install")
   pi.Install(new Hashtable());
      else if (args[0].ToLower() == "/uninstall")
   pi.Uninstall(null);
      else
   throw new Exception("Invalid command line");
  }
     }
 }
 catch (Exception ex)
 {
     Console.Error.WriteLine(ex.Message);
 }
    }
    else
    {
 System.ServiceProcess.ServiceBase[] ServicesToRun;
 ServicesToRun = new System.ServiceProcess.ServiceBase[] { new ServiceMain() };
 System.ServiceProcess.ServiceBase.Run(ServicesToRun);
    }
}


posted by 뚱2