同步操作将从 新生命/XCoder 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
using System;using System.Diagnostics;using System.IO;using System.Linq;using System.Net.Http;using System.Runtime.InteropServices;using System.Threading.Tasks;using NewLife;using NewLife.Log;using NewLife.Web;namespace XCoder{/// <summary>GTK助手,自动检查安装GTK运行时</summary>public class GtkHelper{#region 属性public String GtkRoot { get; set; }public String GtkPath { get; set; }public Version Version { get; set; }#endregion#region 主要方法public static Task CheckRuntime(Int32 msTimeout = 3_000){var task = Task.Run(async () =>{var gtk = new GtkHelper { Log = XTrace.Log };if (!gtk.Check()) await gtk.DownloadAsync();gtk.Install();});// 最多等3秒task.Wait(msTimeout);return task;}/// <summary>检查是否安装有GTK运行时</summary>/// <returns></returns>public Boolean Check(){// 只处理Windowsif (!Runtime.Windows) return true;// LOCALDATAif (GtkRoot.IsNullOrEmpty()){var data = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);GtkRoot = data.CombinePath("Gtk").GetFullPath();}//XTrace.WriteLine("查找GTK运行时:{0}", GtkRoot);var di = GtkRoot.AsDirectory();if (!di.Exists) return false;var dis = di.GetDirectories();if (dis == null || dis.Length == 0) return false;//var gtk = dis.OrderByDescending(e => e.Name).FirstOrDefault();//GtkPath = gtk.FullName;//Version = new Version(gtk.Name.TrimStart('v', 'V'));foreach (var item in dis){var gtk = item.FullName.CombinePath("libgdk-3-0.dll");if (File.Exists(gtk)){GtkPath = item.FullName;try{Version = new Version(item.Name.TrimStart('v', 'V'));}catch { }break;}}if (GtkPath.IsNullOrEmpty()) return false;XTrace.WriteLine("发现GTK运行时:[{0}] {1}", Version, GtkPath);return true;}/// <summary>下载</summary>/// <returns></returns>public async Task<Boolean> DownloadAsync(){var set = NewLife.Setting.Current;//var client = new WebClientX//{// Log = XTrace.Log//};//var links = client.GetLinks(set.PluginServer);//var lnk = links.First(e => e.Name.EqualIgnoreCase("Gtk"));//var file = client.DownloadLink(set.PluginServer, "Gtk", GtkRoot);var file = await DownloadLinkAsync(set.PluginServer, "Gtk", GtkRoot);var link = new Link();link.Parse(file);XTrace.WriteLine("版本:{0}", link.Version);//client.DownloadLinkAndExtract(set.PluginServer, "Gtk", gtk, true);GtkPath = GtkRoot.CombinePath(link.Version + "");Version = link.Version;Extract(file, GtkPath, true);return true;}/// <summary>安装</summary>public void Install(){if (!GtkPath.IsNullOrEmpty()) SetDllDirectory(GtkPath);}#endregion#region 辅助/// <summary>分析指定页面指定名称的链接,并下载到目标目录,返回目标文件</summary>/// <remarks>/// 根据版本或时间降序排序选择/// </remarks>/// <param name="urls">指定页面</param>/// <param name="name">页面上指定名称的链接</param>/// <param name="destdir">要下载到的目标目录</param>/// <returns>返回已下载的文件,无效时返回空</returns>private async Task<String> DownloadLinkAsync(String urls, String name, String destdir){Log.Info("下载链接 {0},目标 {1}", urls, name);var names = name.Split(",", ";");var file = "";Link link = null;Exception lastError = null;foreach (var url in urls.Split(",", ";")){try{var http = new HttpClient();var html = await http.GetStringAsync(url);var ls = Link.Parse(html, url);if (ls.Length == 0) return file;// 过滤名称后降序排序,多名称时,先确保前面的存在,即使后面名称也存在并且也时间更新都不能用foreach (var item in names){link = ls.Where(e => !e.Url.IsNullOrWhiteSpace()).Where(e => e.Name.EqualIgnoreCase(item) || e.FullName.Equals(item)).OrderByDescending(e => e.Version).ThenByDescending(e => e.Time).FirstOrDefault();if (link != null) break;}}catch (Exception ex){lastError = ex;}if (link != null) break;}if (link == null){if (lastError != null) throw lastError;return file;}var linkName = link.FullName;var file2 = destdir.CombinePath(linkName).EnsureDirectory();// 已经提前检查过,这里几乎不可能有文件存在if (File.Exists(file2)){// 如果连接名所表示的文件存在,并且带有时间,那么就智能是它啦var p = linkName.LastIndexOf("_");if (p > 0 && (p + 8 + 1 == linkName.Length || p + 14 + 1 == linkName.Length)){Log.Info("分析得到文件 {0},目标文件已存在,无需下载 {1}", linkName, link.Url);return file2;}}Log.Info("分析得到文件 {0},准备下载 {1},保存到 {2}", linkName, link.Url, file2);// 开始下载文件,注意要提前建立目录,否则会报错file2 = file2.EnsureDirectory(true);var sw = Stopwatch.StartNew();{var http = new HttpClient();var ns = await http.GetStreamAsync(link.Url);using var fs = File.OpenWrite(file2);await ns.CopyToAsync(fs);}//TaskEx.Run(() => DownloadFileAsync(link.Url, file2)).Wait();sw.Stop();if (File.Exists(file2)){Log.Info("下载完成,共{0:n0}字节,耗时{1:n0}毫秒", file2.AsFile().Length, sw.ElapsedMilliseconds);file = file2;}return file;}/// <summary>分析指定页面指定名称的链接,并下载到目标目录,解压Zip后返回目标文件</summary>/// <param name="urls">提供下载地址的多个目标页面</param>/// <param name="name">页面上指定名称的链接</param>/// <param name="destdir">要下载到的目标目录</param>/// <param name="overwrite">是否覆盖目标同名文件</param>/// <returns></returns>private String Extract(String file, String destdir, Boolean overwrite = false){if (file.IsNullOrEmpty()) return null;// 解压缩try{Log.Info("解压缩到 {0}", destdir);//ZipFile.ExtractToDirectory(file, destdir);file.AsFile().Extract(destdir, overwrite);// 删除zipFile.Delete(file);return file;}catch (Exception ex){Log.Error(ex?.GetTrue()?.ToString());// 这个时候出现异常,删除zipif (!file.IsNullOrEmpty() && File.Exists(file)){try{File.Delete(file);}catch { }}}return null;}[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]static extern Int32 SetDllDirectory(String pathName);#endregion#region 日志public ILog Log { get; set; } = Logger.Null;public void WriteLog(String format, params Object[] args) => Log?.Info(format, args);#endregion}}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。