2012-02-23 4 views
0

ClickOnce 배포 응용 프로그램이 있습니다. 우리는 설치가 단지 1 버전의 eacn 시간을 갱신한다는 것을 확인하고 싶습니다. (다른 우수 사례 솔루션도 환영합니다).ClickOnce 업데이트, 버전 점프 제어

예를 들어 사용자에게 버전 1.16이 설치되었다고 말하면 서버에있는 버전이 1.18 인 새로운 릴리스가 2 개 있습니다. 다음 번에 응용 프로그램을 업데이트 할 때 먼저 1.16에서 1.17로 업데이트 할 것을 확인하고 싶습니다. 다음에 업데이트 할 때 1.17에서 1.18 등으로 업데이트됩니다. 1.16에서 1.18로 직접 업데이트하지 않습니다.

왜, 요청할 수 있습니다. 글쎄, 우리의 응용 프로그램에 로컬 (SQL EXPRESS) 데이터베이스가 있다는 사실과 관련이 있습니다. 우리는 응용 프로그램이 시작될 때 호출되는 사용자 정의 업데이트 클래스가 있습니다. CO 업데이트가 발생했는지 여부를 감지하여 변경된 스키마 변경 사항으로 로컬 db를 업데이트합니다. 나는. CO 갱신은 먼저 scehma 변경을 수행하는 데 필요한 파일을 전달한 후, 사용자 정의 갱신 클래스가 실제 db 수정을 수행합니다. 이 예제에서는 v.16에서 v.17로 변경된 db 변경 스크립트가 절대로 적용되지 않으므로 1 개 이상의 버전을 점프 할 때 문제가 발생합니다.

첫 번째 방법은 CO 업데이트 폴더를 데이지 체인 방식으로 사용하는 것입니다. 1.18에서 1.17, 1.17 업데이트까지 v.16 업데이트가 있지만 문제를 해결하지는 못합니다.

아이디어가 있으십니까?

답변

1

저는 최종 사용자의 PC에서도 SQL Server Express를 사용하는 강력한 ClickOnce 응용 프로그램을 사용하고 있습니다. 우리의 경우, 로컬 데이터베이스 스키마의 동기화는 웹 서버에서 관리됩니다.

응용 프로그램이 시작되면 현재 클라이언트 데이터베이스에서 버전 정보가 추출되고 (DB가없는 경우 "0"버전이 반환 됨) 웹 서비스가 필요한 스크립트 파일을 반환하여 로컬 데이터 베이스. ClickOnce 응용 프로그램은 순차적으로 스크립트를 실행하고 사용자가 마지막으로 응용 프로그램을 시작한시기와 관계없이 데이터베이스 스키마가 완벽하게 작성됩니다.

로컬 스키마가 업데이트되면 사용자가 액세스해야하는 모든 데이터가 서버에서 다시 동기화됩니다. 이는 데이터 테이블을 업데이트 할 때마다 테이블을 삭제 한 다음 스키마 업데이트 스크립트 내에서 테이블을 다시 만들어야하기 때문입니다.

이 유형의 복잡한 서버/클라이언트 스크립트/db 관리 시스템을 관리하지 않으려는 경우 관련 SQL 스크립트를 응용 프로그램에 번들로 묶을 수없는 이유는 무엇입니까? 현재 DB 버전을 유지하는 클라이언트 DB 내에서 테이블을 정의하여이를 수행 할 수 있습니다. 사용자가 응용 프로그램에 새 업데이트를 다운로드 할 때 DB의 버전을 확인하고 클라이언트의 현재 DB 버전에 따라 응용 프로그램과 함께 컴파일 한 사용 가능한 스크립트 또는 명령을 실행합니다.

응용 프로그램의 각 후속 게시에만 스크립트를 추가하고 이전 스크립트는 제거하지 마십시오. 새 SQL 스크립트는 DROP 및 갱신중인 오브젝트를 다시 작성해야합니다. 응용 프로그램에서 스크립트를 실행하는 도중에 응용 프로그램이 충돌하는 경우에는 많은 어려움을 줄일 수 있습니다. 나는 이것을 어려운 길을 배웠다.

스크립트가 있거나 응용 프로그램과 함께 컴파일 된 SQL 명령을 포함하는 대신 버전 검사가 서버에서 관리되는 동기화 메커니즘을 만드는 것이 좋습니다. 이렇게하면 응용 프로그램을 게시 할 필요없이 데이터베이스를 사소하게 변경할 수 있습니다. 저를 믿으십시오, 당신의 사용자는 잦은 응용 프로그램 업데이트를 다운로드 할 필요가 없기 때문에 감사 할 것입니다. 대신 이러한 유형의 변경 사항은 매끄럽게 처리되며 자동으로 백그라운드에서 수행됩니다.

1

데스크톱에서 시작된 경우 프로그램의 버전을 찾고, ClickOnce에서 시작된 경우에는 업데이트 버전을 찾는 데 사용하는 방법을 붙여 넣습니다.

private string GetTheVersion() 
    { 
     string version = string.Empty; 
     Version currentVersion; 
     Version updateVersion; 
     StringBuilder sb = new StringBuilder(); 
     if (ApplicationDeployment.IsNetworkDeployed) 
     { 
       currentVersion = ApplicationDeployment.CurrentDeployment.CurrentVersion; 
      updateVersion = ApplicationDeployment.CurrentDeployment.UpdatedVersion; 

      sb.AppendLine(string.Format("Current Version: {0}.{1}.{2}.{3}", currentVersion.Major.ToString(), currentVersion.Minor.ToString(), currentVersion.MajorRevision.ToString(), currentVersion.MinorRevision.ToString())); 
      sb.AppendLine(string.Format("Updated Version: {0}.{1}.{2}.{3}", updateVersion.Major.ToString(), updateVersion.Minor.ToString(), updateVersion.MajorRevision.ToString(), updateVersion.MinorRevision.ToString())); 
      version = sb.ToString(); 
     } 
     else 
     { 
      currentVersion = Assembly.GetCallingAssembly().GetName().Version; 
      version = string.Format("Current Version: {0}.{1}.{2}.{3}", currentVersion.Major.ToString(), currentVersion.Minor.ToString(), currentVersion.MajorRevision.ToString(), currentVersion.MinorRevision.ToString()); 
     } 

     return version; 
    } 

은 물론, 필요 이상이 더 있습니다,하지만 당신은 다음 업데이트를 수행할지 여부를 결정하기 위해 ApplicationDeployment.CurrentDeployment 클래스의 방법을 사용할 수 있습니다. 배포 방법에 따라 명령 줄 인수 또는 url querystring 변수에 기존 응용 프로그램이 있어야하는 최소 버전을 전달할 수 있습니다.

조이