2012-03-27 3 views
1

설치된 구성 요소를 자동으로 업데이트하는 설치 프로그램을 만들려고합니다.설치 프로그램을 올바르게 구현하는 방법

  • 제품 코드 : {9835AE3C-1CED-4FC6-85E1-D2DC8093E9F4가}
  • 제품 이름 : 푸
  • UpgradeCode : {02FD8E1A-A552-47AE 그러므로 나는 다음과 같은 설정으로, 설치 프로그램 프로젝트를 만들었습니다 -BDAA-F165702DE8DC}
  • 버전 :

Version -attribute을 변경 1.2.002이 새로운 ProductCode가 생성됩니다 (내가 온 그룹화 이해하는 방법 제품은 UpgradeCode을 통해 이루어지며 특정 버전은 ProductCode에 바인딩됩니다.

내 맞춤 작업

는 다음과 같다 :

enter image description here

이 SOOO ... 여기에 우리가 내 설치 클래스가 있습니다

[RunInstaller(true)] 
// my .cs-file 
public partial class Installer : System.Configuration.Install.Installer 
{ 
    public Installer() 
    { 
     this.InitializeComponent(); 
    } 

    protected override void OnAfterInstall(System.Collections.IDictionary savedState) 
    { 
     base.OnAfterInstall(savedState); 

     using (var serviceController = new ServiceController(Settings.Service.Name)) 
     { 
      serviceController.Start(); 
      serviceController.WaitForStatus(ServiceControllerStatus.Running); 
     } 
    } 

    protected override void OnBeforeUninstall(System.Collections.IDictionary savedState) 
    { 
     base.OnBeforeUninstall(savedState); 

     using (var serviceController = new ServiceController(Settings.Service.Name)) 
     { 
      serviceController.Stop(); 
      serviceController.WaitForStatus(ServiceControllerStatus.Stopped); 
     } 
    } 
} 


// my designer 
partial class Installer 
{ 
    private ServiceInstaller ServiceInstaller; 
    private ServiceProcessInstaller ServiceProcessInstaller; 

    /// <summary> 
    /// Required designer variable. 
    /// </summary> 
    private System.ComponentModel.IContainer components = null; 

    /// <summary> 
    /// Clean up any resources being used. 
    /// </summary> 
    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> 
    protected override void Dispose(bool disposing) 
    { 
     if (disposing && (components != null)) 
     { 
      components.Dispose(); 
     } 
     base.Dispose(disposing); 
    } 

    #region Component Designer generated code 

    /// <summary> 
    /// Required method for Designer support - do not modify 
    /// the contents of this method with the code editor. 
    /// </summary> 
    private void InitializeComponent() 
    { 
     this.ServiceProcessInstaller = new System.ServiceProcess.ServiceProcessInstaller(); 
     this.ServiceInstaller = new System.ServiceProcess.ServiceInstaller(); 
     // 
     // ServiceProcessInstaller 
     // 
     this.ServiceProcessInstaller.Account = System.ServiceProcess.ServiceAccount.LocalService; 
     this.ServiceProcessInstaller.Password = null; 
     this.ServiceProcessInstaller.Username = null; 
     // 
     // ServiceInstaller 
     // 
     this.ServiceInstaller.ServiceName = "Foo"; 
     this.ServiceInstaller.StartType = System.ServiceProcess.ServiceStartMode.Automatic; 

    } 

    #endregion 
} 

초기 설치는 문제가되지 않습니다를 - 모든 작품을 벌금 (설치, 자동 시작, ...). 그러나 동일한 UpgradeCode을 사용하여 새로운 .msi 패키지를 설치하려고 시도했지만 ProductCode이 틀리면 설치 프로그램이 "오류 1001 : 지정된 서비스가 이미 있습니다."라는 오류 메시지가 나타납니다. 모든 제거 처리기 (또는 호출)는 호출되지 않고 UpgradeCode/Productcode -magic이 작동하지 않습니다 ...
그래서 내 질문 : 제거 (처리해야하는) 경로는 어디에 있습니까? 올바른 구현은 무엇입니까?

편집 :
HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Installer:Logging의 설정이 iwemv입니다 - output @ pastebin (실제로는 내 시나리오에서 서로 다른 코드 여기 내 문제 등을 가지고).
우리가 라인 161ff에서 볼 수있는 바와 같이, 이전 버전이 발견 :

MSI (c) (50:04) [10:03:31:319]: Doing action: AppSearch 
Aktion gestartet um 10:03:31: AppSearch. 
MSI (c) (50:04) [10:03:31:319]: Note: 1: 2262 2: AppSearch 3: -2147287038 
Aktion beendet um 10:03:31: AppSearch. Rückgabewert 1. 
MSI (c) (50:04) [10:03:31:319]: Doing action: FindRelatedProducts 
Aktion gestartet um 10:03:31: FindRelatedProducts. 
MSI (c) (50:04) [10:03:31:319]: PROPERTY CHANGE: Adding PREVIOUSVERSIONSINSTALLED property. Its value is '{C4C4318A-2F89-416B-A48C-76BD035EB52B}'. 
Aktion beendet um 10:03:31: FindRelatedProducts. Rückgabewert 1. 

라인 (272) 호출 클라이언트 @

MSI (s) (A4:6C) [10:03:41:219]: Command Line: TARGETDIR=C:\Program Files (x86)\MyCompany\Foobar\ ALLUSERS=1 PREVIOUSVERSIONSINSTALLED={C4C4318A-2F89-416B-A48C-76BD035EB52B} VSDNETURLMSG=Dieses Setup erfordert die Version 4.0 von .NET Framework. Installieren Sie .NET Framework, und führen Sie Setup erneut aus. .NET Framework kann über das Internet bezogen werden. Möchten Sie es jetzt beziehen? VSDNETMSG=Dieses Setup erfordert die Version 4.0 von .NET Framework. Installieren Sie .NET Framework, und führen Sie Setup erneut aus. CURRENTDIRECTORY=D:\Foo\Release CLIENTUILEVEL=0 CLIENTPROCESSID=5200 USERNAME=MyCompany Support COMPANYNAME=MyCompany GmbH SOURCEDIR=D:\Foo\Release\ ACTION=INSTALL EXECUTEACTION=INSTALL ROOTDRIVE=D:\ INSTALLLEVEL=1 SECONDSEQUENCE=1 ADDLOCAL=DefaultFeature ACTION=INSTALL 

sooo를

MSI (c) (50:04) [10:03:31:413]: Switching to server: TARGETDIR="C:\Program Files (x86)\MyCompany\Foobar\" ALLUSERS="1" PREVIOUSVERSIONSINSTALLED="{C4C4318A-2F89-416B-A48C-76BD035EB52B}" VSDNETURLMSG="Dieses Setup erfordert die Version 4.0 von .NET Framework. Installieren Sie .NET Framework, und führen Sie Setup erneut aus. .NET Framework kann über das Internet bezogen werden. Möchten Sie es jetzt beziehen?" VSDNETMSG="Dieses Setup erfordert die Version 4.0 von .NET Framework. Installieren Sie .NET Framework, und führen Sie Setup erneut aus." CURRENTDIRECTORY="D:\Foo\Release" CLIENTUILEVEL="0" CLIENTPROCESSID="5200" USERNAME="MyCompany Support" COMPANYNAME="MyCompany GmbH" SOURCEDIR="D:\Foo\Release\" ACTION="INSTALL" EXECUTEACTION="INSTALL" ROOTDRIVE="D:\" INSTALLLEVEL="1" SECONDSEQUENCE="1" ADDLOCAL=DefaultFeature 

라인 (313) 호출 @ 서버 ... 조치는 설치이며 업데이트/설치 제거/...가 아닙니다!

+0

업그레이드 코드가 동일하고 최신 버전 인 경우 업그레이드를 수행하면 이전 버전의 제거가 트리거됩니다. 예를 들어 응용 프로그램마다 다른 설치 유형이있는 경우, 즉 첫 번째 설치 유형이 사용자 당 설치되고 두 번째 설치 유형이 기계 당 설치되는 경우 또는 다른 방법으로 설치된 경우 설치가 건너 뛰게됩니다. 자세한 내용을 보려면 자세한 로그를 만들어야합니다. http://support.microsoft.com/kb/223300 –

+0

@BogdanMitrache 힌트를 보내 주셔서 감사합니다. - "검열 된"출력 @ pastebin (http : // pastebin)을 포함 시켰습니다. .com/CnXXgeJT) –

답변

1

"올바르게"물어 본 결과, InstallUtil 사용자 지정 작업은 끔찍한 반 패턴이며 MSI가 기본적으로 지원하는 것들에 코드를 작성함으로써 바퀴가 새롭게 바뀌 었음을 알아야합니다. 또한 Visual Studio 배포 프로젝트는 여러 가지면에서 끔찍한 점이 있습니다.이 경우 MSI의 서비스 설치 및 제어 기능이 노출되지 않으므로 VS11의 다음 릴리스에서 제거됩니다.

어떤 배경 : (너의이의 예입니다 및 c)

Zataoca: Custom actions are (generally) an admission of failure.

지금 당신에게 내 조언은 사용자 지정 작업을 제거하고 윅스 대신 병합 모듈을 사용하여 얻을 수 있습니다. 개념은 서비스 EXE가있는 구성 요소를 병합 모듈에 인수 분해 한 다음 VDPROJ에서 병합 모듈을 사용하게하는 것입니다. (콘솔 앱에서 클래스를 가져 와서 라이브러리로 옮긴 다음 ILDASM을 사용하여 라이브러리를 다시 콘솔 앱에 병합합니다. Windows Installer XML을 사용하여 1) 실제로 ServiceInstall 및 ServiceControl 테이블을 노출하고 2) FOSS이기 때문에 병합 모듈을 작성하십시오.

Augmenting InstallShield using Windows Installer XML - Windows Services

당신의 결과는 MSI는 훨씬 간단/청소기되며 MSI 당신을 위해 일을하고있다 때문에 1001 개 오류 메시지가 마술 사라집니다.

+0

그 입력에 대해 많은 감사를드립니다 ... 실제로 .vdproj 파일을 삭제하고 멋지고 슬림 한 .wxs 파일을 작성했습니다. 내 구현의 유일한 단점은 모든 파일을 파일 태그로 나열하고 "프로젝트 X의 출력"을 가져올 수 없다는 것입니다. 하지만 ServiceInstall 및 ServiceControl 태그는 매우 강력합니다. –

+0

이 기능을 구현하지 못하면 언제든지 저에게 연락하십시오. 처음으로 할 때 약간 혼란 스러울 수도 있습니다. –

+0

WiX는 프로젝트 참조를 지원합니다. .NET 프로젝트에 대한 참조를 WiX 프로젝트에 추가 한 다음 wxs에서 파일 이름 속성에 $ (var.ProjectName.TargetPath)와 같은 것을 말합니다. –

관련 문제