Post

[WinSparkle] 프로그램 자동 업데이트

요즘에는 거의 모든 프로그램에서 자동 업데이트 기능을 제공하고 있습니다.

저의 경우 2008년도 SI 프로젝트에서 자동 업데이트 기능을 직접 구현하여 사용하였고, 또 그 시절 데브피아에서는 어떤 분이 자동 업데이트 기능을 판매하기도 했었습니다. 최근 회사 프로그램에서도 직접 자동 업데이트 기능을 구현하여 사용하였습니다.

이제는 맥에서 사용하던 자동 업데이트 프로그램인 Sparkle을 윈도우즈에서도 사용할 수 있습니다. 더 이상 자동 업데이트 기능을 구현할 필요가 없습니다.

Sparkle이 윈도우즈로 포팅되면서 여러 변종이 생겨났습니다.

C#/.NET에서 사용 가능한 NetSparkle 그리고 좀 더 간단하게 사용 가능한 WinSparkle(https://winsparkle.org/)이 있습니다.

1
2
3
4
WinSparkle
WinSparkle: Easy updates on Windows WinSparkle is an easy-to-use software update library for Windows developers. It's Open Source, available under the permissive MIT license. Sparkle for Windows WinSparkle is a heavily (to the point of being its almost-port) inspired by the Sparkle framework origina...

winsparkle.org

WinSparkle에서는 아래 언어에 대한 바인딩을 지원합니다.

C#/.NET, Python, Go, Pascal

현재 진행하고 있는 프로젝트의 고객사에서 자동 업데이트 기능을 요구해 왔습니다.

해당 프로젝트가 Python으로 구현되어 Python 바인딩을 지원하는 WinSparkle을 이용하여 해당 기능을 구현하기로 했습니다.

먼저 Python 바인딩인 pywinsparkle을 설치합니다.

1
2
3
4
pywinsparkle
A python wrapper for the winsparkle project

pypi.org

에 가시면 예제 코드가 있습니다. 이 코드를 이용하면 아주 간단하게 프로그램에 자동 업데이트 기능을 추가할 수 있습니다.

이제 자동 업데이트 정보를 XML 파일에 저장하여 서버에 올려놓으면 프로그램 실행 시(구현에 따라 다름)에 최신 버전으로 자동 업데이트할 수 있습니다.

아래는 XML 파일 예제입니다. 여기서 중요한 부분은 릴리즈 노트(sparkle:releaseNotesLink), 설치 프로그램 위치(url), 버전(sparkle:version)입니다.
실행 프로그램 버전과 XML의 버전을 확인하여 최신 버전이 있으면 릴리즈 노트를 보여주고 사용자가 최신 프로그램을 설치할 수 있도록 합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle">
    <channel>
        <title>WinSparkle Test Appcast</title>
        <description>Most recent updates to WinSparkle Test</description>
        <language>en</language>
        <item>
            <title>Version 1.5.5880</title>
            <sparkle:releaseNotesLink> https://your_domain/your_path/release_notes.html </sparkle:releaseNotesLink>
            <pubDate>Fri, 06 Feb 2016 22:49:00 +0100</pubDate>
            <enclosure url="https://your_domain/your_path/setup.exe" parkle:dsaSignature="MEQCICh10SofkNHa5iJgVWDi2O8RBYyN+nxkFEL7u/tBuWboAiB6VOV/WQMRJE+kRoICZXAhq5b24WkgqcDs0z7gyBkGVw=="
            sparkle:version="1.5.5880"
            length="0"
            type="application/octet-stream" />
        </item>
    </channel>
</rss>

위 예제에서 뭔가 중요해 보이는 sparkle:dsaSignature라는 항목이 있습니다. 이 부분은 설치 파일의 변조를 방지하는 데 사용됩니다.

WinSparkle 웹페이지에서 다운받아 압축 해제하면 bin 폴더에 generate_keys.bat, sign_update.bat이 있습니다. 참고로 배치 파일을 실행하기 위해서는 openssl.exe 파일이 필요합니다.

generate_keys.bat를 실행하면 dsa_pub.pem, dsa_priv.pem 파일이 생성됩니다. 생성한 파일들을 잘 보관하시기 바랍니다.

서버로 올릴 설치 프로그램과 앞서 생성한 dsa_priv.pem 파일을 이용하여 Signature 생성합니다.

명령창에서 사각 영역 부분의 텍스트를 복사하여 XML 파일의 sparkle:dsaSignature 부분에 붙여 넣습니다.

그리고 코드에서 dsa_pub.pem 파일을 읽어 DSA 공개키를 설정합니다.

1
2
3
4
if os.path.isfile('dsa_pub.pem'):
    with open('dsa_pub.pem', 'r') as file:
        pub_key = file.read()
    pywinsparkle.win_sparkle_set_dsa_pub_pem(pub_key)

Signature 키 혹은 설치 파일이 변경되면 업데이트 오류가 발생하여 자동 업데이트가 되지 않습니다.

DSA 키를 적용하면 보안상 좋을 것 같습니다. 하지만 최신 프로그램을 배포할 때마다 Signature를 키를 생성하여 XML 파일에 적용해야 하는 불편함도 발생합니다.

Jenkins를 이용한 자동화도 힘들 것 같습니다.

따라서 DSA 키를 적용하지 않기로 하였습니다.

자동 업데이트 기능을 통하여 사용자들은 좀더 편리하게 프로그램을 업데이트할 수 있습니다.

현재(2021.4.27) pywinsparkle은 python 3.7 버전까지 지원하고 있습니다.