更新程序 新界面,显示更新日志
This commit is contained in:
1 parent
b0af3bd106
commit
558f9bfa04
6 files changed
+1486
-401
No files matched your search
+562
-270
@@ -1,8 +1,10 @@
|
||||
using System;
|
||||
using COSXML.Network;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
@@ -12,307 +14,597 @@ using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using static Update.ChangelogTheme;
|
||||
|
||||
namespace Update
|
||||
{
|
||||
public partial class MainForm : Form
|
||||
{
|
||||
public string Title { get { return Text; } set { Text = value; } }
|
||||
private Point mouseOffset; // 记录鼠标指针的坐标
|
||||
private bool isMouseDown; // 记录鼠标左键是否按下
|
||||
public partial class MainForm : Form
|
||||
{
|
||||
public string Title { get { return Text; } set { Text = value; } }
|
||||
private Point mouseOffset; // 记录鼠标指针的坐标
|
||||
private bool isMouseDown; // 记录鼠标左键是否按下
|
||||
|
||||
public MainForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
public MainForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.TopMost = true;
|
||||
}
|
||||
this.TopMost = true;
|
||||
lb_title.Text = "更新日志";
|
||||
|
||||
private void MessageForm_Paint(object sender, PaintEventArgs e)
|
||||
{
|
||||
SetFormRoundRectRgn(this, 7);
|
||||
SetFormRoundRectRgn(panel2, 7);
|
||||
SetFormRoundRectRgn(this.btnOk, 7);
|
||||
SetFormRoundRectRgn(this.btnCancel, 7);
|
||||
}
|
||||
var changelogItems = GetChangeInfos();
|
||||
if (changelogItems != null)
|
||||
{
|
||||
|
||||
private void btnOk_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (lblMessage.Text == "升级完成,点击确定重启程序")
|
||||
{
|
||||
string extPath = System.Environment.CurrentDirectory + "\\" + Program.softName.Replace(".exe", "") + ".exe";
|
||||
System.Diagnostics.Process.Start(extPath);
|
||||
Application.Exit();
|
||||
return;
|
||||
}
|
||||
string fromVersion = (Program.oldVersion / 100m).ToString();
|
||||
string toVersion = (Program.newVersion / 100m).ToString();
|
||||
ShowChangelog(fromVersion, toVersion, changelogItems);
|
||||
}
|
||||
|
||||
btnOk.Enabled = false;
|
||||
//// 演示数据:v1.0.0 升级到 v1.3.0,展示 1.1.0 ~ 1.3.0(新的在上)
|
||||
//ShowChangelog("1.0.0", "1.3.0", new[]
|
||||
//{
|
||||
// new ChangelogItem { Version = "1.3.0", PublishedAt = "2026-10-10", Notes = "新增深色模式,支持跟随系统\n新增快捷键面板(Ctrl + /)\n启动速度提升 40%" },
|
||||
// new ChangelogItem { Version = "1.2.0", PublishedAt = "2026-09-05", Notes = "支持导出数据为 Excel 格式\n优化列表滚动性能\n修复偶发的保存失败问题" },
|
||||
// new ChangelogItem { Version = "1.1.0", PublishedAt = "2026-08-01", Notes = "新增自动更新功能\n修复高分屏下界面模糊的问题" },
|
||||
//});
|
||||
}
|
||||
private List<ChangelogItem> GetChangeInfos()
|
||||
{
|
||||
string paidanUrl = $"https://update-wx-order.e57.cn";
|
||||
string shanghuoUrl = $"https://update.e57.cn";
|
||||
using (WebClient c = new WebClient())
|
||||
{
|
||||
c.Encoding = Encoding.UTF8;
|
||||
string url = $"/api/releases/since?version={(Program.oldVersion / 100m)}&channel=stable";
|
||||
if (Program.softName == "29WxFindOrder")
|
||||
{
|
||||
url = paidanUrl + url;
|
||||
}
|
||||
else if (Program.softName == "29供应链.exe")
|
||||
url = shanghuoUrl + url;
|
||||
string json = c.DownloadString(url);
|
||||
var root = MiniJson.Json.Deserialize(json) as Dictionary<string, object>;
|
||||
if (root["ok"].ToString() == "True")
|
||||
{
|
||||
var data = (Dictionary<string, object>)root["data"];
|
||||
var versionsRaw = (List<object>)data["versions"];
|
||||
|
||||
CloseMainProgram();
|
||||
var list = new List<ChangelogItem>();
|
||||
foreach (Dictionary<string, object> item in versionsRaw)
|
||||
{
|
||||
var ci = new ChangelogItem
|
||||
{
|
||||
Version = item["version"]?.ToString(),
|
||||
Notes = item["notes"]?.ToString(),
|
||||
};
|
||||
|
||||
if (!System.IO.Directory.Exists("upBak"))
|
||||
System.IO.Directory.CreateDirectory("upBak");
|
||||
var upBakPath = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "upBak";
|
||||
if (!System.IO.Directory.Exists("upTemp"))
|
||||
System.IO.Directory.CreateDirectory("upTemp");
|
||||
var upTempPath = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "upTemp";
|
||||
if (DateTime.TryParse(item["publishedAt"]?.ToString(), out DateTime v))
|
||||
{
|
||||
ci.PublishedAt = v.ToString("yyyy-MM-dd");
|
||||
}
|
||||
list.Add(ci);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// 清空文件夹准备下载
|
||||
foreach (string filePath in Directory.GetFiles(upTempPath))
|
||||
{
|
||||
File.Delete(filePath); // 删除文件
|
||||
}
|
||||
foreach (string dirPath in Directory.GetDirectories(upTempPath))
|
||||
{
|
||||
Directory.Delete(dirPath, true); // 删除子文件夹及其内容
|
||||
}
|
||||
/// <summary>
|
||||
/// 渲染更新日志:头部展示版本区间,中间按版本分组列出更新条目
|
||||
/// </summary>
|
||||
private void ShowChangelog(string fromVersion, string toVersion, IEnumerable<ChangelogItem> entries)
|
||||
{
|
||||
int length = entries.Count();
|
||||
lblHeroTitle.Text = "v" + fromVersion + " → v" + toVersion;
|
||||
lblHeroMeta.Text = length > 1 ? "共包含 " + length + " 个版本的更新内容" : "本次更新内容";
|
||||
|
||||
this.lblMessage.Text = "升级中请稍候...";
|
||||
progressBar1.Visible = true;
|
||||
progressBar1.Maximum = 100;//fileNameArr.Count();
|
||||
progressBar1.Value = 0;
|
||||
Task.Run(async() =>
|
||||
{
|
||||
string tempFile = upTempPath + "\\" + Program.updateUrl.Substring(Program.updateUrl.LastIndexOf("/") + 1);
|
||||
//bool result = Program.DownloadFile(Program.updateUrl, tempFile);
|
||||
panelChangelog.SuspendLayout();
|
||||
panelChangelog.Controls.Clear();
|
||||
|
||||
//while (true)
|
||||
//{
|
||||
// Invoke(new Action(() =>
|
||||
// {
|
||||
// progressBar1.Value = Program.progress;
|
||||
// }));
|
||||
// if (Program.progress == 100)
|
||||
// break;
|
||||
//}
|
||||
var blocks = entries.Select((entry, i) => new ChangelogBlock(entry, i == 0, panelChangelog.Width)).ToList();
|
||||
int contentHeight = blocks.Sum(b => b.Height);
|
||||
|
||||
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
|
||||
using (var downloadClient = new WebClient())
|
||||
{
|
||||
downloadClient.Proxy = null;
|
||||
// 内容超出可视区时预留垂直滚动条宽度,避免出现横向滚动条
|
||||
int width = panelChangelog.ClientSize.Width;
|
||||
if (contentHeight > panelChangelog.ClientSize.Height)
|
||||
width -= SystemInformation.VerticalScrollBarWidth;
|
||||
|
||||
downloadClient.DownloadProgressChanged += (s, args) =>
|
||||
{
|
||||
Invoke(new Action(() => { progressBar1.Value = args.ProgressPercentage; }));
|
||||
|
||||
};
|
||||
int y = 6;
|
||||
foreach (var block in blocks)
|
||||
{
|
||||
block.Width = width;
|
||||
block.Location = new Point(0, y);
|
||||
y += block.Height;
|
||||
panelChangelog.Controls.Add(block);
|
||||
}
|
||||
panelChangelog.ResumeLayout(true);
|
||||
}
|
||||
|
||||
await downloadClient.DownloadFileTaskAsync(new Uri(Program.updateUrl), tempFile);
|
||||
}
|
||||
private void heroPanel_Paint(object sender, PaintEventArgs e)
|
||||
{
|
||||
var panel = (Panel)sender;
|
||||
if (panel.Width <= 0 || panel.Height <= 0)
|
||||
return;
|
||||
|
||||
if (1 == 1)
|
||||
//if (result)
|
||||
{
|
||||
ZipFile.ExtractToDirectory(tempFile, upTempPath);
|
||||
File.Delete(tempFile);
|
||||
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
|
||||
using (var brush = new LinearGradientBrush(panel.ClientRectangle, AccentBg, Color.White, 40F))
|
||||
e.Graphics.FillRectangle(brush, panel.ClientRectangle);
|
||||
|
||||
string mainPath = System.Environment.CurrentDirectory;
|
||||
// 备份旧文件
|
||||
foreach (string filePath in Directory.GetFiles(upTempPath))
|
||||
{
|
||||
try
|
||||
{
|
||||
string fileName = filePath.Substring(filePath.LastIndexOf("\\") + 1);
|
||||
File.Copy(mainPath + "\\" + fileName, upBakPath + "\\" + fileName, true);
|
||||
Thread.Sleep(10);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
foreach (string dirPath in Directory.GetDirectories(upTempPath))
|
||||
{
|
||||
try
|
||||
{
|
||||
string fileName = dirPath.Substring(dirPath.LastIndexOf("\\") + 1);
|
||||
CopyDirectory(mainPath + "\\" + fileName, upBakPath + "\\" + fileName);
|
||||
Thread.Sleep(10);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
using (var pen = new Pen(LineColor))
|
||||
{
|
||||
e.Graphics.DrawLine(pen, 0, 0, panel.Width, 0);
|
||||
e.Graphics.DrawLine(pen, 0, panel.Height - 1, panel.Width, panel.Height - 1);
|
||||
}
|
||||
}
|
||||
|
||||
string error = "";
|
||||
// 替换旧文件
|
||||
foreach (string filePath in Directory.GetFiles(upTempPath))
|
||||
{
|
||||
if (!string.IsNullOrEmpty(error))
|
||||
{
|
||||
error = "发生错误:\r\n" + error + "\r\n请关闭升级窗口重试!";
|
||||
break;
|
||||
}
|
||||
try
|
||||
{
|
||||
string fileName = filePath.Substring(filePath.LastIndexOf("\\") + 1);
|
||||
File.Copy(upTempPath + "\\" + fileName, mainPath + "\\" + fileName, true);
|
||||
Thread.Sleep(10);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
error = "发生错误:\r\n" + ex.Message + "\r\n请关闭升级窗口重试!";
|
||||
Invoke(new Action(() =>
|
||||
{
|
||||
lblMessage.Text = error;
|
||||
}));
|
||||
}
|
||||
}
|
||||
foreach (string dirPath in Directory.GetDirectories(upTempPath))
|
||||
{
|
||||
if (!string.IsNullOrEmpty(error))
|
||||
break;
|
||||
try
|
||||
{
|
||||
string fileName = dirPath.Substring(dirPath.LastIndexOf("\\") + 1);
|
||||
CopyDirectory(upTempPath + "\\" + fileName, mainPath + "\\" + fileName);
|
||||
Thread.Sleep(10);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
error = "发生错误:\r\n" + ex.Message + "\r\n请关闭升级窗口重试!";
|
||||
Invoke(new Action(() =>
|
||||
{
|
||||
lblMessage.Text = error;
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
Thread.Sleep(50);
|
||||
Invoke(new Action(() =>
|
||||
{
|
||||
if (string.IsNullOrEmpty(error))
|
||||
{
|
||||
progressBar1.Value = 100;
|
||||
lblMessage.Text = "升级完成,点击确定重启程序";
|
||||
btnOk.Enabled = true;
|
||||
}
|
||||
}));
|
||||
}
|
||||
else
|
||||
{
|
||||
Invoke(new Action(() =>
|
||||
{
|
||||
progressBar1.Value = 100;
|
||||
this.lblMessage.Text = "升级失败,未获取到升级文件";
|
||||
btnOk.Enabled = true;
|
||||
}));
|
||||
}
|
||||
});
|
||||
}
|
||||
private void btnOk_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (lblMessage.Text == "升级完成,点击确定重启程序")
|
||||
{
|
||||
string extPath = System.Environment.CurrentDirectory + "\\" + Program.softName.Replace(".exe", "") + ".exe";
|
||||
System.Diagnostics.Process.Start(extPath);
|
||||
Application.Exit();
|
||||
return;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 拷贝文档目录
|
||||
/// </summary>
|
||||
/// <param name="srcPath"></param>
|
||||
/// <param name="destPath"></param>
|
||||
public static void CopyDirectory(string srcPath, string destPath)
|
||||
{
|
||||
try
|
||||
{
|
||||
DirectoryInfo dir = new DirectoryInfo(srcPath);
|
||||
FileSystemInfo[] fileinfo = dir.GetFileSystemInfos(); //获取目录下(不包含子目录)的文件和子目录
|
||||
foreach (FileSystemInfo i in fileinfo)
|
||||
{
|
||||
if (i is DirectoryInfo) //判断是否文件夹
|
||||
{
|
||||
if (!Directory.Exists(destPath + "\\" + i.Name))
|
||||
{
|
||||
Directory.CreateDirectory(destPath + "\\" + i.Name); //目标目录下不存在此文件夹即创建子文件夹
|
||||
}
|
||||
CopyDirectory(i.FullName, destPath + "\\" + i.Name); //递归调用复制子文件夹
|
||||
}
|
||||
else
|
||||
{
|
||||
File.Copy(i.FullName, destPath + "\\" + i.Name, true); //不是文件夹即复制文件,true表示可以覆盖同名文件
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
btnOk.Enabled = false;
|
||||
|
||||
private void btnCancel_Click(object sender, EventArgs e)
|
||||
{
|
||||
this.Close();
|
||||
}
|
||||
CloseMainProgram();
|
||||
|
||||
private void panel1_MouseDown(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (e.Button == MouseButtons.Left)
|
||||
{
|
||||
mouseOffset = new Point(-e.X, -e.Y);
|
||||
isMouseDown = true;
|
||||
}
|
||||
}
|
||||
if (!System.IO.Directory.Exists("upBak"))
|
||||
System.IO.Directory.CreateDirectory("upBak");
|
||||
var upBakPath = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "upBak";
|
||||
if (!System.IO.Directory.Exists("upTemp"))
|
||||
System.IO.Directory.CreateDirectory("upTemp");
|
||||
var upTempPath = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "upTemp";
|
||||
|
||||
private void panel1_MouseUp(object sender, MouseEventArgs e)
|
||||
{
|
||||
isMouseDown = false;
|
||||
}
|
||||
// 清空文件夹准备下载
|
||||
foreach (string filePath in Directory.GetFiles(upTempPath))
|
||||
{
|
||||
File.Delete(filePath); // 删除文件
|
||||
}
|
||||
foreach (string dirPath in Directory.GetDirectories(upTempPath))
|
||||
{
|
||||
Directory.Delete(dirPath, true); // 删除子文件夹及其内容
|
||||
}
|
||||
|
||||
private void panel1_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (isMouseDown)
|
||||
{
|
||||
// 获取鼠标的位置
|
||||
Point mousePos = MousePosition;
|
||||
mousePos.Offset(mouseOffset.X, mouseOffset.Y);
|
||||
Location = mousePos;
|
||||
}
|
||||
}
|
||||
this.lblMessage.Text = "升级中请稍候...";
|
||||
progressBar1.Visible = true;
|
||||
progressBar1.Maximum = 100;//fileNameArr.Count();
|
||||
progressBar1.Value = 0;
|
||||
Task.Run(async () =>
|
||||
{
|
||||
string tempFile = upTempPath + "\\" + Program.updateUrl.Substring(Program.updateUrl.LastIndexOf("/") + 1);
|
||||
//bool result = Program.DownloadFile(Program.updateUrl, tempFile);
|
||||
|
||||
public static void SetFormRoundRectRgn(Control c, int rgnRadius)
|
||||
{
|
||||
int hRgn = 0;
|
||||
hRgn = Win32.CreateRoundRectRgn(0, 0, c.Width + 1, c.Height + 1, rgnRadius, rgnRadius);
|
||||
Win32.SetWindowRgn(c.Handle, hRgn, true);
|
||||
Win32.DeleteObject(hRgn);
|
||||
}
|
||||
//while (true)
|
||||
//{
|
||||
// Invoke(new Action(() =>
|
||||
// {
|
||||
// progressBar1.Value = Program.progress;
|
||||
// }));
|
||||
// if (Program.progress == 100)
|
||||
// break;
|
||||
//}
|
||||
|
||||
private void btnClose_Click(object sender, EventArgs e)
|
||||
{
|
||||
Application.Exit();
|
||||
}
|
||||
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
|
||||
using (var downloadClient = new WebClient())
|
||||
{
|
||||
downloadClient.Proxy = null;
|
||||
|
||||
private void CloseMainProgram()
|
||||
{
|
||||
string in_sAppName = Program.softName; //(一个word文档程序)
|
||||
in_sAppName = in_sAppName.Replace(".exe", "");
|
||||
downloadClient.DownloadProgressChanged += (s, args) =>
|
||||
{
|
||||
Invoke(new Action(() => { progressBar1.Value = args.ProgressPercentage; }));
|
||||
|
||||
try
|
||||
{
|
||||
System.Diagnostics.Process[] psiNewcas = System.Diagnostics.Process.GetProcessesByName(in_sAppName);
|
||||
//System.Diagnostics.Process.GetProcessesByName("");
|
||||
};
|
||||
|
||||
//var pro = System.Diagnostics.Process.GetProcesses();
|
||||
//foreach(var p in pro)
|
||||
//{
|
||||
// Console.WriteLine(p.ProcessName);
|
||||
//}
|
||||
await downloadClient.DownloadFileTaskAsync(new Uri(Program.updateUrl), tempFile);
|
||||
}
|
||||
|
||||
foreach (System.Diagnostics.Process p in psiNewcas)
|
||||
{
|
||||
p.Kill();
|
||||
//p.WaitForExit();
|
||||
//p.Close();
|
||||
//Console.WriteLine(in_sAppName + "已经停止了");
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
Console.WriteLine(in_sAppName + "停止失败");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (1 == 1)
|
||||
//if (result)
|
||||
{
|
||||
ZipFile.ExtractToDirectory(tempFile, upTempPath);
|
||||
File.Delete(tempFile);
|
||||
|
||||
public enum FormLevel
|
||||
{
|
||||
SMALL,
|
||||
MEDIUM,
|
||||
LARGE = 500
|
||||
}
|
||||
string mainPath = System.Environment.CurrentDirectory;
|
||||
// 备份旧文件
|
||||
foreach (string filePath in Directory.GetFiles(upTempPath))
|
||||
{
|
||||
try
|
||||
{
|
||||
string fileName = filePath.Substring(filePath.LastIndexOf("\\") + 1);
|
||||
File.Copy(mainPath + "\\" + fileName, upBakPath + "\\" + fileName, true);
|
||||
Thread.Sleep(10);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
foreach (string dirPath in Directory.GetDirectories(upTempPath))
|
||||
{
|
||||
try
|
||||
{
|
||||
string fileName = dirPath.Substring(dirPath.LastIndexOf("\\") + 1);
|
||||
CopyDirectory(mainPath + "\\" + fileName, upBakPath + "\\" + fileName);
|
||||
Thread.Sleep(10);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
string error = "";
|
||||
// 替换旧文件
|
||||
foreach (string filePath in Directory.GetFiles(upTempPath))
|
||||
{
|
||||
if (!string.IsNullOrEmpty(error))
|
||||
{
|
||||
error = "发生错误:\r\n" + error + "\r\n请关闭升级窗口重试!";
|
||||
break;
|
||||
}
|
||||
try
|
||||
{
|
||||
string fileName = filePath.Substring(filePath.LastIndexOf("\\") + 1);
|
||||
File.Copy(upTempPath + "\\" + fileName, mainPath + "\\" + fileName, true);
|
||||
Thread.Sleep(10);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
error = "发生错误:\r\n" + ex.Message + "\r\n请关闭升级窗口重试!";
|
||||
Invoke(new Action(() =>
|
||||
{
|
||||
lblMessage.Text = error;
|
||||
}));
|
||||
}
|
||||
}
|
||||
foreach (string dirPath in Directory.GetDirectories(upTempPath))
|
||||
{
|
||||
if (!string.IsNullOrEmpty(error))
|
||||
break;
|
||||
try
|
||||
{
|
||||
string fileName = dirPath.Substring(dirPath.LastIndexOf("\\") + 1);
|
||||
CopyDirectory(upTempPath + "\\" + fileName, mainPath + "\\" + fileName);
|
||||
Thread.Sleep(10);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
error = "发生错误:\r\n" + ex.Message + "\r\n请关闭升级窗口重试!";
|
||||
Invoke(new Action(() =>
|
||||
{
|
||||
lblMessage.Text = error;
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
Thread.Sleep(50);
|
||||
Invoke(new Action(() =>
|
||||
{
|
||||
if (string.IsNullOrEmpty(error))
|
||||
{
|
||||
progressBar1.Value = 100;
|
||||
lblMessage.Text = "升级完成,点击确定重启程序";
|
||||
btnOk.Enabled = true;
|
||||
}
|
||||
}));
|
||||
}
|
||||
else
|
||||
{
|
||||
Invoke(new Action(() =>
|
||||
{
|
||||
progressBar1.Value = 100;
|
||||
this.lblMessage.Text = "升级失败,未获取到升级文件";
|
||||
btnOk.Enabled = true;
|
||||
}));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 拷贝文档目录
|
||||
/// </summary>
|
||||
/// <param name="srcPath"></param>
|
||||
/// <param name="destPath"></param>
|
||||
public static void CopyDirectory(string srcPath, string destPath)
|
||||
{
|
||||
try
|
||||
{
|
||||
DirectoryInfo dir = new DirectoryInfo(srcPath);
|
||||
FileSystemInfo[] fileinfo = dir.GetFileSystemInfos(); //获取目录下(不包含子目录)的文件和子目录
|
||||
foreach (FileSystemInfo i in fileinfo)
|
||||
{
|
||||
if (i is DirectoryInfo) //判断是否文件夹
|
||||
{
|
||||
if (!Directory.Exists(destPath + "\\" + i.Name))
|
||||
{
|
||||
Directory.CreateDirectory(destPath + "\\" + i.Name); //目标目录下不存在此文件夹即创建子文件夹
|
||||
}
|
||||
CopyDirectory(i.FullName, destPath + "\\" + i.Name); //递归调用复制子文件夹
|
||||
}
|
||||
else
|
||||
{
|
||||
File.Copy(i.FullName, destPath + "\\" + i.Name, true); //不是文件夹即复制文件,true表示可以覆盖同名文件
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private void btnCancel_Click(object sender, EventArgs e)
|
||||
{
|
||||
this.Close();
|
||||
}
|
||||
|
||||
private void panel1_MouseDown(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (e.Button == MouseButtons.Left)
|
||||
{
|
||||
mouseOffset = new Point(-e.X, -e.Y);
|
||||
isMouseDown = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void panel1_MouseUp(object sender, MouseEventArgs e)
|
||||
{
|
||||
isMouseDown = false;
|
||||
}
|
||||
|
||||
private void panel1_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (isMouseDown)
|
||||
{
|
||||
// 获取鼠标的位置
|
||||
Point mousePos = MousePosition;
|
||||
mousePos.Offset(mouseOffset.X, mouseOffset.Y);
|
||||
Location = mousePos;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void btnClose_Click(object sender, EventArgs e)
|
||||
{
|
||||
Application.Exit();
|
||||
}
|
||||
|
||||
private void CloseMainProgram()
|
||||
{
|
||||
string in_sAppName = Program.softName; //(一个word文档程序)
|
||||
in_sAppName = in_sAppName.Replace(".exe", "");
|
||||
|
||||
try
|
||||
{
|
||||
System.Diagnostics.Process[] psiNewcas = System.Diagnostics.Process.GetProcessesByName(in_sAppName);
|
||||
//System.Diagnostics.Process.GetProcessesByName("");
|
||||
|
||||
//var pro = System.Diagnostics.Process.GetProcesses();
|
||||
//foreach(var p in pro)
|
||||
//{
|
||||
// Console.WriteLine(p.ProcessName);
|
||||
//}
|
||||
|
||||
foreach (System.Diagnostics.Process p in psiNewcas)
|
||||
{
|
||||
p.Kill();
|
||||
//p.WaitForExit();
|
||||
//p.Close();
|
||||
//Console.WriteLine(in_sAppName + "已经停止了");
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
Console.WriteLine(in_sAppName + "停止失败");
|
||||
}
|
||||
}
|
||||
|
||||
private void panel2_Paint(object sender, PaintEventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
public class Changelog
|
||||
{
|
||||
public bool Ok { get; set; }
|
||||
public ChangelogData Data { get; set; }
|
||||
}
|
||||
public class ChangelogData
|
||||
{
|
||||
public List<ChangelogItem> versions { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// 单个版本的更新日志
|
||||
/// </summary>
|
||||
public class ChangelogItem
|
||||
{
|
||||
public string Version { get; set; }
|
||||
public string PublishedAt { get; set; }
|
||||
public string Notes { get; set; }
|
||||
|
||||
public string[] Items
|
||||
{
|
||||
get
|
||||
{
|
||||
string[] temp = new string[0];
|
||||
if (string.IsNullOrEmpty(Notes)) return temp;
|
||||
return Notes.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新日志中的单个版本区块:版本标题行(色条 + 版本号 + 最新标记 + 日期)与条目列表
|
||||
/// </summary>
|
||||
public class ChangelogBlock : Panel
|
||||
{
|
||||
private const int LeftPad = 28;
|
||||
private const int RightPad = 28;
|
||||
private const int BarWidth = 3;
|
||||
private const int BarHeight = 16;
|
||||
private const int TextLeft = 55; // 条目文字左边,留出圆点位置
|
||||
private const int ItemPadding = 5; // 条目上下内边距
|
||||
private const int BottomGap = 20; // 区块底部留白
|
||||
private const int HeaderHeight = 28;
|
||||
|
||||
private readonly bool isNewest;
|
||||
private readonly Font versionFont = new Font("微软雅黑", 12F, FontStyle.Bold);
|
||||
private readonly Font dateFont = new Font("微软雅黑", 9F);
|
||||
private readonly Font badgeFont = new Font("微软雅黑", 8.5F);
|
||||
private readonly Font itemFont = new Font("微软雅黑", 10.5F);
|
||||
private readonly Size versionSize;
|
||||
private readonly Size dateSize;
|
||||
private readonly List<System.Windows.Forms.Label> lblItems = new List<System.Windows.Forms.Label>();
|
||||
private readonly System.Windows.Forms.Label lblVersion = new System.Windows.Forms.Label();
|
||||
private readonly System.Windows.Forms.Label lblDate = new System.Windows.Forms.Label();
|
||||
private Rectangle badgeRect = Rectangle.Empty;
|
||||
private Rectangle barRect = Rectangle.Empty;
|
||||
private readonly List<Point> bulletPoints = new List<Point>();
|
||||
private int laidOutWidth = -1;
|
||||
|
||||
public ChangelogBlock(ChangelogItem entry, bool isNewest, int width)
|
||||
{
|
||||
this.isNewest = isNewest;
|
||||
BackColor = Color.White;
|
||||
DoubleBuffered = true;
|
||||
|
||||
versionSize = TextRenderer.MeasureText("v" + entry.Version, versionFont);
|
||||
dateSize = TextRenderer.MeasureText(entry.PublishedAt, dateFont);
|
||||
|
||||
lblVersion.Font = versionFont;
|
||||
lblVersion.ForeColor = Accent;
|
||||
lblVersion.BackColor = Color.White;
|
||||
lblVersion.Text = "v" + entry.Version;
|
||||
Controls.Add(lblVersion);
|
||||
|
||||
lblDate.Font = dateFont;
|
||||
lblDate.ForeColor = SubColor;
|
||||
lblDate.BackColor = Color.White;
|
||||
lblDate.Text = entry.PublishedAt;
|
||||
Controls.Add(lblDate);
|
||||
|
||||
foreach (string item in entry.Items)
|
||||
{
|
||||
var label = new System.Windows.Forms.Label
|
||||
{
|
||||
Font = itemFont,
|
||||
ForeColor = TextColor,
|
||||
BackColor = Color.White,
|
||||
Padding = new Padding(0, ItemPadding, 0, ItemPadding),
|
||||
Text = item
|
||||
};
|
||||
lblItems.Add(label);
|
||||
Controls.Add(label);
|
||||
}
|
||||
|
||||
Width = width;
|
||||
}
|
||||
|
||||
protected override void OnResize(EventArgs eventargs)
|
||||
{
|
||||
base.OnResize(eventargs);
|
||||
LayoutContent(Width);
|
||||
}
|
||||
|
||||
private void LayoutContent(int width)
|
||||
{
|
||||
if (width <= 0 || width == laidOutWidth)
|
||||
return;
|
||||
laidOutWidth = width;
|
||||
|
||||
SuspendLayout();
|
||||
|
||||
barRect = new Rectangle(LeftPad, (HeaderHeight - BarHeight) / 2, BarWidth, BarHeight);
|
||||
lblVersion.SetBounds(LeftPad + BarWidth + 8, (HeaderHeight - versionSize.Height) / 2, versionSize.Width, versionSize.Height);
|
||||
|
||||
badgeRect = Rectangle.Empty;
|
||||
int headerRight = lblVersion.Right;
|
||||
if (isNewest)
|
||||
{
|
||||
Size badgeSize = TextRenderer.MeasureText("最新", badgeFont, Size.Empty, TextFormatFlags.NoPadding);
|
||||
badgeRect = new Rectangle(headerRight + 8, (HeaderHeight - 18) / 2, badgeSize.Width + 16, 18);
|
||||
headerRight = badgeRect.Right;
|
||||
}
|
||||
|
||||
lblDate.SetBounds(Math.Max(headerRight + 8, width - RightPad - dateSize.Width),
|
||||
(HeaderHeight - dateSize.Height) / 2, dateSize.Width, dateSize.Height);
|
||||
|
||||
int lineHeight = TextRenderer.MeasureText("中", itemFont, Size.Empty, TextFormatFlags.NoPadding).Height;
|
||||
int textWidth = Math.Max(60, width - TextLeft - RightPad);
|
||||
bulletPoints.Clear();
|
||||
int y = HeaderHeight;
|
||||
foreach (var label in lblItems)
|
||||
{
|
||||
int measured = TextRenderer.MeasureText(label.Text, itemFont, new Size(textWidth, 0), TextFormatFlags.WordBreak).Height;
|
||||
label.SetBounds(TextLeft, y, textWidth, measured + ItemPadding * 2);
|
||||
bulletPoints.Add(new Point(TextLeft - 14, y + ItemPadding + lineHeight / 2));
|
||||
y += label.Height;
|
||||
}
|
||||
|
||||
Height = y + BottomGap;
|
||||
ResumeLayout(false);
|
||||
}
|
||||
|
||||
protected override void OnPaint(PaintEventArgs e)
|
||||
{
|
||||
base.OnPaint(e);
|
||||
Graphics g = e.Graphics;
|
||||
g.SmoothingMode = SmoothingMode.AntiAlias;
|
||||
|
||||
using (var path = RoundedRect(barRect, BarWidth / 2f))
|
||||
using (var brush = new SolidBrush(Accent))
|
||||
g.FillPath(brush, path);
|
||||
|
||||
if (isNewest && badgeRect.Width > 0)
|
||||
{
|
||||
using (var path = RoundedRect(badgeRect, badgeRect.Height / 2f))
|
||||
using (var brush = new SolidBrush(Accent))
|
||||
g.FillPath(brush, path);
|
||||
TextRenderer.DrawText(g, "最新", badgeFont, badgeRect, Color.White,
|
||||
TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter | TextFormatFlags.NoPadding);
|
||||
}
|
||||
|
||||
using (var dot = new SolidBrush(Accent))
|
||||
foreach (Point p in bulletPoints)
|
||||
g.FillEllipse(dot, p.X - 3, p.Y - 3, 6, 6);
|
||||
}
|
||||
|
||||
private static GraphicsPath RoundedRect(Rectangle rect, float radius)
|
||||
{
|
||||
var path = new GraphicsPath();
|
||||
float d = radius * 2;
|
||||
path.AddArc(rect.X, rect.Y, d, d, 180, 90);
|
||||
path.AddArc(rect.Right - d, rect.Y, d, d, 270, 90);
|
||||
path.AddArc(rect.Right - d, rect.Bottom - d, d, d, 0, 90);
|
||||
path.AddArc(rect.X, rect.Bottom - d, d, d, 90, 90);
|
||||
path.CloseFigure();
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
public enum FormLevel
|
||||
{
|
||||
SMALL,
|
||||
MEDIUM,
|
||||
LARGE = 500
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新日志窗口的配色,与设计稿保持一致
|
||||
/// </summary>
|
||||
internal static class ChangelogTheme
|
||||
{
|
||||
public static readonly Color Accent = Color.FromArgb(152, 99, 143);
|
||||
public static readonly Color AccentBg = Color.FromArgb(245, 237, 244);
|
||||
public static readonly Color SubColor = Color.FromArgb(107, 114, 128);
|
||||
public static readonly Color LineColor = Color.FromArgb(229, 231, 238);
|
||||
public static readonly Color TextColor = Color.FromArgb(31, 36, 48);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Generated
+216
-128
@@ -29,135 +29,217 @@ namespace Update
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
|
||||
this.lblMessage = new System.Windows.Forms.Label();
|
||||
this.btnOk = new System.Windows.Forms.Button();
|
||||
this.btnCancel = new System.Windows.Forms.Button();
|
||||
this.panel1 = new System.Windows.Forms.Panel();
|
||||
this.btnClose = new System.Windows.Forms.Button();
|
||||
this.panel2 = new System.Windows.Forms.Panel();
|
||||
this.progressBar1 = new System.Windows.Forms.ProgressBar();
|
||||
this.panel1.SuspendLayout();
|
||||
this.panel2.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// lblMessage
|
||||
//
|
||||
this.lblMessage.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
|
||||
this.lblMessage = new System.Windows.Forms.Label();
|
||||
this.btnOk = new System.Windows.Forms.Button();
|
||||
this.btnCancel = new System.Windows.Forms.Button();
|
||||
this.panel1 = new System.Windows.Forms.Panel();
|
||||
this.lb_title = new System.Windows.Forms.Label();
|
||||
this.btnClose = new System.Windows.Forms.Button();
|
||||
this.panel2 = new System.Windows.Forms.Panel();
|
||||
this.heroPanel = new System.Windows.Forms.Panel();
|
||||
this.lblHeroTitle = new System.Windows.Forms.Label();
|
||||
this.lblHeroMeta = new System.Windows.Forms.Label();
|
||||
this.panelChangelog = new System.Windows.Forms.Panel();
|
||||
this.progressBar1 = new System.Windows.Forms.ProgressBar();
|
||||
this.panel3 = new System.Windows.Forms.Panel();
|
||||
this.panel1.SuspendLayout();
|
||||
this.panel2.SuspendLayout();
|
||||
this.heroPanel.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// lblMessage
|
||||
//
|
||||
this.lblMessage.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.lblMessage.Location = new System.Drawing.Point(14, 33);
|
||||
this.lblMessage.Name = "lblMessage";
|
||||
this.lblMessage.Size = new System.Drawing.Size(327, 98);
|
||||
this.lblMessage.TabIndex = 0;
|
||||
this.lblMessage.Text = "发现新版本,即将为您升级!";
|
||||
this.lblMessage.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
//
|
||||
// btnOk
|
||||
//
|
||||
this.btnOk.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnOk.BackColor = System.Drawing.Color.Blue;
|
||||
this.btnOk.Cursor = System.Windows.Forms.Cursors.Hand;
|
||||
this.btnOk.FlatAppearance.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(255)))));
|
||||
this.btnOk.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||
this.btnOk.Font = new System.Drawing.Font("微软雅黑", 11F);
|
||||
this.btnOk.ForeColor = System.Drawing.Color.White;
|
||||
this.btnOk.Location = new System.Drawing.Point(232, 177);
|
||||
this.btnOk.Name = "btnOk";
|
||||
this.btnOk.Size = new System.Drawing.Size(109, 30);
|
||||
this.btnOk.TabIndex = 9;
|
||||
this.btnOk.TabStop = false;
|
||||
this.btnOk.Text = "确 定";
|
||||
this.btnOk.UseVisualStyleBackColor = false;
|
||||
this.btnOk.Click += new System.EventHandler(this.btnOk_Click);
|
||||
//
|
||||
// btnCancel
|
||||
//
|
||||
this.btnCancel.Cursor = System.Windows.Forms.Cursors.Hand;
|
||||
this.btnCancel.FlatAppearance.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(255)))));
|
||||
this.btnCancel.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||
this.btnCancel.Font = new System.Drawing.Font("微软雅黑", 11F);
|
||||
this.btnCancel.ForeColor = System.Drawing.Color.Blue;
|
||||
this.btnCancel.Location = new System.Drawing.Point(14, 177);
|
||||
this.btnCancel.Name = "btnCancel";
|
||||
this.btnCancel.Size = new System.Drawing.Size(109, 30);
|
||||
this.btnCancel.TabIndex = 10;
|
||||
this.btnCancel.TabStop = false;
|
||||
this.btnCancel.Text = "取 消";
|
||||
this.btnCancel.UseVisualStyleBackColor = false;
|
||||
this.btnCancel.Visible = false;
|
||||
this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
|
||||
//
|
||||
// panel1
|
||||
//
|
||||
this.panel1.BackColor = System.Drawing.Color.Blue;
|
||||
this.panel1.Controls.Add(this.btnClose);
|
||||
this.panel1.Dock = System.Windows.Forms.DockStyle.Top;
|
||||
this.panel1.Location = new System.Drawing.Point(2, 2);
|
||||
this.panel1.Name = "panel1";
|
||||
this.panel1.Size = new System.Drawing.Size(355, 24);
|
||||
this.panel1.TabIndex = 11;
|
||||
this.panel1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.panel1_MouseDown);
|
||||
this.panel1.MouseMove += new System.Windows.Forms.MouseEventHandler(this.panel1_MouseMove);
|
||||
this.panel1.MouseUp += new System.Windows.Forms.MouseEventHandler(this.panel1_MouseUp);
|
||||
//
|
||||
// btnClose
|
||||
//
|
||||
this.btnClose.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnClose.Cursor = System.Windows.Forms.Cursors.Hand;
|
||||
this.btnClose.FlatAppearance.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(255)))));
|
||||
this.btnClose.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||
this.btnClose.Font = new System.Drawing.Font("微软雅黑", 11F);
|
||||
this.btnClose.ForeColor = System.Drawing.Color.White;
|
||||
this.btnClose.Location = new System.Drawing.Point(339, -5);
|
||||
this.btnClose.Name = "btnClose";
|
||||
this.btnClose.Size = new System.Drawing.Size(17, 28);
|
||||
this.btnClose.TabIndex = 11;
|
||||
this.btnClose.TabStop = false;
|
||||
this.btnClose.Text = "x";
|
||||
this.btnClose.UseVisualStyleBackColor = false;
|
||||
this.btnClose.Click += new System.EventHandler(this.btnClose_Click);
|
||||
//
|
||||
// panel2
|
||||
//
|
||||
this.panel2.BackColor = System.Drawing.Color.White;
|
||||
this.panel2.Controls.Add(this.progressBar1);
|
||||
this.panel2.Controls.Add(this.lblMessage);
|
||||
this.panel2.Controls.Add(this.btnOk);
|
||||
this.panel2.Controls.Add(this.btnCancel);
|
||||
this.panel2.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.panel2.Location = new System.Drawing.Point(2, 2);
|
||||
this.panel2.Name = "panel2";
|
||||
this.panel2.Size = new System.Drawing.Size(355, 221);
|
||||
this.panel2.TabIndex = 12;
|
||||
//
|
||||
// progressBar1
|
||||
//
|
||||
this.progressBar1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
this.lblMessage.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(107)))), ((int)(((byte)(114)))), ((int)(((byte)(128)))));
|
||||
this.lblMessage.Location = new System.Drawing.Point(20, 416);
|
||||
this.lblMessage.Name = "lblMessage";
|
||||
this.lblMessage.Size = new System.Drawing.Size(607, 45);
|
||||
this.lblMessage.TabIndex = 0;
|
||||
this.lblMessage.TextAlign = System.Drawing.ContentAlignment.TopCenter;
|
||||
//
|
||||
// btnOk
|
||||
//
|
||||
this.btnOk.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnOk.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(152)))), ((int)(((byte)(99)))), ((int)(((byte)(143)))));
|
||||
this.btnOk.Cursor = System.Windows.Forms.Cursors.Hand;
|
||||
this.btnOk.FlatAppearance.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(152)))), ((int)(((byte)(99)))), ((int)(((byte)(143)))));
|
||||
this.btnOk.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||
this.btnOk.Font = new System.Drawing.Font("微软雅黑", 11F);
|
||||
this.btnOk.ForeColor = System.Drawing.Color.White;
|
||||
this.btnOk.Location = new System.Drawing.Point(522, 521);
|
||||
this.btnOk.Name = "btnOk";
|
||||
this.btnOk.Size = new System.Drawing.Size(109, 30);
|
||||
this.btnOk.TabIndex = 9;
|
||||
this.btnOk.TabStop = false;
|
||||
this.btnOk.Text = "确 定";
|
||||
this.btnOk.UseVisualStyleBackColor = false;
|
||||
this.btnOk.Click += new System.EventHandler(this.btnOk_Click);
|
||||
//
|
||||
// btnCancel
|
||||
//
|
||||
this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.btnCancel.Cursor = System.Windows.Forms.Cursors.Hand;
|
||||
this.btnCancel.FlatAppearance.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(152)))), ((int)(((byte)(99)))), ((int)(((byte)(143)))));
|
||||
this.btnCancel.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||
this.btnCancel.Font = new System.Drawing.Font("微软雅黑", 11F);
|
||||
this.btnCancel.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(152)))), ((int)(((byte)(99)))), ((int)(((byte)(143)))));
|
||||
this.btnCancel.Location = new System.Drawing.Point(24, 521);
|
||||
this.btnCancel.Name = "btnCancel";
|
||||
this.btnCancel.Size = new System.Drawing.Size(109, 30);
|
||||
this.btnCancel.TabIndex = 10;
|
||||
this.btnCancel.TabStop = false;
|
||||
this.btnCancel.Text = "取 消";
|
||||
this.btnCancel.UseVisualStyleBackColor = false;
|
||||
this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
|
||||
//
|
||||
// panel1
|
||||
//
|
||||
this.panel1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(152)))), ((int)(((byte)(99)))), ((int)(((byte)(143)))));
|
||||
this.panel1.Controls.Add(this.lb_title);
|
||||
this.panel1.Controls.Add(this.btnClose);
|
||||
this.panel1.Dock = System.Windows.Forms.DockStyle.Top;
|
||||
this.panel1.Location = new System.Drawing.Point(2, 2);
|
||||
this.panel1.Name = "panel1";
|
||||
this.panel1.Size = new System.Drawing.Size(663, 24);
|
||||
this.panel1.TabIndex = 11;
|
||||
this.panel1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.panel1_MouseDown);
|
||||
this.panel1.MouseMove += new System.Windows.Forms.MouseEventHandler(this.panel1_MouseMove);
|
||||
this.panel1.MouseUp += new System.Windows.Forms.MouseEventHandler(this.panel1_MouseUp);
|
||||
//
|
||||
// lb_title
|
||||
//
|
||||
this.lb_title.AutoSize = true;
|
||||
this.lb_title.ForeColor = System.Drawing.Color.White;
|
||||
this.lb_title.Location = new System.Drawing.Point(3, 1);
|
||||
this.lb_title.Name = "lb_title";
|
||||
this.lb_title.Size = new System.Drawing.Size(50, 20);
|
||||
this.lb_title.TabIndex = 12;
|
||||
this.lb_title.Text = "label1";
|
||||
//
|
||||
// btnClose
|
||||
//
|
||||
this.btnClose.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnClose.Cursor = System.Windows.Forms.Cursors.Hand;
|
||||
this.btnClose.FlatAppearance.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(152)))), ((int)(((byte)(99)))), ((int)(((byte)(143)))));
|
||||
this.btnClose.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||
this.btnClose.Font = new System.Drawing.Font("微软雅黑", 13F);
|
||||
this.btnClose.ForeColor = System.Drawing.Color.White;
|
||||
this.btnClose.Location = new System.Drawing.Point(629, -6);
|
||||
this.btnClose.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.btnClose.Name = "btnClose";
|
||||
this.btnClose.Size = new System.Drawing.Size(35, 35);
|
||||
this.btnClose.TabIndex = 11;
|
||||
this.btnClose.TabStop = false;
|
||||
this.btnClose.Text = "✕";
|
||||
this.btnClose.UseVisualStyleBackColor = false;
|
||||
this.btnClose.Click += new System.EventHandler(this.btnClose_Click);
|
||||
//
|
||||
// panel2
|
||||
//
|
||||
this.panel2.BackColor = System.Drawing.Color.White;
|
||||
this.panel2.Controls.Add(this.panel3);
|
||||
this.panel2.Controls.Add(this.heroPanel);
|
||||
this.panel2.Controls.Add(this.panelChangelog);
|
||||
this.panel2.Controls.Add(this.progressBar1);
|
||||
this.panel2.Controls.Add(this.lblMessage);
|
||||
this.panel2.Controls.Add(this.btnOk);
|
||||
this.panel2.Controls.Add(this.btnCancel);
|
||||
this.panel2.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.panel2.Location = new System.Drawing.Point(2, 2);
|
||||
this.panel2.Name = "panel2";
|
||||
this.panel2.Size = new System.Drawing.Size(663, 583);
|
||||
this.panel2.TabIndex = 12;
|
||||
this.panel2.Paint += new System.Windows.Forms.PaintEventHandler(this.panel2_Paint);
|
||||
//
|
||||
// heroPanel
|
||||
//
|
||||
this.heroPanel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.progressBar1.Location = new System.Drawing.Point(14, 139);
|
||||
this.progressBar1.Name = "progressBar1";
|
||||
this.progressBar1.Size = new System.Drawing.Size(327, 23);
|
||||
this.progressBar1.TabIndex = 11;
|
||||
this.progressBar1.Visible = false;
|
||||
//
|
||||
// MainForm
|
||||
//
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
|
||||
this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(255)))));
|
||||
this.ClientSize = new System.Drawing.Size(359, 225);
|
||||
this.Controls.Add(this.panel1);
|
||||
this.Controls.Add(this.panel2);
|
||||
this.Font = new System.Drawing.Font("微软雅黑", 10F);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
|
||||
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||
this.Name = "MainForm";
|
||||
this.Padding = new System.Windows.Forms.Padding(2);
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
this.Text = "MessageForm";
|
||||
this.Paint += new System.Windows.Forms.PaintEventHandler(this.MessageForm_Paint);
|
||||
this.panel1.ResumeLayout(false);
|
||||
this.panel2.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
this.heroPanel.Controls.Add(this.lblHeroTitle);
|
||||
this.heroPanel.Controls.Add(this.lblHeroMeta);
|
||||
this.heroPanel.Location = new System.Drawing.Point(0, 24);
|
||||
this.heroPanel.Name = "heroPanel";
|
||||
this.heroPanel.Size = new System.Drawing.Size(663, 92);
|
||||
this.heroPanel.TabIndex = 13;
|
||||
this.heroPanel.Paint += new System.Windows.Forms.PaintEventHandler(this.heroPanel_Paint);
|
||||
//
|
||||
// lblHeroTitle
|
||||
//
|
||||
this.lblHeroTitle.AutoSize = true;
|
||||
this.lblHeroTitle.BackColor = System.Drawing.Color.Transparent;
|
||||
this.lblHeroTitle.Font = new System.Drawing.Font("微软雅黑", 16F, System.Drawing.FontStyle.Bold);
|
||||
this.lblHeroTitle.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(152)))), ((int)(((byte)(99)))), ((int)(((byte)(143)))));
|
||||
this.lblHeroTitle.Location = new System.Drawing.Point(28, 18);
|
||||
this.lblHeroTitle.Name = "lblHeroTitle";
|
||||
this.lblHeroTitle.Size = new System.Drawing.Size(183, 30);
|
||||
this.lblHeroTitle.TabIndex = 0;
|
||||
this.lblHeroTitle.Text = "v1.0.0 → v1.3.0";
|
||||
//
|
||||
// lblHeroMeta
|
||||
//
|
||||
this.lblHeroMeta.AutoSize = true;
|
||||
this.lblHeroMeta.BackColor = System.Drawing.Color.Transparent;
|
||||
this.lblHeroMeta.Font = new System.Drawing.Font("微软雅黑", 9F);
|
||||
this.lblHeroMeta.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(107)))), ((int)(((byte)(114)))), ((int)(((byte)(128)))));
|
||||
this.lblHeroMeta.Location = new System.Drawing.Point(30, 58);
|
||||
this.lblHeroMeta.Name = "lblHeroMeta";
|
||||
this.lblHeroMeta.Size = new System.Drawing.Size(155, 17);
|
||||
this.lblHeroMeta.TabIndex = 1;
|
||||
this.lblHeroMeta.Text = "共包含 3 个版本的更新内容";
|
||||
//
|
||||
// panelChangelog
|
||||
//
|
||||
this.panelChangelog.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.panelChangelog.AutoScroll = true;
|
||||
this.panelChangelog.BackColor = System.Drawing.Color.White;
|
||||
this.panelChangelog.Location = new System.Drawing.Point(0, 116);
|
||||
this.panelChangelog.Name = "panelChangelog";
|
||||
this.panelChangelog.Size = new System.Drawing.Size(663, 291);
|
||||
this.panelChangelog.TabIndex = 14;
|
||||
//
|
||||
// progressBar1
|
||||
//
|
||||
this.progressBar1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.progressBar1.Location = new System.Drawing.Point(24, 468);
|
||||
this.progressBar1.Name = "progressBar1";
|
||||
this.progressBar1.Size = new System.Drawing.Size(607, 16);
|
||||
this.progressBar1.TabIndex = 11;
|
||||
this.progressBar1.Visible = false;
|
||||
//
|
||||
// panel3
|
||||
//
|
||||
this.panel3.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(229)))), ((int)(((byte)(231)))), ((int)(((byte)(238)))));
|
||||
this.panel3.Location = new System.Drawing.Point(0, 496);
|
||||
this.panel3.Margin = new System.Windows.Forms.Padding(1);
|
||||
this.panel3.Name = "panel3";
|
||||
this.panel3.Size = new System.Drawing.Size(664, 1);
|
||||
this.panel3.TabIndex = 15;
|
||||
//
|
||||
// MainForm
|
||||
//
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
|
||||
this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(152)))), ((int)(((byte)(99)))), ((int)(((byte)(143)))));
|
||||
this.ClientSize = new System.Drawing.Size(667, 587);
|
||||
this.Controls.Add(this.panel1);
|
||||
this.Controls.Add(this.panel2);
|
||||
this.Font = new System.Drawing.Font("微软雅黑", 10F);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
|
||||
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||
this.Name = "MainForm";
|
||||
this.Padding = new System.Windows.Forms.Padding(2);
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
this.Text = "MessageForm";
|
||||
this.panel1.ResumeLayout(false);
|
||||
this.panel1.PerformLayout();
|
||||
this.panel2.ResumeLayout(false);
|
||||
this.heroPanel.ResumeLayout(false);
|
||||
this.heroPanel.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
@@ -170,5 +252,11 @@ namespace Update
|
||||
private System.Windows.Forms.Panel panel2;
|
||||
private System.Windows.Forms.Button btnClose;
|
||||
private System.Windows.Forms.ProgressBar progressBar1;
|
||||
}
|
||||
private System.Windows.Forms.Panel heroPanel;
|
||||
private System.Windows.Forms.Label lblHeroTitle;
|
||||
private System.Windows.Forms.Label lblHeroMeta;
|
||||
private System.Windows.Forms.Panel panelChangelog;
|
||||
private System.Windows.Forms.Label lb_title;
|
||||
private System.Windows.Forms.Panel panel3;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,699 @@
|
||||
/*
|
||||
* Copyright (c) 2013 Calvin Rien
|
||||
*
|
||||
* Based on the JSON parser by Patrick van Bergen
|
||||
* http://techblog.procurios.nl/k/618/news/view/14605/14863/How-do-I-write-my-own-parser-for-JSON.html
|
||||
*
|
||||
* Simplified it so that it doesn't throw exceptions
|
||||
* and can be used in Unity iPhone with maximum code stripping.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
namespace MiniJson
|
||||
{
|
||||
// Example usage:
|
||||
//
|
||||
// using UnityEngine;
|
||||
// using System.Collections;
|
||||
// using System.Collections.Generic;
|
||||
// using MiniJSON;
|
||||
//
|
||||
// public class MiniJSONTest : MonoBehaviour {
|
||||
// void Start () {
|
||||
// var jsonString = "{ \"array\": [1.44,2,3], " +
|
||||
// "\"object\": {\"key1\":\"value1\", \"key2\":256}, " +
|
||||
// "\"string\": \"The quick brown fox \\\"jumps\\\" over the lazy dog \", " +
|
||||
// "\"unicode\": \"\\u3041 Men\u00fa sesi\u00f3n\", " +
|
||||
// "\"int\": 65536, " +
|
||||
// "\"float\": 3.1415926, " +
|
||||
// "\"bool\": true, " +
|
||||
// "\"null\": null }";
|
||||
//
|
||||
// var dict = Json.Deserialize(jsonString) as Dictionary<string,object>;
|
||||
//
|
||||
// Debug.Log("deserialized: " + dict.GetType());
|
||||
// Debug.Log("dict['array'][0]: " + ((List<object>) dict["array"])[0]);
|
||||
// Debug.Log("dict['string']: " + (string) dict["string"]);
|
||||
// Debug.Log("dict['float']: " + (double) dict["float"]); // floats come out as doubles
|
||||
// Debug.Log("dict['int']: " + (long) dict["int"]); // ints come out as longs
|
||||
// Debug.Log("dict['unicode']: " + (string) dict["unicode"]);
|
||||
//
|
||||
// var str = Json.Serialize(dict);
|
||||
//
|
||||
// Debug.Log("serialized: " + str);
|
||||
// }
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// This class encodes and decodes JSON strings.
|
||||
/// Spec. details, see http://www.json.org/
|
||||
///
|
||||
/// JSON uses Arrays and Objects. These correspond here to the datatypes IList and IDictionary.
|
||||
/// All numbers are parsed to doubles.
|
||||
/// </summary>
|
||||
public static class Json
|
||||
{
|
||||
/// <summary>
|
||||
/// Parses the string json into a value
|
||||
/// </summary>
|
||||
/// <param name="json">A JSON string.</param>
|
||||
/// <returns>An List<object>, a Dictionary<string, object>, a double, an integer,a string, null, true, or false</returns>
|
||||
public static object Deserialize(string json)
|
||||
{
|
||||
// save the string for debug information
|
||||
if (json == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return Parser.Parse(json);
|
||||
}
|
||||
|
||||
public static T Deserialize<T>(string json)
|
||||
where T:class,new()
|
||||
{
|
||||
T model =new T();
|
||||
Dictionary<string,object> dic=Deserialize(json) as Dictionary<string,object>;
|
||||
if (dic != null)
|
||||
{
|
||||
var properties = model.GetType().GetProperties();
|
||||
foreach (var pro in properties)
|
||||
{
|
||||
if (dic.ContainsKey(pro.Name))
|
||||
{
|
||||
object val;
|
||||
if (dic[pro.Name]==null && pro.PropertyType.IsValueType)
|
||||
{
|
||||
val = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
val = Convert.ChangeType(dic[pro.Name], pro.PropertyType);
|
||||
}
|
||||
pro.SetValue(model, val,null);
|
||||
}
|
||||
}
|
||||
}
|
||||
return model;
|
||||
}
|
||||
/// <summary>
|
||||
/// Converts a Dictionary / List object or a simple type or a class type (string, int, etc.) into a JSON string
|
||||
/// </summary>
|
||||
/// <param name="obj">A Dictionary<string, object> / List<object></param>
|
||||
/// <returns>A JSON encoded string, or null if object 'json' is not serializable</returns>
|
||||
//public static string Serialize(object obj)
|
||||
//{
|
||||
// return Serializer.Serialize(obj);
|
||||
//}
|
||||
public static string Serialize(object obj)
|
||||
{
|
||||
if (obj.GetType() == typeof(Dictionary<string, object>) || obj.GetType() == typeof(List<object>))
|
||||
{
|
||||
return Serializer.Serialize(obj);
|
||||
}
|
||||
else if (obj.GetType().IsClass)
|
||||
{
|
||||
var properties = obj.GetType().GetProperties();
|
||||
Dictionary<string, object> dic = new Dictionary<string, object>();
|
||||
|
||||
foreach (var pro in properties)
|
||||
{
|
||||
dic.Add(pro.Name, pro.GetValue(obj, null));
|
||||
}
|
||||
return Serializer.Serialize(dic);
|
||||
}
|
||||
else
|
||||
return null;
|
||||
}
|
||||
sealed class Parser : IDisposable
|
||||
{
|
||||
const string WORD_BREAK = "{}[],:\"";
|
||||
|
||||
public static bool IsWordBreak(char c)
|
||||
{
|
||||
return Char.IsWhiteSpace(c) || WORD_BREAK.IndexOf(c) != -1;
|
||||
}
|
||||
|
||||
const string HEX_DIGIT = "0123456789ABCDEFabcdef";
|
||||
|
||||
public static bool IsHexDigit(char c)
|
||||
{
|
||||
return HEX_DIGIT.IndexOf(c) != -1;
|
||||
}
|
||||
|
||||
enum TOKEN
|
||||
{
|
||||
NONE,
|
||||
CURLY_OPEN,
|
||||
CURLY_CLOSE,
|
||||
SQUARED_OPEN,
|
||||
SQUARED_CLOSE,
|
||||
COLON,
|
||||
COMMA,
|
||||
STRING,
|
||||
NUMBER,
|
||||
TRUE,
|
||||
FALSE,
|
||||
NULL
|
||||
};
|
||||
|
||||
StringReader json;
|
||||
|
||||
Parser(string jsonString)
|
||||
{
|
||||
json = new StringReader(jsonString);
|
||||
}
|
||||
|
||||
public static object Parse(string jsonString)
|
||||
{
|
||||
using (var instance = new Parser(jsonString))
|
||||
{
|
||||
return instance.ParseValue();
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
json.Dispose();
|
||||
json = null;
|
||||
}
|
||||
|
||||
Dictionary<string, object> ParseObject()
|
||||
{
|
||||
Dictionary<string, object> table = new Dictionary<string, object>();
|
||||
|
||||
// ditch opening brace
|
||||
json.Read();
|
||||
|
||||
// {
|
||||
while (true)
|
||||
{
|
||||
switch (NextToken)
|
||||
{
|
||||
case TOKEN.NONE:
|
||||
return null;
|
||||
case TOKEN.COMMA:
|
||||
continue;
|
||||
case TOKEN.CURLY_CLOSE:
|
||||
return table;
|
||||
case TOKEN.STRING:
|
||||
// name
|
||||
string name = ParseString();
|
||||
if (name == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// :
|
||||
if (NextToken != TOKEN.COLON)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
// ditch the colon
|
||||
json.Read();
|
||||
|
||||
// value
|
||||
TOKEN valueToken = NextToken;
|
||||
object value = ParseByToken(valueToken);
|
||||
if (value == null && valueToken != TOKEN.NULL)
|
||||
return null;
|
||||
table[name] = value;
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<object> ParseArray()
|
||||
{
|
||||
List<object> array = new List<object>();
|
||||
|
||||
// ditch opening bracket
|
||||
json.Read();
|
||||
|
||||
// [
|
||||
var parsing = true;
|
||||
while (parsing)
|
||||
{
|
||||
TOKEN nextToken = NextToken;
|
||||
|
||||
switch (nextToken)
|
||||
{
|
||||
case TOKEN.NONE:
|
||||
return null;
|
||||
case TOKEN.COMMA:
|
||||
continue;
|
||||
case TOKEN.SQUARED_CLOSE:
|
||||
parsing = false;
|
||||
break;
|
||||
default:
|
||||
object value = ParseByToken(nextToken);
|
||||
if (value == null && nextToken != TOKEN.NULL)
|
||||
return null;
|
||||
array.Add(value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
object ParseValue()
|
||||
{
|
||||
TOKEN nextToken = NextToken;
|
||||
return ParseByToken(nextToken);
|
||||
}
|
||||
|
||||
object ParseByToken(TOKEN token)
|
||||
{
|
||||
switch (token)
|
||||
{
|
||||
case TOKEN.STRING:
|
||||
return ParseString();
|
||||
case TOKEN.NUMBER:
|
||||
return ParseNumber();
|
||||
case TOKEN.CURLY_OPEN:
|
||||
return ParseObject();
|
||||
case TOKEN.SQUARED_OPEN:
|
||||
return ParseArray();
|
||||
case TOKEN.TRUE:
|
||||
return true;
|
||||
case TOKEN.FALSE:
|
||||
return false;
|
||||
case TOKEN.NULL:
|
||||
return null;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
string ParseString()
|
||||
{
|
||||
StringBuilder s = new StringBuilder();
|
||||
char c;
|
||||
|
||||
// ditch opening quote
|
||||
json.Read();
|
||||
|
||||
bool parsing = true;
|
||||
while (parsing)
|
||||
{
|
||||
|
||||
if (json.Peek() == -1)
|
||||
{
|
||||
parsing = false;
|
||||
break;
|
||||
}
|
||||
|
||||
c = NextChar;
|
||||
switch (c)
|
||||
{
|
||||
case '"':
|
||||
parsing = false;
|
||||
break;
|
||||
case '\\':
|
||||
if (json.Peek() == -1)
|
||||
{
|
||||
parsing = false;
|
||||
break;
|
||||
}
|
||||
|
||||
c = NextChar;
|
||||
switch (c)
|
||||
{
|
||||
case '"':
|
||||
case '\\':
|
||||
case '/':
|
||||
s.Append(c);
|
||||
break;
|
||||
case 'b':
|
||||
s.Append('\b');
|
||||
break;
|
||||
case 'f':
|
||||
s.Append('\f');
|
||||
break;
|
||||
case 'n':
|
||||
s.Append('\n');
|
||||
break;
|
||||
case 'r':
|
||||
s.Append('\r');
|
||||
break;
|
||||
case 't':
|
||||
s.Append('\t');
|
||||
break;
|
||||
case 'u':
|
||||
var hex = new char[4];
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
hex[i] = NextChar;
|
||||
if (!IsHexDigit(hex[i]))
|
||||
return null;
|
||||
}
|
||||
|
||||
s.Append((char)Convert.ToInt32(new string(hex), 16));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
s.Append(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return s.ToString();
|
||||
}
|
||||
|
||||
object ParseNumber()
|
||||
{
|
||||
string number = NextWord;
|
||||
|
||||
if (number.IndexOf('.') == -1 && number.IndexOf('E') == -1 && number.IndexOf('e') == -1)
|
||||
{
|
||||
long parsedInt;
|
||||
Int64.TryParse(number, System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out parsedInt);
|
||||
return parsedInt;
|
||||
}
|
||||
|
||||
double parsedDouble;
|
||||
Double.TryParse(number, System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out parsedDouble);
|
||||
return parsedDouble;
|
||||
}
|
||||
|
||||
void EatWhitespace()
|
||||
{
|
||||
while (Char.IsWhiteSpace(PeekChar))
|
||||
{
|
||||
json.Read();
|
||||
|
||||
if (json.Peek() == -1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char PeekChar
|
||||
{
|
||||
get
|
||||
{
|
||||
return Convert.ToChar(json.Peek());
|
||||
}
|
||||
}
|
||||
|
||||
char NextChar
|
||||
{
|
||||
get
|
||||
{
|
||||
return Convert.ToChar(json.Read());
|
||||
}
|
||||
}
|
||||
|
||||
string NextWord
|
||||
{
|
||||
get
|
||||
{
|
||||
StringBuilder word = new StringBuilder();
|
||||
|
||||
while (!IsWordBreak(PeekChar))
|
||||
{
|
||||
word.Append(NextChar);
|
||||
|
||||
if (json.Peek() == -1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return word.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
TOKEN NextToken
|
||||
{
|
||||
get
|
||||
{
|
||||
EatWhitespace();
|
||||
|
||||
if (json.Peek() == -1)
|
||||
{
|
||||
return TOKEN.NONE;
|
||||
}
|
||||
|
||||
switch (PeekChar)
|
||||
{
|
||||
case '{':
|
||||
return TOKEN.CURLY_OPEN;
|
||||
case '}':
|
||||
json.Read();
|
||||
return TOKEN.CURLY_CLOSE;
|
||||
case '[':
|
||||
return TOKEN.SQUARED_OPEN;
|
||||
case ']':
|
||||
json.Read();
|
||||
return TOKEN.SQUARED_CLOSE;
|
||||
case ',':
|
||||
json.Read();
|
||||
return TOKEN.COMMA;
|
||||
case '"':
|
||||
return TOKEN.STRING;
|
||||
case ':':
|
||||
return TOKEN.COLON;
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
case '-':
|
||||
return TOKEN.NUMBER;
|
||||
}
|
||||
|
||||
switch (NextWord)
|
||||
{
|
||||
case "false":
|
||||
return TOKEN.FALSE;
|
||||
case "true":
|
||||
return TOKEN.TRUE;
|
||||
case "null":
|
||||
return TOKEN.NULL;
|
||||
}
|
||||
|
||||
return TOKEN.NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
sealed class Serializer
|
||||
{
|
||||
StringBuilder builder;
|
||||
|
||||
Serializer()
|
||||
{
|
||||
builder = new StringBuilder();
|
||||
}
|
||||
|
||||
public static string Serialize(object obj)
|
||||
{
|
||||
var instance = new Serializer();
|
||||
|
||||
instance.SerializeValue(obj);
|
||||
|
||||
return instance.builder.ToString();
|
||||
}
|
||||
|
||||
void SerializeValue(object value)
|
||||
{
|
||||
IList asList;
|
||||
IDictionary asDict;
|
||||
string asStr;
|
||||
|
||||
if (value == null)
|
||||
{
|
||||
builder.Append("null");
|
||||
}
|
||||
else if ((asStr = value as string) != null)
|
||||
{
|
||||
SerializeString(asStr);
|
||||
}
|
||||
else if (value is bool)
|
||||
{
|
||||
builder.Append((bool)value ? "true" : "false");
|
||||
}
|
||||
else if ((asList = value as IList) != null)
|
||||
{
|
||||
SerializeArray(asList);
|
||||
}
|
||||
else if ((asDict = value as IDictionary) != null)
|
||||
{
|
||||
SerializeObject(asDict);
|
||||
}
|
||||
else if (value is char)
|
||||
{
|
||||
SerializeString(new string((char)value, 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
SerializeOther(value);
|
||||
}
|
||||
}
|
||||
|
||||
void SerializeObject(IDictionary obj)
|
||||
{
|
||||
bool first = true;
|
||||
|
||||
builder.Append('{');
|
||||
|
||||
foreach (object e in obj.Keys)
|
||||
{
|
||||
if (!first)
|
||||
{
|
||||
builder.Append(',');
|
||||
}
|
||||
|
||||
SerializeString(e.ToString());
|
||||
builder.Append(':');
|
||||
|
||||
SerializeValue(obj[e]);
|
||||
|
||||
first = false;
|
||||
}
|
||||
|
||||
builder.Append('}');
|
||||
}
|
||||
|
||||
void SerializeArray(IList anArray)
|
||||
{
|
||||
builder.Append('[');
|
||||
|
||||
bool first = true;
|
||||
|
||||
for (int i = 0; i < anArray.Count; i++)
|
||||
{
|
||||
object obj = anArray[i];
|
||||
if (!first)
|
||||
{
|
||||
builder.Append(',');
|
||||
}
|
||||
|
||||
SerializeValue(obj);
|
||||
|
||||
first = false;
|
||||
}
|
||||
|
||||
builder.Append(']');
|
||||
}
|
||||
|
||||
void SerializeString(string str)
|
||||
{
|
||||
builder.Append('\"');
|
||||
|
||||
char[] charArray = str.ToCharArray();
|
||||
for (int i = 0; i < charArray.Length; i++)
|
||||
{
|
||||
char c = charArray[i];
|
||||
switch (c)
|
||||
{
|
||||
case '"':
|
||||
builder.Append("\\\"");
|
||||
break;
|
||||
case '\\':
|
||||
builder.Append("\\\\");
|
||||
break;
|
||||
case '\b':
|
||||
builder.Append("\\b");
|
||||
break;
|
||||
case '\f':
|
||||
builder.Append("\\f");
|
||||
break;
|
||||
case '\n':
|
||||
builder.Append("\\n");
|
||||
break;
|
||||
case '\r':
|
||||
builder.Append("\\r");
|
||||
break;
|
||||
case '\t':
|
||||
builder.Append("\\t");
|
||||
break;
|
||||
default:
|
||||
int codepoint = Convert.ToInt32(c);
|
||||
if ((codepoint >= 32) && (codepoint <= 126))
|
||||
{
|
||||
builder.Append(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.Append("\\u");
|
||||
builder.Append(codepoint.ToString("x4"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
builder.Append('\"');
|
||||
}
|
||||
|
||||
void SerializeOther(object value)
|
||||
{
|
||||
// NOTE: decimals lose precision during serialization.
|
||||
// They always have, I'm just letting you know.
|
||||
// Previously floats and doubles lost precision too.
|
||||
if (value is float)
|
||||
{
|
||||
builder.Append(((float)value).ToString("R", System.Globalization.CultureInfo.InvariantCulture));
|
||||
}
|
||||
else if (value is int
|
||||
|| value is uint
|
||||
|| value is long
|
||||
|| value is sbyte
|
||||
|| value is byte
|
||||
|| value is short
|
||||
|| value is ushort
|
||||
|| value is ulong)
|
||||
{
|
||||
builder.Append(value);
|
||||
}
|
||||
else if (value is double
|
||||
|| value is decimal)
|
||||
{
|
||||
builder.Append(Convert.ToDouble(value).ToString("R", System.Globalization.CultureInfo.InvariantCulture));
|
||||
}
|
||||
else
|
||||
{
|
||||
SerializeString(value.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,12 @@ namespace Update
|
||||
[STAThread]
|
||||
static void Main(string[] args)
|
||||
{
|
||||
if (args.Length > 0)
|
||||
//Program.oldVersion = 1332;
|
||||
//Application.EnableVisualStyles();
|
||||
//Application.SetCompatibleTextRenderingDefault(false);
|
||||
//Application.Run(new MainForm());
|
||||
//return;
|
||||
if (args.Length > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
|
||||
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
|
||||
//通过使用 "*",如下所示:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
[assembly: AssemblyVersion("1.1.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.1.0.0")]
|
||||
@@ -62,6 +62,7 @@
|
||||
<Compile Include="MainForm.designer.cs">
|
||||
<DependentUpon>MainForm.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="MiniJson.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="WebClientUtils.cs">
|
||||
|
||||
Reference in new issue
Block a user