[.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