自动更新.
启动a程序.
检测b程序版本号.
然后根据版本号,在服务器上上传下载(判断是否更新).
由于要控制别人程序.所以还要检测别人程序的版本号.
不一致会发短信到开发人员
ICSharpCode.SharpZipLib.dll 解压缩工具
private string GetRequestDownFile(string url, string path)//HTTP下载 { try { // 设置参数 HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest; //发送请求并获取相应回应数据 HttpWebResponse response = request.GetResponse() as HttpWebResponse; //直到request.GetResponse()程序才开始向目标网页发送Post请求 Stream responseStream = response.GetResponseStream(); //创建本地文件写入流 Stream stream = new FileStream(path, FileMode.Create); byte[] bArr = new byte[1024]; int size = responseStream.Read(bArr, 0, (int)bArr.Length); while (size > 0) { stream.Write(bArr, 0, size); size = responseStream.Read(bArr, 0, (int)bArr.Length); } stream.Close(); responseStream.Close(); return path; } catch (Exception ef) { if (ef.Message == "未能解析此远程名称: 'ekaipiao.gingkoo.com'") { } if (ef.Message == "远程服务器返回错误: (404) 未找到。") { } return null; } }
网址对应服务器地址.http://ekaipiao.gingkoo.com/clients/GingkooPrint(14).exe
Client后面是相对路径
private void start() { Process p = new Process();//新建进程 p.StartInfo.FileName = Application.StartupPath + @"\Print.exe";//设置进程名字 p.StartInfo.CreateNoWindow = true; p.StartInfo.WindowStyle = ProcessWindowStyle.Normal; p.Start(); }
A程序启动B程序
file = GetRequestDownFile("http://ekaipiao.gingkoo.com/clients/Service.ini", Application.StartupPath + @"\Service.ini");
下载服务器版本号.如果大于.下载最新版本覆盖
保证速度.服务器上存放新版的ZIP.客户端下载后台解压启动.
FastZip fastZip = new FastZip();//解压缩对象
fastZip.ExtractZip(Application.StartupPath + @"\relase for Win7 or above.zip", Application.StartupPath, null);
//fastZip.ExtractZip(@"D:\test1.zip", @"D:\解压目录", null);//解压
//fastZip.CreateZip(@"D:\文档.zip", @"D:\来源目录", true, null);//压缩
无损喔
start(); Process[] proc = Process.GetProcesses(); foreach (var item in proc) { if (item.ProcessName.Contains("AutoUpdate"))//vshost { item.Kill(); } }
启动目标程序.就可以杀死自己了
如何去检测外部程序.
检测注册表.
如果是绿色软件就读取桌面快捷方式.
满电脑搜索就算了
private List<string> DesktopSean()//桌面搜索 { List<string> data = new List<string>(); string dir = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Desktop); DirectoryInfo dirInfo = new DirectoryInfo(dir); FileInfo[] files = dirInfo.GetFiles("*.lnk", SearchOption.TopDirectoryOnly);//当前目录 List<int> test = new List<int>(); foreach (FileInfo file in files) { data.Add(file.DirectoryName + "\\" + file.Name); // data.Add(AppDomain.CurrentDomain.SetupInformation.ApplicationBase+file); } return data; }
会把电脑上所有的快捷方式找出来.桌面上的EXE实际也是lnk
private string VersionSean(string item)//检测版本号 { IWshShortcut _shortcut = null; IWshShell_Class shell = new IWshShell_Class(); if (System.IO.File.Exists(item) == true) _shortcut = shell.CreateShortcut(item) as IWshShortcut;//通过快捷方式获取物理路径 var path1 = _shortcut.TargetPath; FileVersionInfo.GetVersionInfo(Path.Combine(path1)); FileVersionInfo myFileVersionInfo = FileVersionInfo.GetVersionInfo(path1);//通过物理路径获取版本号 return myFileVersionInfo.FileVersion; } private string WindowsVersionSean() { string windowsversion = null; OperatingSystem os = Environment.OSVersion; switch (os.Platform) { case PlatformID.Win32Windows: switch (os.Version.Minor) { case 0: windowsversion = "Windows 95 "; break; case 10: if (os.Version.Revision.ToString() == "2222A ") windowsversion = "Windows 98 第二版 "; else windowsversion = "Windows 98 "; break; case 90: windowsversion = "Windows Me "; break; } break; case PlatformID.Win32NT: switch (os.Version.Major) { case 3: windowsversion = "Windows NT 3.51 "; break; case 4: windowsversion = "Windows NT 4.0 "; break; case 5: switch (os.Version.Minor) { case 0: windowsversion = "Windows 200 "; break; case 1: windowsversion = "Windows XP "; break; case 2: windowsversion = "Windows 2003 "; break; } break; case 6: switch (os.Version.Minor) { case 0: windowsversion = "Windows Vista "; break; case 1: windowsversion = "Windows 7 "; break; } break; } break; } return windowsversion; }//检测Win版本
为什么要检测Win版本号呢。这个是自动更新的部分.因为WIN7和xp暂时不能用同一套源码.
var a = DesktopSean(); foreach (string item in a) { if (item.Contains("增值税发票税控开票软件(税控盘版).lnk"))//百旺 { Baiwang = VersionSean(item); } if (item.Contains("开票软件.lnk"))//航信 { Hangxin = VersionSean(item); } }
这样就可以读取到外部程序的版本号了
[DllImport("kernel32")] public static extern long WritePrivateProfileString(string section, string key, string val, string filePath); [DllImport("kernel32")] public static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath); GetPrivateProfileString("VersionData", "Key", "", temp, 500, file);//读 WritePrivateProfileString("VersionData", "Key", temp.ToString(), Application.StartupPath + @"\Client.ini");//写
这种方法可以操作INI文件
为什么要说呢.因为版本号在服务器的INI中
如果检测到客户端外部程序的版本号和服务器上存储的版本号不一致就准备发短信呀发邮件呀告诉我们的开发人员外部程序升级啦。看看有啥影响没~
public static string GetHtmlFromUrl(string url) { string strRet = null; if (url == null || url.Trim().ToString() == "") { return strRet; } string targeturl = url.Trim().ToString(); try { HttpWebRequest hr = (HttpWebRequest)WebRequest.Create(targeturl); hr.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)"; hr.Method = "GET"; hr.Timeout = 30 * 60 * 1000; WebResponse hs = hr.GetResponse(); Stream sr = hs.GetResponseStream(); StreamReader ser = new StreamReader(sr, Encoding.Default); strRet = ser.ReadToEnd(); } catch (Exception ex) { strRet = null; } return strRet; }
调的是SMS的接口
每个人可以免费发五条短信~
string name = GetHtmlFromUrl(" http://gbk.sms.webchinese.cn/?Uid=账号&Key=密钥&smsMob=收信人&smsText=内容 ");
public bool SendEmail(string StrTo, string strFrom, string StrBody, string strSubject, string name, string pwd, string path) { #region 检查邮箱的类别 string sHos = "smtp.qq.com";//根据发送邮箱地址获取你的smtp主机 if (name.Contains("@163")) { sHos = "smtp.163.com"; } else if (name.Contains("@126")) { sHos = "smtp.126.com"; } else if (name.Contains("@qq")) { sHos = "smtp.qq.com"; } else if (name.Contains("@sohu")) { sHos = "smtp.sohu.com"; } else if (name.Contains("@sina")) { sHos = "smtp.sina.com"; } else if (name.Contains("@tom")) { sHos = "smtp.tom.com.cn"; } else if (name.Contains("@foxmail")) { sHos = "smtp.foxmail.com"; } else if (name.Contains("@139")) { sHos = "smtp.139.com"; } #endregion //设置收发邮件人的地址 System.Net.Mail.MailAddress fromEmail = new System.Net.Mail.MailAddress(strFrom); System.Net.Mail.MailAddress toEmail = new System.Net.Mail.MailAddress(StrTo); //创建电子邮件对象 System.Net.Mail.MailMessage mail = new System.Net.Mail.MailMessage(fromEmail, toEmail); mail.Body = StrBody; //邮件内容 mail.Subject = strSubject; //邮件标题 mail.IsBodyHtml = true; //邮件是否包含html格式 mail.BodyEncoding = Encoding.UTF8; //邮件内容的编码方式 mail.Priority = System.Net.Mail.MailPriority.Normal; //邮件的发送优先级别 //邮递员 System.Net.Mail.SmtpClient smtpClient = new System.Net.Mail.SmtpClient(); smtpClient.Host = sHos;//设置成发件人的smtp主机名或者ip地址 smtpClient.Port = 25; //默认端口号 smtpClient.UseDefaultCredentials = false; //不使用当前用户的默认凭据进行身份验证,用Credentials进行身份验证 smtpClient.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network; smtpClient.Credentials = new System.Net.NetworkCredential(name, pwd);//你的用户名和密码 //以下是邮件附件部分,path是附件的客户端路径含文件名 if (path != "") { if (File.Exists(path)) { //设置附件的类型可以是任何类型的文件 Attachment attachment = new Attachment(path, System.Net.Mime.MediaTypeNames.Application.Octet); mail.Attachments.Add(attachment); } } try { smtpClient.Send(mail); } catch (Exception e) { //String s = e.Message; return false; } return true; }
SendEmail("收件人邮箱", "发件人邮箱", "标题", "内容", "发件人账号", "发件人密码", "附件");
就这样,如果客户端的软件检测到外部程序的版本号升级了。就会哭着闹着告诉开发人员
using System; using System.Diagnostics; using System.Reflection; using System.Windows.Forms; namespace AutoUpdate { static class Program { /// <summary> /// 应用程序的主入口点。 /// </summary> [STAThread] static void Main(string[] Args) { //Application.EnableVisualStyles(); //Application.SetCompatibleTextRenderingDefault(false); //Application.Run(new Update()); Process instance = RunningInstance(); if (instance == null) { //没有实例在运行 //Application.Run(new Login()); System.Security.Principal.WindowsIdentity identity = System.Security.Principal.WindowsIdentity.GetCurrent(); //创建Windows用户主题 Application.EnableVisualStyles(); System.Security.Principal.WindowsPrincipal principal = new System.Security.Principal.WindowsPrincipal(identity); //判断当前登录用户是否为管理员 if (principal.IsInRole(System.Security.Principal.WindowsBuiltInRole.Administrator)) { //如果是管理员,则直接运行 Application.EnableVisualStyles(); Application.Run(new Update()); } else { //创建启动对象 System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo(); //设置运行文件 Z startInfo.FileName = System.Windows.Forms.Application.ExecutablePath; //设置启动参数 startInfo.Arguments = String.Join(" ", Args); //设置启动动作,确保以管理员身份运行 startInfo.Verb = "runas"; //如果不是管理员,则启动UAC System.Diagnostics.Process.Start(startInfo); //退出 System.Windows.Forms.Application.Exit(); } } else { //已经有一个实例在运行 HandleRunningInstance(instance); } } private static Process RunningInstance() { Process current = Process.GetCurrentProcess(); Process[] processes = Process.GetProcessesByName(current.ProcessName); //遍历与当前进程名称相同的进程列表 foreach (Process process in processes) { //如果实例已经存在则忽略当前进程 if (process.Id != current.Id) { //保证要打开的进程同已经存在的进程来自同一文件路径 if (Assembly.GetExecutingAssembly().Location.Replace("/", "\\") == current.MainModule.FileName) { //返回已经存在的进程 return process; } } } return null; } private static void HandleRunningInstance(Process instance) { // MessageBox.Show("已经在运行!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Information); //ShowWindowAsync(instance.MainWindowHandle, 1); //调用api函数,正常显示窗口 //SetForegroundWindow(instance.MainWindowHandle); //将窗口放置最前端 } } }
简单点 .上面的Program包含了管理员启动和禁止多次启动.
代码是如何混淆并不关心.微软推出了DotNet REACTOR.EXE会用就行
open 添加主程序EXE
File添加其他程序
anti ildasm 是防止反编译
obfuscation 是代码混淆
string encryption 是 字符串加密