lastupdate.yml 파일 생성
최신 버젼을 생성하면 간단한 유틸리티를 통해 버젼 정보와 파일 해시코드를 lastupdate.yml 파일로 생성한다. 만약 기존 버젼에서 유지해야 파일(예를 드어 설정파일)이 있다면 lastupdate.yml을 프로젝트에 추가해서 그 정보를 기록할 수 있도록 한다.
온라인의 특정 경로로 복사
업데이트 프로그램 실행
프로그램은 시작 시 라이브러리의 Splash Screen을 띄우면서 최신 버젼이 있는지를 확인
최신 버젼의 확인은 lastupdate.yml의 버젼을 통해 확인
최신 버젼이 있을 경우 라이브러리는 업데이트를 진행
업데이트
라이브러리를 임시 파일로 복사 후 재실행 이때 관리자 권한이 필요할 경우 관리자 권한으로 상승해서 실행
기존 경로의 파일을 복구를 위해 백업함
lastupdate.yml을 이용해서 다운로드 할 파일과 유지해야 할 파일, 삭제해야 할 파일을 구분해서 새로운 버젼을 구축함
Files 목록을 순회하면서 해시값을 비교해 다를 경우 원격에서 복사. 같을 경우 로컬에서 복사
다음은 업데이트 정보 클래스 입니다.
[XmlRoot("Update")]
public class UpdateInfo
{
[XmlIgnore]
public Version Version { get; set; } = default!;
[XmlAttribute(nameof(Version))]
public string VersionText
{
get => Version.ToString();
set
{
Version = Version.Parse(value);
}
}
public List<File> KeepFiles { get; set; } = new List<File>();
public List<File> Files { get; set; } = new List<File>();
public bool IsLessVersionThan(UpdateInfo remote)
{
if (Version < remote.Version)
return true;
return false;
}
public IEnumerable<File> GetFiles(UpdateInfo remote)
{
foreach (var file in remote.KeepFiles)
{
file.Action = ActionKind.Keep;
yield return file;
}
foreach (var file in remote.Files)
{
var localFile = Files.FirstOrDefault(x => x.Name == file.Name);
if (localFile is null || localFile.Hash != file.Hash)
{
file.Action = ActionKind.Update;
yield return file;
}
}
foreach (var file in Files)
{
var remoteFile = remote.Files.FirstOrDefault(x => x.Name == file.Name);
if (remoteFile is null)
{
file.Action = ActionKind.Remove;
yield return file;
}
}
}
public void ToFile(string filename)
{
var serializer = new XmlSerializer(typeof(UpdateInfo));
using var xw = XmlWriter.Create(filename, new() { Indent = true });
serializer.Serialize(xw, this);
}
public static UpdateInfo FromFile(string filename)
{
var serializer = new XmlSerializer(typeof(UpdateInfo));
using var xr = XmlReader.Create(filename);
return (UpdateInfo)serializer.Deserialize(xr);
}
public static UpdateInfo FromUri(string uri)
{
var serializer = new XmlSerializer(typeof(UpdateInfo));
using var webClient = new WebClient();
var data = webClient.DownloadData(uri);
using var s = new MemoryStream(data);
return (UpdateInfo)serializer.Deserialize(s);
}
public class File
{
[XmlAttribute]
public string Name { get; set; } = default!;
[XmlAttribute]
public string Hash { get; set; } = default!;
[XmlIgnore]
public ActionKind Action { get; set; }
}
public enum ActionKind
{
Keep,
Remove,
Update
}
}