private string Download(string file, AppUpdateInfo info, ProgressDelegate.ProgressHandler progress = null, object sender = null) { if (info != null) { switch (info.DownloadMode) { case 0: //http 下载 { if (HttpTool.Download(info.HttpUrl, file, progress, sender)) { return(file); } } break; case 1: //ftp 下载 { FtpTool ftp = new FtpTool(info.FtpIp, info.FtpAccount, info.FtpPassword); if (ftp.Download(info.FtpFile, file, progress, sender)) { return(file); } } break; } } return(null); }
/// <summary> /// http下载文件 /// </summary> /// <param name="url">下载文件地址</param> /// <param name="file">文件存放地址,包含文件名</param> /// <param name="progress">回调进度</param> /// <returns></returns> public static bool Download(string url, string file, ProgressDelegate.ProgressHandler progress = null, object sender = null) { try { string path = Path.GetDirectoryName(file); DirTool.Create(path); //创建文件目录 string tempFile = DirTool.Combine(path, GuidTool.Short() + ".temp"); //临时文件 if (File.Exists(tempFile)) { File.Delete(tempFile); //存在则删除 } FileStream fs = new FileStream(tempFile, FileMode.Append, FileAccess.Write, FileShare.ReadWrite); // 设置参数 HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest; //发送请求并获取相应回应数据 HttpWebResponse response = request.GetResponse() as HttpWebResponse; //直到request.GetResponse()程序才开始向目标网页发送Post请求 Stream responseStream = response.GetResponseStream(); //创建本地文件写入流 //Stream stream = new FileStream(tempFile, FileMode.Create); byte[] buffer = new byte[100 * 1024]; int readCount = 0; long filesize = response.ContentLength, current = 0; while ((readCount = responseStream.Read(buffer, 0, buffer.Length)) > 0) { fs.Write(buffer, 0, readCount); current += readCount; if (filesize <= 0 || filesize < current) { if (current > 0) { filesize = current; } else { filesize = 1; } } progress?.Invoke(sender, new ProgressEventArgs(current, filesize)); } //stream.Close(); fs.Close(); responseStream.Close(); File.Delete(file); //删除原始文件 File.Move(tempFile, file); //下载的临时文件重命名 return(true); } catch (Exception ex) { return(false); } }
/// <summary> /// 更新 /// </summary> /// <param name="info">新版本信息</param> /// <param name="tempPath">文件下载位置</param> /// <param name="dictionary">文件相对位置字典</param> /// <param name="downProgress">下载进度回调</param> /// <param name="downSender">下载进度事件数据</param> /// <param name="releaseProgress">释放进度回调</param> /// <param name="releaseSender">释放进度事件数据</param> /// <returns> /// -10000;//没有新版本 /// -20000;//文件下载失败 /// -30000;//文件释放失败 /// </returns> public int Update(AppUpdateInfo info, string tempPath, Dictionary <string, string> dictionary, ProgressDelegate.ProgressHandler downProgress = null, object downSender = null, ProgressDelegate.ProgressHandler releaseProgress = null, object releaseSender = null) { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); //请求最新版本信息 if (info != null) { string file = DirTool.Combine(tempPath, GuidTool.Short() + "-" + info.Version); //准备更新(下载) string downfile = Download(file, info, downProgress, downSender); if (!string.IsNullOrWhiteSpace(downfile) && File.Exists(downfile)) { //格式化释放文件目录(相对路径转换为绝对路径) string releasepath = AppDirTool.Get(info.ReleasePath, dictionary); //释放文件,释放完成后删除临时文件 int unpackCode = FilePackageTool.Unpack(downfile, releasepath, releaseProgress, releaseSender); File.Delete(file); if (unpackCode > 0) { stopwatch.Stop(); return((int)stopwatch.Elapsed.TotalSeconds); } else { return(-30000 + unpackCode);//文件释放失败 } } else { return(-20000);//文件下载失败 } } else { return(-10000);//没有新版本 } }
public bool Download(string ftpFile, string localFile, ProgressDelegate.ProgressHandler progress = null, object sender = null, bool overwrite = true) { try { long current = 0, filesize = GetFileSize(ftpFile); string localPath = DirTool.GetFilePath(localFile); if (!Directory.Exists(localPath)) { Directory.CreateDirectory(localPath); } string uri = Path.Combine(FtpUri, ftpFile); FtpWebRequest ftp = GetRequest(uri); ftp.Method = WebRequestMethods.Ftp.DownloadFile; using (FtpWebResponse response = (FtpWebResponse)ftp.GetResponse()) { using (Stream responseStream = response.GetResponseStream()) { using (FileStream fs = new FileStream(localFile, FileMode.Create)) { byte[] buffer = new byte[1024 * 1024]; int read = 0; do { read = responseStream.Read(buffer, 0, buffer.Length); fs.Write(buffer, 0, read); current += read; progress?.Invoke(sender, new ProgressEventArgs(current, filesize)); } while (!(read == 0)); fs.Flush(); } } } return(true); } catch { } return(false); }
/// <summary> /// 文件打包 /// </summary> /// <param name="srcPath">要打包的路径</param> /// <param name="dstFile">打包后的文件</param> /// <param name="progress">回调进度</param> /// <param name="overwrite">覆盖打包后的文件(重复时)</param> /// <returns> /// -11;//要打包的路径不存在 /// -12;//打包后的目标文件已存在 /// -13;//要打包的路径中没有文件 /// -14;//输出文件夹不存在 /// -404;//未知错误,操作失败 /// </returns> public static int Pack(string srcPath, string dstFile, ProgressDelegate.ProgressHandler progress = null, object sender = null, bool overwrite = true) { DateTime beginTime = DateTime.Now; if (!Directory.Exists(srcPath)) { return(-11); //要打包的路径不存在 } if (File.Exists(dstFile) && !overwrite) { return(-12); //打包后的目标文件已存在 } if (!DirTool.Create(DirTool.GetFilePath(dstFile))) { return(-14); //输出文件夹不存在 } List <string> tempfiles = FileTool.GetAllFile(srcPath); List <FilePackageModel> files = CreateFilePackageModel(tempfiles, srcPath); if (ListTool.HasElements(files)) { long allfilesize = files.Sum(x => x.Size); //文件总大小 long surplusfilesize = allfilesize; //剩余要写入的文件大小 using (FileStream fsWrite = new FileStream(dstFile, FileMode.Create)) { try { //写入文件类型标识和版本号 byte[] filetypeandversion = Encoding.Default.GetBytes(FileType + FileVersion); fsWrite.Write(filetypeandversion, 0, filetypeandversion.Length); //写入头部总长度 int headl = files.Sum(x => x.AllByteLength); byte[] headlength = BitConverter.GetBytes(headl); fsWrite.Write(headlength, 0, headlength.Length); //循环写入文件信息 files.ForEach(x => { fsWrite.Write(x.NameLengthByte, 0, x.NameLengthByte.Length); fsWrite.Write(x.NameByte, 0, x.NameByte.Length); fsWrite.Write(x.PathLengthByte, 0, x.PathLengthByte.Length); fsWrite.Write(x.PathByte, 0, x.PathByte.Length); fsWrite.Write(x.SizeLengthByte, 0, x.SizeLengthByte.Length); fsWrite.Write(x.SizeByte, 0, x.SizeByte.Length); fsWrite.Write(x.MD5LengthByte, 0, x.MD5LengthByte.Length); fsWrite.Write(x.MD5Byte, 0, x.MD5Byte.Length); }); //循环写入文件 files.ForEach(x => { //读取文件(可访问被打开的exe文件) using (FileStream fsRead = new FileStream(DirTool.Combine(srcPath, x.Path, x.Name), FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { int readCount = 0; byte[] buffer = new byte[FileBuffer]; while ((readCount = fsRead.Read(buffer, 0, buffer.Length)) > 0) { fsWrite.Write(buffer, 0, readCount); surplusfilesize -= readCount; progress?.Invoke(sender, new ProgressEventArgs(allfilesize - surplusfilesize, allfilesize)); } } }); } catch (Exception e) { } } if (surplusfilesize == 0) { return((int)Math.Ceiling((DateTime.Now - beginTime).TotalSeconds));//操作成功 } } else { return(-13);//要打包的路径中没有文件 } //打包失败后,删除打包后的文件 try { File.Delete(dstFile); } catch (Exception e) { } return(-404);//未知错误,操作失败 }
/// <summary> /// 拆包 /// </summary> /// <param name="srcFile">包文件路径</param> /// <param name="dstPath">拆包到的目录 </param> /// <param name="progress">回调进度</param> /// <param name="overwrite">覆盖拆包后的文件(重复时)</param> /// <returns> /// -11; //要解包的文件不存在 /// -12;//要解包的目标文件夹已存在 /// -20;// 文件类型不匹配 /// -99;//未知错误,操作失败 /// </returns> public static int Unpack(string srcFile, string dstPath, ProgressDelegate.ProgressHandler progress = null, object sender = null, bool overwrite = true) { DateTime beginTime = DateTime.Now; if (!File.Exists(srcFile)) { return(-11); //要解包的文件不存在 } if (Directory.Exists(dstPath) && !overwrite) { return(-12); //要解包的目标文件夹已存在 } using (FileStream fsRead = new FileStream(srcFile, FileMode.Open)) { try { string version = GetFileVersion(fsRead); if (version == null) { return(-20); // 文件类型不匹配 } //读取头部总长度 byte[] headl = new byte[4]; int headlength = 0; fsRead.Read(headl, 0, headl.Length); headlength = BitConverter.ToInt32(headl, 0); if (headlength > 0) { //读取文件列表信息 byte[] headdata = new byte[headlength]; fsRead.Read(headdata, 0, headlength); List <FilePackageModel> files = GetFilePackageModel(headdata); if (ListTool.HasElements(files)) { long allfilesize = files.Sum(x => x.Size); //文件总大小 long current = 0; //当前进度 //读取写出所有文件 files.ForEach(x => { if (DirTool.Create(DirTool.Combine(dstPath, x.Path))) { try { using (FileStream fsWrite = new FileStream(DirTool.Combine(dstPath, x.Path, x.Name), FileMode.Create)) { long size = x.Size; int readCount = 0; byte[] buffer = new byte[FileBuffer]; while (size > FileBuffer) { readCount = fsRead.Read(buffer, 0, buffer.Length); fsWrite.Write(buffer, 0, readCount); size -= readCount; current += readCount; progress?.Invoke(sender, new ProgressEventArgs(current, allfilesize)); } if (size <= FileBuffer) { readCount = fsRead.Read(buffer, 0, (int)size); fsWrite.Write(buffer, 0, readCount); current += readCount; progress?.Invoke(sender, new ProgressEventArgs(current, allfilesize)); } } } catch (Exception e) { fsRead.Seek(x.Size, SeekOrigin.Current); current += x.Size; progress?.Invoke(sender, new ProgressEventArgs(current, allfilesize)); } } }); //验证文件列表 bool allCheck = true; foreach (var file in files) { string temp = DirTool.Combine(dstPath, file.Path, file.Name); string tempCk = FileTool.GetMD5(temp); if (tempCk != file.MD5)//验证文件(Size:速度会快一些,MD5在大文件的验证上非常耗时) { allCheck = false; break; } } if (allCheck) { return((int)Math.Ceiling((DateTime.Now - beginTime).TotalSeconds)); //操作成功 } } } } catch (Exception e) { } } return(-99);//未知错误,操作失败 }
/// <summary> /// 文件加密 /// </summary> /// <param name="srcFile">源文件</param> /// <param name="dstFile">目标文件</param> /// <param name="password">加密密码</param> /// <param name="progress">回调进度</param> /// <param name="overwrite">是否覆盖已有目标文件</param> /// <returns> /// >0:操作成功(操作共计秒数) /// -11:要加密的文件不存在 /// -12:加密后的目标文件已存在 /// -404:未知错误,操作失败 /// </returns> public static int Encrypt(string srcFile, string dstFile, string password, ProgressDelegate.ProgressHandler progress = null, object sender = null, bool overwrite = true) { DateTime beginTime = DateTime.Now; if (!File.Exists(srcFile)) { return(-11); //要加密的文件不存在 } if (File.Exists(dstFile) && !overwrite) { return(-12); //加密后的目标文件已存在 } string fmtPwd = AesTool.FmtPassword(password); string pwdMd5 = MD5Tool.Encrypt(MD5Tool.Encrypt(fmtPwd)); string md5 = FileTool.GetMD5(srcFile); using (FileStream fsRead = new FileStream(srcFile, FileMode.Open)) { using (FileStream fsWrite = new FileStream(dstFile, FileMode.Create)) { try { //写入文件类型标识和版本号 byte[] filetypeandversion = Encoding.Default.GetBytes(FileType + FileVersion); fsWrite.Write(filetypeandversion, 0, filetypeandversion.Length); //文件头部数据定义 List <byte[]> headdata = new List <byte[]>() { Encoding.Default.GetBytes(FileType), Encoding.Default.GetBytes(md5), Encoding.Default.GetBytes(AesTool.Encrypt(fmtPwd, AesTool.DefaultPassword)), Encoding.Default.GetBytes(pwdMd5), Encoding.Default.GetBytes(DateTime.Now.ToString()) }; //写入头部信息个数 byte[] count = BitConverter.GetBytes(headdata.Count); fsWrite.Write(count, 0, count.Length); //写入各部分长度 for (int i = 0; i < headdata.Count; i++) { byte[] length = BitConverter.GetBytes(headdata[i].Length); fsWrite.Write(length, 0, length.Length); } //写入各部分数据 for (int i = 0; i < headdata.Count; i++) { fsWrite.Write(headdata[i], 0, headdata[i].Length); } //写入文件源数据 int readCount = 0; byte[] buffer = new byte[FileBuffer]; while ((readCount = fsRead.Read(buffer, 0, buffer.Length)) > 0) { if (readCount != buffer.Length) { byte[] temp = new byte[readCount]; Buffer.BlockCopy(buffer, 0, temp, 0, readCount); byte[] enbyte = AesTool.Encrypt(temp, fmtPwd); fsWrite.Write(enbyte, 0, enbyte.Length); } else { byte[] enbyte = AesTool.Encrypt(buffer, fmtPwd); fsWrite.Write(enbyte, 0, enbyte.Length); } progress?.Invoke(sender, new ProgressEventArgs(fsRead.Position, fsRead.Length)); } return((int)Math.Ceiling((DateTime.Now - beginTime).TotalSeconds));//操作成功 } catch (Exception e) { } } //加密失败后,删除加密的文件 try { File.Delete(dstFile); } catch (Exception e) { } } return(-404);//未知错误,操作失败 }
/// <summary> /// 文件解密 /// </summary> /// <param name="srcFile">源文件</param> /// <param name="dstFile">目标文件</param> /// <param name="password">解密密码</param> /// <param name="progress">回调进度</param> /// <param name="overwrite">是否覆盖已有目标文件</param> /// <returns> /// >0:操作成功(操作共计秒数) /// -11:要解密的文件不存在 /// -12:解密后的目标文件已存在 /// -20:文件类型不匹配 /// -30:文件头不长度不吻合 /// -90:解锁密码错误 /// -404:未知错误,操作失败 /// </returns> public static int Decrypt(string srcFile, string dstFile, string password, ProgressDelegate.ProgressHandler progress = null, object sender = null, bool overwrite = true) { DateTime beginTime = DateTime.Now; if (!File.Exists(srcFile)) { return(-11); //要解密的文件不存在 } if (File.Exists(dstFile) && !overwrite) { return(-12); //解密后的目标文件已存在 } string fmtPwd = AesTool.FmtPassword(password); string pwdMd5 = MD5Tool.Encrypt(MD5Tool.Encrypt(fmtPwd)); List <string> headdata = new List <string>(); using (FileStream fsRead = new FileStream(srcFile, FileMode.Open)) { try { //读取文件类型标识和版本号 byte[] filetype = Encoding.Default.GetBytes(FileType); fsRead.Read(filetype, 0, filetype.Length); string filetypestr = Encoding.Default.GetString(filetype); byte[] fileversion = Encoding.Default.GetBytes(FileVersion); fsRead.Read(fileversion, 0, fileversion.Length); string fileversionstr = Encoding.Default.GetString(fileversion); if (filetypestr != FileType && fileversionstr != FileVersion) { return(-20); //文件类型不匹配 } //读取头部信息个数 byte[] count = new byte[4]; fsRead.Read(count, 0, count.Length); int countint = BitConverter.ToInt32(count, 0); //读取各部分长度和数据 byte[] headlength = new byte[4 * countint]; if (fsRead.Read(headlength, 0, headlength.Length) == headlength.Length) { for (int i = 0; i < countint; i++) { int datalong = BitConverter.ToInt32(headlength, i * 4); byte[] tempdata = new byte[datalong]; fsRead.Read(tempdata, 0, datalong); headdata.Add(Encoding.Default.GetString(tempdata)); } } if (headdata.Count < 5) { return(-30); //文件头不长度不吻合 } if (pwdMd5 != headdata[3]) { return(-90); //解锁密码错误 } using (FileStream fsWrite = new FileStream(dstFile, FileMode.Create)) { int readCount = 0; byte[] buffer = new byte[FileBuffer + 16]; while ((readCount = fsRead.Read(buffer, 0, buffer.Length)) > 0) { if (readCount != buffer.Length) { byte[] temp = new byte[readCount]; Buffer.BlockCopy(buffer, 0, temp, 0, readCount); byte[] debyte = AesTool.Decrypt(temp, fmtPwd); fsWrite.Write(debyte, 0, debyte.Length); } else { byte[] debyte = AesTool.Decrypt(buffer, fmtPwd); fsWrite.Write(debyte, 0, debyte.Length); } progress?.Invoke(sender, new ProgressEventArgs(fsRead.Position, fsRead.Length)); } } } catch (Exception e) { } } string md5 = FileTool.GetMD5(dstFile); if (headdata.Count > 1 && md5 == headdata[1]) { return((int)Math.Ceiling((DateTime.Now - beginTime).TotalSeconds));//操作成功 } else { //解密失败后,删除解密的文件 try { File.Delete(dstFile); } catch (Exception e) { } } return(-404);//未知错误,操作失败 }