自動更新.啟動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();
}
B程序啟動A程序
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 是 字符串加密