Winform 自动升级程序

news2025/8/7 3:17:54

抽时间整理下升级这块的功能,并封装一个升级工具包。

作为winform 程序员都有一个C/S端程序绕不过的问题。那就是如何升级程序?

程序升级两种1.启动时强制更新 2.自动、手动获取更新,并确认是否升级。

今天咱们介绍,自动或者手动更新功能。

       首先思考如何升级? 升级肯定要有一个新的升级文件包,还有一个本地版本和服务器版本号,因为这样才能对比是否升级。

       看下下面的升级提示:

 等待上面的升级下载程序完毕即可。会自动替换主程序,并启动主程序。

设计思路:我绘制了一张图可以从图中看。

 1. 主程序开始升级,会检查是否有升级器有就启动下载,没有就去先下载升级器

 2. 启动升级器,下载文件,下载后解压替换主程序。 并启动主程序。 

下载器的一些代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace AutoUpdate
{
    public partial class FrmMain : Form
    {
        public FrmMain()
        {
            InitializeComponent();
        }

        string Rootpath = Environment.CurrentDirectory;

        /// <summary>
        /// 本地存储目录
        /// </summary>
        string ZipFilePath = Common.FilePathConfig.DownZIPPath;
        /// <summary>
        /// 本地解压目录
        /// </summary>
        string UnFilePath = Common.FilePathConfig.UnDownZIPPath;

        /// <summary>
        /// 开始升级程序客户端 author:huochengyan
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Start_Click(object sender, EventArgs e)
        {
            timer1.Enabled = true;
            Thread th = new Thread(StartUpdate);
            th.IsBackground = true;
            th.Start();
        }
        /// <summary>
        /// 开始下载文件 升级
        /// </summary>
        private void StartUpdate()
        {
            bool result = Common.HttpHelper.HttpDownload(Common.FilePathConfig.DownZIPUrl, ZipFilePath, this.progressBar1, this.label2_tishi);
            timer1.Enabled = false;
            if (result)
            {
                RefThisForm("下载成功!");
                Thread.Sleep(100);
                RefThisForm("正在解压,请稍后");
                if (!Directory.Exists(UnFilePath))
                    Directory.CreateDirectory(UnFilePath);
                //UnFilePath = new FileInfo(ZipFilePath).DirectoryName;


                string reusult = Common.ZIPHelper.UnZipFile(ZipFilePath,UnFilePath);
                if (reusult != "")
                {
                    RefThisForm("解压成功!");
                    CheckUnZIPFile(reusult);
                }
                else
                {
                    RefThisForm("解压失败!压缩包路径:" + ZipFilePath);
                }
            }
            else
            {
                MsgShow("下载失败!");
            }


        }

        private void FrmMain_Load(object sender, EventArgs e)
        {
            InitConfig();
            FrmMain.CheckForIllegalCrossThreadCalls = false;

            //删除陈旧的历史下载记录ZIP信息
            try
            {
                File.Delete(ZipFilePath);
            }
            catch (Exception ex)
            {

            }
            //检查下载器文件的dll

            button1_Start_Click(null, null);

        }
        private void CheckFile()
        {
            string UnZipdllPath = Rootpath + "/ICSharpCode.SharpZipLib.dll";         
            if (!File.Exists(UnZipdllPath))
            {
                MessageBox.Show("下载器文件丢失:ICSharpCode.SharpZipLib.dll");
            }
        }
        private void InitConfig() {
            try
            {
                Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
                Common.FilePathConfig.DownZIPUrl = config.AppSettings.Settings["softURL"].Value;

            }
            catch (Exception ex)
            {
                MessageBox.Show("读取配置失败!" + ex.ToString());
            }
        }
        /// <summary>
        /// 检查文件 解压
        /// </summary>
        /// <param name="UnZipFilePath"></param>
        private void CheckUnZIPFile(string UnZipFileDirPath)
        { 
            string mainexe = UnZipFileDirPath + "/LongDeTools.exe";
            Directory.SetCurrentDirectory(Directory.GetParent(UnZipFileDirPath).FullName);
            string OldFolder = Directory.GetCurrentDirectory();
            if (!File.Exists(mainexe))
            {
                MessageBox.Show("未能找到主程序:" + mainexe);
                return;
            }
            else {
                //覆盖源目录文件 
                // string result=Common.FileHelper.CopyFolder(OldFolder,UnZipFileDirPath);
                //MessageBox.Show("请确认开始替换原始文件!");
                RefThisForm("安装中..."); //RefThisForm("替换原始主程序中。。。。");
               
                bool result1=Common.FileHelper.CopyOldLabFilesToNewLab(UnZipFileDirPath,OldFolder,0);
                if (result1)
                {
                    RefThisForm("安装中..."); //RefThisForm("替换原始程序完毕。。。。");
                    //清空解压的文件
                    FileInfo fileinfo = new FileInfo(UnZipFileDirPath);
                    try
                    {
                        if (Directory.Exists(fileinfo.FullName))
                        {
                            // MessageBox.Show("要删除的文件目录:" + fileinfo.FullName);
                            Common.FileHelper.DelectDir(fileinfo.FullName);
                            Common.FileHelper.DelectDir(Common.FilePathConfig.UnDownZIPPath);
                            GC.Collect();
                        }
                    }
                    catch (Exception ex)
                    {
                        MsgShow("清理下载文件垃圾失败!"+ex.ToString());
                    }
                }
                else
                {
                    MsgShow("升级失败!");
                }
            }
            //2. 启动新下载的程序  
        
            StartNewSystem();

            GC.Collect();

        }
        /// <summary>
        /// 启动最新下载的程序
        /// </summary>
        private void StartNewSystem()
        {
            //string path = Environment.CurrentDirectory;
            //Directory.SetCurrentDirectory(Directory.GetParent(path).FullName);
            //path = Directory.GetCurrentDirectory();
            //string mainexe = path + "/LongDeTools.exe";
            string  path=System.Windows.Forms.Application.StartupPath;
            string mainexe = "";
            if (Directory.Exists(path)) {
                mainexe = Directory.GetParent(path)+"/" + "LongDeTools.exe";
            }
            if (File.Exists(mainexe))
            {
               Process.Start(mainexe);
                RefThisForm("升级完成");
                MessageBox.Show("升级到最新版本!!!");
                this.Close();
               
            }
            else {
                MsgShow("要启动的文件不存在!!!"+mainexe);
            }
            ///清理下载的文件的缓存垃圾
            GC.Collect();
            
        }
        private void RefThisForm(string text)
        {
            this.Text = text;
        }
        /// <summary>
        /// 时间  戳 事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void timer1_Tick(object sender, EventArgs e)
        {
            //Console.WriteLine("时间timer\r\n"+DateTime.Now.ToString()+"\r\n");

            label2_tishi.Text = progressBar1.Value/1048576+"M/"+ progressBar1.Maximum/ 1048576 + "M";
            if(progressBar1.Value== progressBar1.Maximum)
                label2_tishi.Text= progressBar1.Maximum / 1048576 + "M/" + progressBar1.Maximum / 1048576 + "M";
        }

        private void MsgShow(string msg) {
            MessageBox.Show(msg);
        }

        private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            FrmSetServer frm = new FrmSetServer();
            frm.ShowDialog();
        }
    }
}

 

using ICSharpCode.SharpZipLib.Checksums;
using ICSharpCode.SharpZipLib.Zip;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace AutoUpdate.Common
{
    /// <summary>   
    /// 适用与ZIP压缩   
    /// </summary>   
    public class ZIPHelper
    {
        #region 压缩  

        /// <summary>   
        /// 递归压缩文件夹的内部方法   
        /// </summary>   
        /// <param name="folderToZip">要压缩的文件夹路径</param>   
        /// <param name="zipStream">压缩输出流</param>   
        /// <param name="parentFolderName">此文件夹的上级文件夹</param>   
        /// <returns></returns>   
        private static bool ZipDirectory(string folderToZip, ZipOutputStream zipStream, string parentFolderName)
        {
            bool result = true;
            string[] folders, files;
            ZipEntry ent = null;
            FileStream fs = null;
            Crc32 crc = new Crc32();

            try
            {
                ent = new ZipEntry(Path.Combine(parentFolderName, Path.GetFileName(folderToZip) + "/"));
                zipStream.PutNextEntry(ent);
                zipStream.Flush();

                files = Directory.GetFiles(folderToZip);
                foreach (string file in files)
                {
                    fs = File.OpenRead(file);

                    byte[] buffer = new byte[fs.Length];
                    fs.Read(buffer, 0, buffer.Length);
                    ent = new ZipEntry(Path.Combine(parentFolderName, Path.GetFileName(folderToZip) + "/" + Path.GetFileName(file)));
                    ent.DateTime = DateTime.Now;
                    ent.Size = fs.Length;

                    fs.Close();

                    crc.Reset();
                    crc.Update(buffer);

                    ent.Crc = crc.Value;
                    zipStream.PutNextEntry(ent);
                    zipStream.Write(buffer, 0, buffer.Length);
                }

            }
            catch
            {
                result = false;
            }
            finally
            {
                if (fs != null)
                {
                    fs.Close();
                    fs.Dispose();
                }
                if (ent != null)
                {
                    ent = null;
                }
                GC.Collect();
                GC.Collect(1);
            }

            folders = Directory.GetDirectories(folderToZip);
            foreach (string folder in folders)
                if (!ZipDirectory(folder, zipStream, folderToZip))
                    return false;

            return result;
        }

        /// <summary>   
        /// 压缩文件夹    
        /// </summary>   
        /// <param name="folderToZip">要压缩的文件夹路径</param>   
        /// <param name="zipedFile">压缩文件完整路径</param>   
        /// <param name="password">密码</param>   
        /// <returns>是否压缩成功</returns>   
        public static bool ZipDirectory(string folderToZip, string zipedFile, string password)
        {
            bool result = false;
            if (!Directory.Exists(folderToZip))
                return result;

            ZipOutputStream zipStream = new ZipOutputStream(File.Create(zipedFile));
            zipStream.SetLevel(6);
            if (!string.IsNullOrEmpty(password)) zipStream.Password = password;

            result = ZipDirectory(folderToZip, zipStream, "");

            zipStream.Finish();
            zipStream.Close();

            return result;
        }

        /// <summary>   
        /// 压缩文件夹   
        /// </summary>   
        /// <param name="folderToZip">要压缩的文件夹路径</param>   
        /// <param name="zipedFile">压缩文件完整路径</param>   
        /// <returns>是否压缩成功</returns>   
        public static bool ZipDirectory(string folderToZip, string zipedFile)
        {
            bool result = ZipDirectory(folderToZip, zipedFile, null);
            return result;
        }

        /// <summary>   
        /// 压缩文件   
        /// </summary>   
        /// <param name="fileToZip">要压缩的文件全名</param>   
        /// <param name="zipedFile">压缩后的文件名</param>   
        /// <param name="password">密码</param>   
        /// <returns>压缩结果</returns>   
        public static bool ZipFile(string fileToZip, string zipedFile, string password)
        {
            bool result = true;
            ZipOutputStream zipStream = null;
            FileStream fs = null;
            ZipEntry ent = null;

            if (!File.Exists(fileToZip))
                return false;

            try
            {
                fs = File.OpenRead(fileToZip);
                byte[] buffer = new byte[fs.Length];
                fs.Read(buffer, 0, buffer.Length);
                fs.Close();

                fs = File.Create(zipedFile);
                zipStream = new ZipOutputStream(fs);
                if (!string.IsNullOrEmpty(password)) zipStream.Password = password;
                ent = new ZipEntry(Path.GetFileName(fileToZip));
                zipStream.PutNextEntry(ent);
                zipStream.SetLevel(6);

                zipStream.Write(buffer, 0, buffer.Length);

            }
            catch
            {
                result = false;
            }
            finally
            {
                if (zipStream != null)
                {
                    zipStream.Finish();
                    zipStream.Close();
                }
                if (ent != null)
                {
                    ent = null;
                }
                if (fs != null)
                {
                    fs.Close();
                    fs.Dispose();
                }
            }
            GC.Collect();
            GC.Collect(1);

            return result;
        }

        /// <summary>   
        /// 压缩文件   
        /// </summary>   
        /// <param name="fileToZip">要压缩的文件全名</param>   
        /// <param name="zipedFile">压缩后的文件名</param>   
        /// <returns>压缩结果</returns>   
        public static bool ZipFile(string fileToZip, string zipedFile)
        {
            bool result = ZipFile(fileToZip, zipedFile, null);
            return result;
        }

        /// <summary>   
        /// 压缩文件或文件夹   
        /// </summary>   
        /// <param name="fileToZip">要压缩的路径</param>   
        /// <param name="zipedFile">压缩后的文件名</param>   
        /// <param name="password">密码</param>   
        /// <returns>压缩结果</returns>   
        public static bool Zip(string fileToZip, string zipedFile, string password)
        {
            bool result = false;
            if (Directory.Exists(fileToZip))
                result = ZipDirectory(fileToZip, zipedFile, password);
            else if (File.Exists(fileToZip))
                result = ZipFile(fileToZip, zipedFile, password);

            return result;
        }

        /// <summary>   
        /// 压缩文件或文件夹   
        /// </summary>   
        /// <param name="fileToZip">要压缩的路径</param>   
        /// <param name="zipedFile">压缩后的文件名</param>   
        /// <returns>压缩结果</returns>   
        public static bool Zip(string fileToZip, string zipedFile)
        {
            bool result = Zip(fileToZip, zipedFile, null);
            return result;

        }

        #endregion

        #region 解压  

        /// <summary>   
        /// 解压功能(解压压缩文件到指定目录)   
        /// </summary>   
        /// <param name="fileToUnZip">待解压的文件</param>   
        /// <param name="zipedFolder">指定解压目标目录</param>   
        /// <param name="password">密码</param>   
        /// <returns>解压结果</returns>   
        public static bool UnZip(string fileToUnZip, string zipedFolder, string password)
        {
            bool result = true;
            FileStream fs = null;
            ZipInputStream zipStream = null;
            ZipEntry ent = null;
            string fileName;

            if (!File.Exists(fileToUnZip))
                return false;

            if (!Directory.Exists(zipedFolder))
                Directory.CreateDirectory(zipedFolder);

            try
            {
                zipStream = new ZipInputStream(File.OpenRead(fileToUnZip));
                if (!string.IsNullOrEmpty(password)) zipStream.Password = password;
                while ((ent = zipStream.GetNextEntry()) != null)
                {
                    if (!string.IsNullOrEmpty(ent.Name))
                    {
                        fileName = Path.Combine(zipedFolder, ent.Name);
                        fileName = fileName.Replace('/', '\\');//change by Mr.HopeGi   

                        if (fileName.EndsWith("\\"))
                        {
                            Directory.CreateDirectory(fileName);
                            continue;
                        }

                        fs = File.Create(fileName);
                        int size = 2048;
                        byte[] data = new byte[size];
                        while (true)
                        {
                            size = zipStream.Read(data, 0, data.Length);
                            if (size > 0)
                                fs.Write(data, 0, data.Length);
                            else
                                break;
                        }
                    }
                }
            }
            catch
            {
                result = false;
            }
            finally
            {
                if (fs != null)
                {
                    fs.Close();
                    fs.Dispose();
                }
                if (zipStream != null)
                {
                    zipStream.Close();
                    zipStream.Dispose();
                }
                if (ent != null)
                {
                    ent = null;
                }
                GC.Collect();
                GC.Collect(1);
            }
            return result;
        }

        /// <summary>   
        /// 解压功能(解压压缩文件到指定目录)   
        /// </summary>   
        /// <param name="fileToUnZip">待解压的文件</param>   
        /// <param name="zipedFolder">指定解压目标目录</param>   
        /// <returns>解压结果</returns>   
        public static bool UnZip(string fileToUnZip, string zipedFolder)
        {
            bool result = UnZip(fileToUnZip, zipedFolder, null);
            return result;
        }

        #endregion

        #region  使用GZIP解压
        public static bool  UnZipFile(string zipFilePath)
        {
            if (!File.Exists(zipFilePath))
            {
                //Console.WriteLine("Cannot find file '{0}'", zipFilePath);
                return false;
            }
            try
            {
                using (ZipInputStream s = new ZipInputStream(File.OpenRead(zipFilePath)))
                {

                    ZipEntry theEntry;
                    while ((theEntry = s.GetNextEntry()) != null)
                    {

                        //Console.WriteLine(theEntry.Name);

                        string directoryName =Path.GetDirectoryName(theEntry.Name);
                        string fileName = Path.GetFileName(theEntry.Name);

                        // create directory
                        if (directoryName.Length > 0)
                        {
                            Directory.CreateDirectory(directoryName);
                        }

                        if (fileName != String.Empty)
                        {
                            using (FileStream streamWriter = File.Create(theEntry.Name))
                            {

                                int size = 2048;
                                byte[] data = new byte[2048];
                                while (true)
                                {
                                    size = s.Read(data, 0, data.Length);
                                    if (size > 0)
                                    {
                                        streamWriter.Write(data, 0, size);
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
                return true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
                return false;
            }
        }

        /// <summary>
        /// 解压文件 
        /// </summary>
        /// <param name="TargetFile">ZIP路径</param>
        /// <param name="fileDir">解压到的路径</param>
        /// <returns></returns>
        public static string UnZipFile(string TargetFile, string fileDir)
        {
            string rootFile = " ";
            try
            {
                //读取压缩文件(zip文件),准备解压缩
                ZipInputStream s = new ZipInputStream(File.OpenRead(TargetFile.Trim()));
                ZipEntry theEntry;
                string path = fileDir;
                //解压出来的文件保存的路径

                string rootDir = " ";
                //根目录下的第一个子文件夹的名称
                while ((theEntry = s.GetNextEntry()) != null)
                {
                    rootDir = Path.GetDirectoryName(theEntry.Name);
                    //得到根目录下的第一级子文件夹的名称
                    if (rootDir.IndexOf("\\") >= 0)
                    {
                        rootDir = rootDir.Substring(0, rootDir.IndexOf("\\") + 1);
                    }
                    string dir = Path.GetDirectoryName(theEntry.Name);
                    //根目录下的第一级子文件夹的下的文件夹的名称
                    string fileName = Path.GetFileName(theEntry.Name);
                    //根目录下的文件名称
                    if (dir != " ")
                    //创建根目录下的子文件夹,不限制级别
                    {
                        if (!Directory.Exists(fileDir + "\\" + dir))
                        {
                            path = fileDir + "\\" + dir;
                            //在指定的路径创建文件夹
                            Directory.CreateDirectory(path);
                            //MessageBox.Show(path);
                        }
                    }
                    else if (dir == " " && fileName != "")
                    //根目录下的文件
                    {
                        path = fileDir;
                        rootFile = fileName;
                    }
                    else if (dir != " " && fileName != "")
                    //根目录下的第一级子文件夹下的文件
                    {
                        if (dir.IndexOf("\\") > 0)
                        //指定文件保存的路径
                        {
                            path = fileDir + "\\" + dir;
                        }
                    }

                    if (dir == rootDir)
                    //判断是不是需要保存在根目录下的文件
                    {
                        path = fileDir + "\\" + rootDir;
                    }

                    //以下为解压缩zip文件的基本步骤
                    //基本思路就是遍历压缩文件里的所有文件,创建一个相同的文件。
                    if (fileName != String.Empty)
                    {
                        FileStream streamWriter = File.Create(path + "\\" + fileName);

                        int size = 2048;
                        byte[] data = new byte[2048];
                        while (true)
                        {
                            size = s.Read(data, 0, data.Length);
                            if (size > 0)
                            {
                                streamWriter.Write(data, 0, size);
                            }
                            else
                            {
                                break;
                            }
                        }

                        streamWriter.Close();
                    }
                }
                s.Close();

                return fileDir;
            }
            catch (Exception ex)
            {
                MessageBox.Show("解压失败,升级包路径为:"+ fileDir+"\r\n"+"异常为:"+ex.ToString());
                return "";
            }
        }

        #endregion
    }

}

启动两个下载参数:1. 下载文件位置 2. 下载文件版本号位置

做了一个配置界面:

主程序调用下载器:

   #region 检查更新

        private void 检查更新ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string checkVersion = "http://xxxx.com/NewVersion.txt";
            string newVersion = HttpHelper.GetHttpResponse(checkVersion, 5000,null);
            Console.WriteLine(newVersion);
            Version yun = new Version(newVersion);
            Version ben = new Version(this.ProductVersion);
            if (yun > ben)
            {
                String msg = string.Format("您当前版本:{0},最新版本为:{1},确定要升级到最新版本吗?", this.ProductVersion,newVersion);
                if (DialogResult.OK == MessageBox.Show(msg, "升级提示:升级过程中,将暂停服务!", MessageBoxButtons.OKCancel))
                {
                    ExistDownUpdateSoft();
                    Process.Start(this.applicationPath + "/AutoUpdate/AutoUpdate.exe");
                    CloseAll();
                }
            }
            else {
                MessageBox.Show("已经是最新版!");
            }          
        }

        /// <summary>
        /// 没有升级组件就下载,有就更新。直接返回
        /// </summary>
        /// <returns></returns>
        private bool ExistDownUpdateSoft() {
            if (!File.Exists(this.applicationPath + "/AutoUpdate/AutoUpdate.exe"))
            {
                FrmForm.FrmUpdate frmUpdate = new FrmForm.FrmUpdate();
                DialogResult result = frmUpdate.ShowDialog();
                if (result == DialogResult.OK)
                {
                    return true;
                }
            }
            return true;
        }

        private void CloseAll() {
            System.Environment.Exit(0);
            if (myThread != null)
            {
                myThread.Abort();
            }
            // 关闭所有的线程
            this.Dispose();
            this.Close();
        }

        #endregion

如果将下载更新事件放到启动初始化中,就是成强制更新咯。

至此winform自动升级程序完成!!!

源代码会开源。需要的私信小编。。。。。。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/15713.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

路由进阶:route-policy实验配置

实验拓扑 网络拓扑及IP编址如上图所示&#xff1b;R1、R2运行RIPv2&#xff0c;R2、R3运行OSPF。R1上开设三个Loopback接口&#xff0c;地址分别是192.168.1.1/24、192.168.2.1/24及192.168.3.1/24&#xff0c;R1并没有在这三个接口上激活RIPv2&#xff1b; 实验需求 R1在RIP…

[附源码]计算机毕业设计JAVA航空售票管理系统

[附源码]计算机毕业设计JAVA航空售票管理系统 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybati…

智慧安防解决方案-最新全套文件

智慧安防解决方案-最新全套文件一、建设背景二、思路架构三、建设方案二、获取 - 智慧安防全套最新解决方案合集一、建设背景 随着经济的发展和城市建设速度的加快&#xff0c;全球各地区的安全问题接踵而至&#xff0c;我国正进入“突发公共事件的高发期”和“社会高风险期”…

LabVIEW性能和内存管理 6

LabVIEW性能和内存管理 6 本文介绍LabVIEW性能和内存管理的几个建议6。 数据空间Dataspaces VI的数据存储在它的数据空间中 每个VI都有自己的数据空间 可重入VIs有多个数据空间 可重入性和数据空间 不可重入的 每个调用共享一个数据空间 一次只能执行一个调用 …

如何把PDF转换成Word文档?给大家分享三种转换方法

如何将PDF文件的格式转换成Word文档来使用呢&#xff1f;对文件的格式转换&#xff0c;相信大家最常转换格式的文件就是这两种了&#xff0c;因为它们存在我们日常的各个角落。我们在工作中需要使用Word来编辑文字&#xff0c;发送或者是下载文件&#xff0c;基本都是PDF格式。…

EN 16034门窗及配件—CE认证

门窗及配件CE认证&#xff08;欧盟强制认证&#xff09;&#xff0d;简介 在欧盟市场“CE”标志属强制性认证标志&#xff0c;以表明产品符合欧盟《技术协调与标准化新方法》指令的基本要求。这是欧盟法律对产品提出的一种强制性要求。 在门窗及配件上加贴CE标志不但可以证明其…

从零开始学习Linux(1)

Linux基本操作 文章目录Linux基本操作前言一、操作系统相关知识1.什么是操作系统&#xff1f;2.操作系统有什么作用二、Linux基本操作1.ls指令2.pwd命令3.cd命令3.热键4.touch指令5.nano指令6.start指令7.mkdir指令&#xff08;重要&#xff09;8.rmdir指令&&rm指令&am…

蓝牙学习二(连接和通讯简述)

1.简介 蓝牙的通信是双向的&#xff0c;为了创建和维护一个BLE通信连接&#xff0c;在蓝牙中引入了“角色”这一概念&#xff0c;一个BLE设备不是主机&#xff08;集中器&#xff09;就是从机&#xff08;外围设备&#xff09;角色&#xff0c;这是根据是谁发起这个连接来确定的…

JVM - G1收集器、Region、停顿时间模型、垃圾回收(建议收藏)

​ 编辑切换为居中 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; Region 使用G1收集器时&#xff0c;java堆的内存会划分为多个大小相等的独立区域&#xff08;Region&#xff09;&#xff0c;Region中也有新生代和老年代的概念&#xff0c;但是新生…

Source Insight是一个面向项目开发的程序编辑器和代码浏览器丨产品简介

Source Insight是为大型、高要求的现实世界编程项目而设计的。事实上&#xff0c;今天&#xff0c;重要的技术公司正在使用Source Insight来开发一些最大、最成功的商业硬件和软件产品。 代码分析 Source Insight会在您工作时动态解析您的源代码并维护自己的符号信息数据库&a…

Redis实战篇(六)用户签到、UV统计

一、用户签到 1、BitMap用法 我们按月来统计用户签到信息&#xff0c;签到记录为1&#xff0c;未签订则记录为0。 把每一个bit位对应每月的一天&#xff0c;形成映射关系。用0和1标识业务状态&#xff0c;这种思路称为位图&#xff08;BitMap&#xff09;。 Redis中利用strin…

qt qml

QT Quick是QT提供的一种高级用户界面工具包&#xff0c;包含对QML完美支持. Qt Quick 就是使用 QML 构建的一套类库。 Qml模块本身并没有涉及图形显示&#xff0c;所有的图形处理都由Qt Quick模块完成。 QMl是一种高效的开发UI 的语言。QML&#xff08;Qt Meta-Object Languag…

对接建行支付

前两篇文章介绍了对接微信支付和农行支付的方法&#xff0c;这篇文章介绍一下建行支付。 使用场景&#xff1a; 在微信公众号中调用微信付款&#xff0c;或者公众号内页面调用龙支付或者H5页面支付。 一、微信支付 参考建行给的接口文档 交易流程如下&#xff1a; 按照接口要求…

sync_binlog和innodb_flush_log_at_trx_commit的区别

innodb_flush_log_at_trx_commi 这个指的是写redo及后续操作&#xff0c;ib_logfile这个文件的刷新方式。 sync_binlog纯粹指的是binlog &#xff0c;如 mysql-bin0003等。 基于innodb_flush_log_at_trx_commit 的三个参数的解释。 Innodb_flush_log_at_trx_commit 0 redolo…

代码随想录59——单调栈:503下一个更大元素II、42接雨水

文章目录1.503下一个更大元素II1.1.题目1.2.解答2.42接雨水2.1.题目2.2.解答2.2.1.双指针for循环解法2.2.3.单调栈解法1.503下一个更大元素II 参考&#xff1a;代码随想录&#xff0c;503下一个更大元素II&#xff1b;力扣题目链接 1.1.题目 1.2.解答 做本题之前建议先做 73…

Spring Boot 集成freemarker模板引擎

前言 J2EE的领域中包含5大引擎&#xff0c;分别为模板引擎、流程引擎、搜索引擎、规则引擎、报表引擎。每种引擎都能解决某一方面的问题&#xff0c;模板引擎解决的是用户界面与业务数据分离&#xff0c;流程引擎解决的是驱动业务按照一定的流程执行&#xff0c;搜索引擎解决的…

局部线性分析(机器学习)

目录 局部线性嵌入&#xff08;LLE&#xff09; 局部线性嵌入&#xff08;LLE&#xff09;算法的主要步骤分为三步 效果如下 局部线性嵌入&#xff08;LLE&#xff09; 局部线性嵌入&#xff08;LLE&#xff09;是一种非线性降维算法 它能够使降维后的数据较好地保持原有流…

大学生HTML个人网页作业作品:基于html css实现围棋网页(带报告4800字)

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

动静态链接动静态库制作与使用

前置知识 程序的编译与链接&#xff1a;动静态库属于程序链接阶段的概念&#xff0c;如果对程序的编译链接过程不太熟悉&#xff0c;可以先看一下着篇文章gcc&动静态链接&#xff1a;这篇文章讲解了如何在Linux环境下用gcc完成编译链接的每一步操作 链接库 在链接的过程…

Java对象内存结构和创建过程

文章目录对象的内存布局对象头Mark WordKlass Pointer实例数据对齐数据对象的创建总结对象的内存布局 我们的对象一般存储在我们的堆内存中&#xff0c;我们把实例对象可以划分为对象头&#xff0c;实例数据&#xff0c;对齐填充 对象头&#xff08;object header&#xff09…