업데이트 정보 파일구조를 다음처럼 만들었습니다.
<?xml version="1.0" encoding="utf-8"?>
<Update xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Version="1.0.0">
<KeepFiles />
<Files>
<File Name="test.txt" Hash="1213131321352512341234555" />
</Files>
</Update>
유지해야 할 파일을 KeepFiles
목록에 두고 배포 파일 목록을 Files
에 둡니다.
- 현 버젼이 원격 버젼보다 낮을 경우 업데이트 진행
-
KeepFiles
목록을 그대로 새 버젼 디렉토리에 복사
-
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
}
}