자동 업데이트는 어떻게 구현해야합니까?
대부분의 프로그램에는 자동 업데이트 프로그램이 포함되어 있습니다.이 프로그램은 때때로 온라인에서 업데이트를 찾은 다음 발견 된 업데이트를 다운로드하여 적용합니다. 프로그램 버그가 수정되고 지원 파일이 수정되며 (보통) 상황이 개선됩니다.
안타깝게도 아무리 열심히 봐도이 과정에 대한 정보를 어디서도 찾을 수 없습니다. 구현 된 자동 업데이트 프로그램이 독점적이거나 중요하지 않은 것으로 보입니다.
네트워크에서 업데이트를 찾고 사용 가능한 경우 다운로드하는 시스템을 구현하는 것은 매우 쉽습니다. 자동 업데이트 프로그램의 해당 부분은 구현마다 크게 변경됩니다. 문제는 패치 를 적용 하는 다른 접근 방식이 무엇인지 입니다. 파일을 다운로드하고 이전 파일을 새 파일로 바꾸고, 다운로드 한 마이그레이션 스크립트를 실행하고, 시스템의 일부를 원숭이 패치하는 등? 개념이 선호되지만 Java, C, Python, Ruby, Lisp 등의 예를 들어도 좋습니다.
나는 "언어 불가지론 적"이 여기서 제한 요소가 될 것이라고 생각합니다. 응용 프로그램은 매우 다양한 모양과 크기로 제공되므로 한 가지 해결책이 없습니다. 여러 언어로 여러 자동 업데이트 프로그램을 구현했는데 두 가지가 비슷하지 않았습니다.
가장 일반적인 철학은 응용 프로그램이 일부 집 위치 (웹 주소, 웹 쿼리, 회사 네트워크 위치 등)를 확인하여 최신 버전인지 여부를 묻거나 최신 버전이 무엇인지 묻는 것입니다. 답변에 업데이트가 필요한 경우 해당 프로세스는 상황에 따라 다릅니다.
인기있는 대안은 응용 프로그램이 시작될 때 스크립트를 실행하도록 홈 위치를 초대하는 것입니다. 스크립트는 버전을 확인하고, 필요한 경우 업데이트를 다운로드하고, 예를 들어 사용 피드백을 요청할 수 있습니다.
매개 변수를 좁 히면 더 나은 도움을 드릴 수 있습니다.
업데이트 : "패칭"에 대한 접근 방식은 응용 프로그램의 특성에 따라 다르며 여기에는 매우 다양한 다양성이 있습니다. 예를 들어 단일 실행 파일이있는 경우 실행 파일을 대체하는 것이 가장 실용적 일 수 있습니다. 응용 프로그램에 많은 파일이있는 경우 교체되는 파일 수를 최소화하는 방법을 찾아야합니다. 애플리케이션이 고도로 사용자 정의되거나 매개 변수화 된 경우 재조정 노력을 최소화하기 위해 노력해야합니다. 응용 프로그램이 해석 된 코드 (예 : Excel VBA 응용 프로그램 또는 MS Access MDB 응용 프로그램)를 사용하는 경우 코드의 일부를 교체 할 수 있습니다. Java 응용 프로그램에서는 JAR 파일 또는 JAR 내용의 하위 집합 만 교체하면됩니다. 또한 현재 클라이언트 버전을 인식하고 적절하게 업데이트하는 방법이 있어야합니다. 나는 계속할 수 있습니다. 하지만 다양성에 대한 제 요점을 보셨기를 바랍니다. 이것은 일반적으로 가장 좋은 대답이 "음, 상황에 따라 다릅니다 ...!"로 시작하는 경우 중 하나입니다. 그래서 많은 답변에 "파라미터 범위를 좁히십시오"가 포함됩니다.
또한 업데이트 바이너리 자체뿐만 아니라 업데이트에 대한 정보를 가져 오는 것이 보안에 미치는 영향도 고려해야합니다.
다운로드 소스를 신뢰하십니까? 업데이트를 받기 위해 집으로 전화를 걸 수도 있지만, 중간에 악성 서버로 리디렉션하는 사람이 있다면 어떨까요? HTTPS 또는 유사한 보안 연결이 도움이되지만 디지털 서명 검사를 사용하여 결국 다운로드하는 비트를 다시 확인하는 것이 좋습니다.
먼저 응용 프로그램 홈 웹 사이트에 최신 버전의 파일이 필요합니다. 이 작업에 대한 특수 SQL 테이블을 가지고 새 버전을 게시 / 야간 빌드 완료 후 자동으로 채우는 가장 좋은 방법입니다. 응용 프로그램은 버전과 함께 내장 http 링크를 요청하고 현재 버전과 비교하는 새 스레드를 생성합니다. .NET에서는 다음과 같은 코드를 사용할 수 있습니다.
Version GetLatestVersion() {
HttpWebRequestrequest = (HttpWebRequest)WebRequest.Create(new Uri(new Uri(http://example.net), "version.txt));
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (request.HaveResponse)
{
StreamReader stream = new StreamReader(response.GetResponseStream(), Encoding.Default);
return new Version(stream.ReadLine());
}
else
{
return null;
}
}
Version latest = GetLatestVersion();
Version current = new Version(Application.ProductVersion);
if (current < latest)
{
// you need an update
}
else
{
// you are up-to-date
}
이 예에서 version.php는 1.0.1.0과 같은 하나의 일반 문자열에만 있습니다.
제가 드릴 수있는 또 다른 팁은 업데이트를 다운로드하는 방법입니다. 다음 아이디어가 매우 마음에 듭니다. 애플리케이션 리소스에는 즉석에서 컴파일 (CodeDom 사용)하는 CLR 코드 문자열이 있으며, 기본 애플리케이션은이를 호출하고 닫습니다. 업데이터는 인수, 설정 또는 레지스트리를 읽고 새 모듈을 다운로드합니다. 그리고 모든 임시 파일을 삭제하는 메인 애플리케이션을 호출합니다. 끝난!
(그러나 여기에있는 모든 것은 .NET에 관한 것입니다)
가장 간단한 솔루션 (많은 프로그램에서 사용됨)은 이전 버전의 경우 제거 프로그램을 실행하고 새 버전의 경우 설치 프로그램을 실행하는 것입니다 (선택적으로 EULA와 같이 사용자가 이미 답변 한 질문을 건너 뛰는 것). 유일한 문제는 새 버전이 이전 버전의 구성 옵션을 읽을 수 있어야한다는 것입니다.
또한 Windows에서는 사용중인 실행 파일을 삭제할 수 없으므로 전체 프로세스를 실행하는 Temp 폴더에 작은 실행 파일을 드롭 한 다음 새 버전의 인스턴스에서 마지막에 삭제하는 것이 좋습니다. 시작되었습니다 (또는 다음 재부팅시 삭제되도록 등록하십시오 ).
가장 간단한 방법은 프로그램이 업데이트가 있는지 확인하기 위해 서버 (웹 사이트)를 쿼리하도록하는 것입니다. 업데이트가있는 경우 사용자에게 최신 버전을 다운로드하라는 메시지를 표시하고 링크를 제공 할 수 있습니다.
더 복잡한 대안은 업데이트가 있는지 주기적으로 확인하는 작은 Windows 서비스 (또는 유닉스 데몬)를 만드는 것입니다.이 서비스는 업데이트를 다운로드하고 설치 프로그램을 시작할 수 있습니다.
일반적인 아키텍처는 최신 버전과이를 얻을 수있는 위치를 알고 제어하는 중앙 서버가 있다는 것입니다. 그런 다음 프로그램은 서버에 쿼리합니다. 샘플 코드는 서버와 사용자가 선택한 형식에 대해 매우 방어 적이기 때문에 포함하지 않겠습니다. 그래도 끔찍한 것은 아닙니다.
이것은 완전한 대답이 아니라 최근에 구현 한 자동 업데이트 메커니즘의 한 예입니다. 상황은 직장에서 사용되는 내부 도구이기 때문에 전통적인 Firefox 유형의 사용자 응용 프로그램과는 약간 다릅니다.
기본적으로 설치 프로그램에서 빌드 및 패키징 할 Subversion 분기 대기열을 관리하는 작은 스크립트입니다. 브랜치의 이름이 쓰여진 작은 파일을 읽고, 첫 번째 파일을 가져 와서 파일 끝에서 다시 작성하고, 여러 스크립트를 호출하는 빌드 프로세스를 시작합니다. 빌드 할 각 브랜치의 구성은 도구 자체와 함께 Subversion 저장소에 저장되는 .INI 파일로 작성됩니다.
이 도구는 여러 컴퓨터에서 실행되기 때문에 도구 자체 나 구성 스크립트를 변경하자마자 모든 컴퓨터에서 자동으로 업데이트하는 방법을 원했습니다.
구현 방식은 간단했습니다. 도구를 시작하면 "외부 쉘"이됩니다. 이 외부 쉘은 두 가지 매우 간단한 작업을 수행합니다.
svn update
자체 및 구성 파일- 이번에는 실제로 하나의 구성을 처리 한 다음 다시 종료되는 "내부 쉘"로 다시 시작됩니다.
이 매우 간단한 update-myself-in-a-loop 시스템은 몇 달 동안 우리에게 아주 잘 봉사했습니다. 자체 포함되어 있기 때문에 매우 우아합니다. 자동 업데이트 프로그램은 프로그램 자체입니다. "outer shell"(자동 업데이트 부분)은 매우 간단하기 때문에 "inner shell"(매번 업데이트 된 소스 파일에서 실행 됨)만큼 업데이트의 이점을 얻지 못하는 것은 중요하지 않습니다.
실제로 언급되지 않은 한 가지는 프로그램을 실행하는 사용자가 실제로 업그레이드 할 충분한 권한이 없을 수도 있다는 점을 진지하게 고려해야한다는 것입니다. 이것은 적어도 비즈니스 사용자에게는 꽤 일반적이며 가정 사용자에게는 덜 일반적입니다.
I'm always working with a (self-imposed) limited account for security reasons and it always pisses me off that most auto-updaters simply assume that I'm running as admin and then after downloading just fail and offer no other way of performing the update other than actually closing the program and running it again in an administrative context. Most do not even cache the downloaded update and have to do it all over again.
It'd be much better if the auto-updater would simply prompt for admin credentials when needed and get on with it.
Because auto updating is a common scenario, most languages have at least one package available to support this. (Below I list some of the available packages)
One of the really nice idea's is the ClickOnce distribution for .NET, it's an installer which sandboxes your application and installs in the user context, so no administrator rights required. You can configure the ClickOnce in your publish to check for updates each application start.
Java has Java Web Start which offers the same kind of functionality for java applets.
Delphi has numerous articles about auto-updating, Torry has a list of WebUpdate components, for instance GoUpdater seems to have a very wide range of functionality.
They all use a website/network share to check for a new version and than retrieve either a patch or a complete install file and run it. So you should try to find a nice package for your application, to save you the hassle of developing and maintaining your own solution.
I'm going to assume answer for Windows.
This way seems to work well.
In the installer do:
1. Create a manual-start service that runs as LocalSystem that when started does the update then stops.
2. Change the service permissions so all users can start the service (if all users should be able to update w/o admin rights).
3. Change the main program to check for updates when started using a simple mechanism. If it detects an update, prompt if the user wants to apply it.
4. If user accepts the update, start the service.
If the architecture allows for it, create a way to monitor the update as it is running.
In a Java-Webstart setting you start a JNLP file which then triggers the download of the Jar files needed to run the application. Everytime webstart checks if there are newer versions of the Jars and would download them replacing the locally cached ones. With a tool named jardiff you will create only diffs towards the newer jars and distribute these via the server (e.g. only get an update).
Pros:
- always up to date
Cons:
- you need an application server (tomcat, JBoss) in order to distribute the files
- you need an internet connection in order to get the application
Reading Carl Seleborgs answer gave me some ideas how a generic code-repository could be useful.
svn comes with a tool called svnsync, which sort of behaves like an svn export but keeps track of the actual revision your export is at.
Someone could utilize this system in order to only fetch the changed files from the users actual revision.
In actuality, you will have a repository with the binaries compiled, and running svnsync will only fetch the binaries that has been modified. It might also be able to merge local changes to text-based configuration files with new configuration-options.
The function of installing a patch to a program is basically one of the basic functions of an installer. Installer software is documented in numerous places but usually on a per-installer basis: There the Microsoft Installer (with Install Shield Extensions), Ruby gems, Java .jar files, the various Linux package manager systems (RPM, Apt-get)and others.
These are all complex systems which solve the problem of patching program in general but for slightly different systems. To decide what is best for you, consider which of these system your application most resembles. Rolling your own is fine but looking at these systems is a place to start.
You can write an internal module of your application to do updates. You can write an external mini application to do updates.
Also look at .NET on-the-fly compilation technology, it makes possible to create such mini application on-the-fly on demand. For example, http://fly.sf.net/
You can use my solution (part of the Target Eye project). http://www.codeproject.com/Articles/310530/Target-Eye-Revealed-part-Target-Eyes-Unique-Auto
If your software is open sourced, and target Linux or developers. It is interesting to install your software as a git repo. And having it pull the stable branch occasionally or everytime when it is launched.
This is particular easy when your application is managed via npm, sbt, mavan, stack, elm-package or alike.
If you are searching for an cross-platform software update solution, take a look at www.updatenode.com
Some highlights:
- free for Open Source projects
- cross-platform & Open Source update client tool
- localized already for the most important languages
- easy to integrate and easy to handle
- cloud based management platform to define and manage updates
- provides additionally support for displaying messages (inform about new events, products, etc.)
- web interface is open (you can create your own client using the service)
- many usage statistics, as used operating systems, geo location, version usage, etc.
- Android API for mobile App updates
Just try it.
BTW, I am part of the dev team for the open source client. :)
참고URL : https://stackoverflow.com/questions/232347/how-should-i-implement-an-auto-updater
'Programing' 카테고리의 다른 글
Mock MVC-테스트 할 요청 매개 변수 추가 (0) | 2020.11.25 |
---|---|
Mocha에서 describe ()의 역할은 무엇입니까? (0) | 2020.11.25 |
PowerShell에서 "종료"란 정확히 무엇입니까? (0) | 2020.11.25 |
저장 프로 시저 대. (0) | 2020.11.25 |
유니폼의 GLSL 배열 만들기? (0) | 2020.11.25 |