windows服务 - C# U盘升级
1.左侧工具栏里有Timer控件,但是如果调用的是系统时间,就需要添加System.timer.timer空间下的控件。
2.服务编写之后,还不能由SCM(服务控制管理器)进行管理,需要给该服务添加装载器。在Service1.cs的设计视图,点击右键,选择“添加装载器”,系统默认就会添加ProjectInstaller.cs这个类
添加该类后,在该类的设计视图上可看到serviceInstaller1和serviceProcessInstaller1,分别设置其属性。
设置serviceInstaller1的运行方式为手动或者自动
设置serviceInstaller1的ServiceName,设置为什么,服务列表中就显示什么
设置serviceProcessInstaller1的运行账号为LocalSystem
3.用U盘实现自动升级软件
步骤:
1.软件打包zip
2.读取U盘 复制到指定位置
3.关闭软件 解压到指定位置
4.启动软件 删除zip
3.1 解压缩 (难点)
1.下载SharpZipLib.dll ,添加引用,添加一个解压类 UnZipClass.cs
UnZipClass.cs
UnZipClass.cs /// <summary>
/// 解压文件
/// </summary>
using System;
using System.Text;
using System.Collections;
using System.IO;
using System.Diagnostics;
using System.Runtime.Serialization.Formatters.Binary;
using System.Data;
using ICSharpCode.SharpZipLib.BZip2;
using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.Zip.Compression;
using ICSharpCode.SharpZipLib.Zip.Compression.Streams;
using ICSharpCode.SharpZipLib.GZip;
namespace TestWinform
{
public class UnZipClass
{
public void UnZip(string[] args)
{
ZipInputStream s = new ZipInputStream(File.OpenRead(args[0])); ZipEntry theEntry;
while ((theEntry = s.GetNextEntry()) != null)
{ string directoryName = Path.GetDirectoryName(args[1]);
string fileName = Path.GetFileName(theEntry.Name); //生成解压目录
Directory.CreateDirectory(directoryName); if (fileName != String.Empty)
{
//解压文件到指定的目录
FileStream streamWriter = File.Create(args[1] + 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;
}
} streamWriter.Close();
}
}
s.Close();
}
}
}
3.2 (启动进程难点)
因为启动进程的用户名是System,开启进程后,不会显示exe的界面,所以必须 【模拟用户开启进程】,调用方法
//模拟用户开启进程
SystemUser.CreateProcess(SystemUser.WTSGetActiveConsoleSessionId(), filePath, "");
SystemUser.cs
SystemUser.cs using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Text; namespace SupervisionWindowsService
{
class SystemUser
{
#region 获取/复制用户令牌,启动进程
internal const int GENERIC_ALL_ACCESS = 0x10000000; //访问权限 [StructLayout(LayoutKind.Sequential)]
public struct StartUpInfo
{
public Int32 cb;
public string lpReserved;
public string lpDesktop;
public string lpTitle;
public Int32 dwX;
public Int32 dwY;
public Int32 dwXSize;
public Int32 dwXCountChars;
public Int32 dwYCountChars;
public Int32 dwFillAttribute;
public Int32 dwFlags;
public Int16 wShowWindow;
public Int16 cbReserved2;
public IntPtr lpReserved2;
public IntPtr hStdInput;
public IntPtr hStdOutput;
public IntPtr hStdError;
} [StructLayout(LayoutKind.Sequential)]
public struct Process_Information
{
public IntPtr hProcess;
public IntPtr hThread;
public Int32 dwProcessID;
public Int32 dwThreadID;
} [StructLayout(LayoutKind.Sequential)]
public struct SecurityAttributes
{
public Int32 Length;
public IntPtr lpSecurityDescriptor;
public bool bInheritHandle;
} public enum SecurityImpersonationLevel
{
SecurityAnonymous,
SecurityIdentification,
SecurityImpersonation,
SecurityDelegation
} public enum TokenType
{
TokenPrimary = 1,
TokenImpersonation
} [DllImport("advapi32", SetLastError = true)]
public static extern bool OpenProcessToken(IntPtr processHandle, TokenAccessLevels desiredAccess, ref IntPtr htok); [DllImport("advapi32.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool CreateProcessAsUser(
IntPtr hToken,
string lpApplicationName,
string lpCommandLine,
ref SecurityAttributes lpProcessAttributes,
ref SecurityAttributes lpThreadAttributes,
bool bInheritHandle,
Int32 dwCreationFlags,
IntPtr lpEnvrionment,
string lpCurrentDirectory,
ref StartUpInfo lpStartupInfo,
ref Process_Information lpProcessInformation); [DllImport("advapi32.dll", SetLastError = true)]
public static extern bool DuplicateTokenEx(
IntPtr hExistingToken,
Int32 dwDesiredAccess,
ref SecurityAttributes lpThreadAttributes,
Int32 ImpersonationLevel,
Int32 dwTokenType,
ref IntPtr phNewToken); [DllImport("userenv.dll", SetLastError = true)]
public static extern bool CreateEnvironmentBlock(out IntPtr lpEnvironment, IntPtr hToken, bool bInherit); [DllImport("kernel32.dll")]
public static extern int WTSGetActiveConsoleSessionId(); [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool CloseHandle(IntPtr handle);
#endregion #region 模拟用户进程
/// <summary>
/// 调用方必须具备System权限
/// </summary>
/// <param name="sessionId"></param>
/// <param name="appFullName"></param>
/// <param name="args"></param>
public static void CreateProcess(int sessionId, string appFullName, string args)
{
if (!System.IO.File.Exists(appFullName))
{
throw new System.IO.FileNotFoundException(appFullName);
}
bool sucess = false;
IntPtr hToken = IntPtr.Zero, hDupedToken = IntPtr.Zero;
Process_Information pi = new Process_Information();
SecurityAttributes sa;
try
{
//服务程序中,通过桌面进程的SessionId来获得
Process explorer = null;
foreach (var process in Process.GetProcessesByName("explorer"))
{
if (process.SessionId == sessionId)
{
explorer = process;
break;
}
}
if (explorer == null)
{
TraceWin32Error("There has no Explorer process running yet!");
return;
}
Process.EnterDebugMode();
sucess = OpenProcessToken(explorer.Handle, TokenAccessLevels.Duplicate | TokenAccessLevels.Read | TokenAccessLevels.Impersonate, ref hToken);
if (!sucess)
{
TraceWin32Error("OpenProcessToken");
return;
}
sa = new SecurityAttributes();
sa.Length = Marshal.SizeOf(sa);
var si = new StartUpInfo();
si.cb = Marshal.SizeOf(si);
sucess = DuplicateTokenEx(
hToken,
GENERIC_ALL_ACCESS,
ref sa,
(int)SecurityImpersonationLevel.SecurityIdentification,
(int)TokenType.TokenPrimary,
ref hDupedToken
);
if (!sucess)
{
TraceWin32Error("DuplicateTokenEx");
return;
}
IntPtr lpEnvironment = IntPtr.Zero;
sucess = CreateEnvironmentBlock(out lpEnvironment, hDupedToken, false);
if (!sucess)
{
TraceWin32Error("CreateEnvironmentBlock");
return;
}
sucess = CreateProcessAsUser(
hDupedToken,
appFullName,
args,
ref sa, ref sa,
false, 0, IntPtr.Zero,
null,
ref si,
ref pi
);
if (!sucess)
{
TraceWin32Error("CreateProcessAsUser");
}
}
finally
{
if (hDupedToken != IntPtr.Zero) CloseHandle(hDupedToken);
if (pi.hProcess != IntPtr.Zero) CloseHandle(pi.hProcess);
if (pi.hThread != IntPtr.Zero) CloseHandle(pi.hThread);
Process.LeaveDebugMode();
}
} static void TraceWin32Error(string error)
{
//WriteLog("{0}\t{1}:Last Error Code[{2}]", DateTime.Now.ToString(), error, Marshal.GetLastWin32Error().ToString());
}
#endregion
}
}
3.3 获取当前工作目录(安装路径)
开始的情况这么写是错误的。
//获取当前工作目录
//string CurrentDirectoryPath = Environment.CurrentDirectory + \\Debug.zip;
/*
Windows服务在系统安装后会在注册表的 "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\[ServiceName]"下以服务的ServiceName建1个目录,目录中会有"ImagePath"节,这里保存的就是该服务的安装路径。
*/
//获取注册表的ImagePath路径
public static string GetWindowsServiceInstallPath(string ServiceName)
{
string key = "SYSTEM\\CurrentControlSet\\Services\\" + ServiceName;
string path = Registry.LocalMachine.OpenSubKey(key).GetValue("ImagePath").ToString();
path = path.Substring(0, path.LastIndexOf("\\"));
return path;
}
3.4 开启关闭进程辅助类
MyProcess.cs
MyProcess.cs using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text; namespace TestWinform
{
class MyProcess
{
/// <summary>
/// 得到进程名
/// </summary>
/// <param name="ProcName"></param>
/// <returns></returns>
public static bool getcloseProc(string ProcName)
{
bool result = false;
System.Collections.ArrayList procList = new System.Collections.ArrayList();
string tempName = "";
int begpos;
int endpos;
foreach (System.Diagnostics.Process thisProc in System.Diagnostics.Process.GetProcesses())
{
tempName = thisProc.ToString();
begpos = tempName.IndexOf("(") + 1;
endpos = tempName.IndexOf(")");
tempName = tempName.Substring(begpos, endpos - begpos);
procList.Add(tempName);
if (tempName == ProcName)
{
result = true;
}
}
return result;
}
/// <summary>
/// 关闭进程
/// </summary>
/// <param name="ProcName"></param>
/// <returns></returns>
public static bool closeProc(string ProcName)
{
bool result = false;
System.Collections.ArrayList procList = new System.Collections.ArrayList();
string tempName = "";
int begpos;
int endpos;
foreach (System.Diagnostics.Process thisProc in System.Diagnostics.Process.GetProcesses())
{
tempName = thisProc.ToString();
begpos = tempName.IndexOf("(") + 1;
endpos = tempName.IndexOf(")");
tempName = tempName.Substring(begpos, endpos - begpos);
procList.Add(tempName);
if (tempName == ProcName)
{
if (!thisProc.CloseMainWindow())
thisProc.Kill(); //当发送关闭窗口命令无效时强行结束进程
result = true;
}
}
return result;
}
/// <summary>
/// 开启进程(这个方法只能开启用户名为System)
/// </summary>
/// <param name="ppath"></param>
public static void MyProcessStart(string ppath)
{
Process MyProcess = new Process();
MyProcess.StartInfo.FileName = ppath;
MyProcess.StartInfo.Verb = "Open";
MyProcess.StartInfo.CreateNoWindow = true;
MyProcess.StartInfo.WindowStyle = ProcessWindowStyle.Maximized;
MyProcess.Start();
}
}
}
4.Service1.cs
Service1.cs
Service1.cs using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using Microsoft.Win32;
using SupervisionWindowsService;
using TestWinform; namespace WindowsServiceDemo
{
public partial class Service1 : ServiceBase
{
static bool auto = true; public Service1()
{
InitializeComponent();
} protected override void OnStart(string[] args)
{
timer1.Enabled = true;
timer1.Start(); } protected override void OnStop()
{
timer1.Stop();
timer1.Enabled = false;
} static void print(DriveInfo di)
{
Console.WriteLine("可移动磁盘为" + di.Name);
if (di.IsReady)
{
//path U盘根目录
string path = di.RootDirectory.ToString();
//pathNext U盘根目录下的Debug.zip
string pathNext = path + "Debug.zip";
//判断是U盘是否存在debug.zip
if (File.Exists(pathNext))
{
//获取当前工作目录
//string CurrentDirectoryPath = Environment.CurrentDirectory + "\\Debug.zip";
string CurrentDirectoryPath = GetWindowsServiceInstallPath("SupervisionWindowsService") + "\\Debug.zip";
//如果存在则删除
if (File.Exists(CurrentDirectoryPath))
{
File.Delete(CurrentDirectoryPath);
}
try
{
//(1)复制到本地目录
File.Copy(pathNext, CurrentDirectoryPath);
////(2)关闭进程TestForm
if (MyProcess.getcloseProc("TestWinform"))
{
MyProcess.closeProc("TestWinform");
} //(解压)2.SharpZipLib.dll - 解压
string[] FileProperties = new string[2];
FileProperties[0] = CurrentDirectoryPath;//待解压的文件
FileProperties[1] = GetWindowsServiceInstallPath("SupervisionWindowsService") + "\\";//解压后放置的目标目录
UnZipClass UnZc = new UnZipClass();
UnZc.UnZip(FileProperties);
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
} } //(3)开启进程
//readPool.QueueUserWorkItem(DialUpAuto);
string filePath = GetWindowsServiceInstallPath("SupervisionWindowsService") + "\\TestWinform.exe";
//string aimPath = filePath + "\\";
//string toPath = Path.Combine(aimPath, "TestOver.exe");
if (!MyProcess.getcloseProc("TestWinform"))
{
//模拟用户开启进程
SystemUser.CreateProcess(SystemUser.WTSGetActiveConsoleSessionId(), filePath, "");
//MyProcess.MyProcessStart(filePath);
}
} } //获取注册表的ImagePath路径
public static string GetWindowsServiceInstallPath(string ServiceName)
{
string key = "SYSTEM\\CurrentControlSet\\Services\\" + ServiceName;
string path = Registry.LocalMachine.OpenSubKey(key).GetValue("ImagePath").ToString();
path = path.Substring(0, path.LastIndexOf("\\"));
return path;
} private void timer1_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
timer1.Interval = 30000; DriveInfo[] dr = DriveInfo.GetDrives();
foreach (DriveInfo di in dr)
{
if (di.DriveType == DriveType.Removable)
{
print(di);
}
else if (di.DriveType == DriveType.Fixed)
{
Debug.WriteLine("{0}是本地磁盘。", di.Name);
}
}
} }
}
windows服务 - C# U盘升级的更多相关文章
- (25)C#windows服务
http://www.cnblogs.com/knowledgesea/p/3616127.html http://jingyan.baidu.com/article/fa4125acb71a8628 ...
- windows服务安装卸载
到C盘下找到对应的开发VS的installutil.exe文件,复制到程序的执行文件(*.exe)相同目录下在开始程序中找到VS命令提示工具 转到程序的执行文件(*.exe)目录下 C:\>cd ...
- C# windows服务制作(包括安装及卸载)
开篇语 因工作内容需要做一个windows服务,此前并没有相关经验,所以做了一个demo来跑跑这个梗(高手跳过,需要的来踩)- 效果如下:打开服务,可以找到我们新增的一个windows服务,这个dem ...
- 以 Console 方式运行、调试、编译 .Net 编写的 Windows 服务
经常看到一些人在调试 Windows 服务时,很执著的在附加进程后调试!其实 .Net 编写的 Windows 应用程序,包括 Windows 服务都可以编译成 Console 程序!甚至于 ASP. ...
- .Net创建windows服务入门
本文主要记录学习.net 如何创建windows服务. 1.创建一个Windows服务程序 2.新建安装程序 3.修改service文件 代码如下 protected override void On ...
- 不用写Windows服务实现定时器功能(FluentScheduler )
MacBook Pro 只有四个 USB Type-C 接口是否错了? 一项新技术的诞生总会对已存在的事物造成冲击或影响,如果大家都害怕冲击与影响,那这个世界永远像现在不变就行了,大家都好好的,待在自 ...
- .net开发windows服务小结
今天学习了在.net下创建一个windows服务,总结一下学习心得. 开发环境:visual studio 2012 一.编写程序 (1)创建一个空解决方法 (2)添加一个控制台应 ...
- C# 生成windows 服务打包程序
c# 开发windows服务程序. 一个简单的服务程序示例. 归纳了几点.有不足之处,请赐教. 一.创建服务程序 1. 菜单栏“文件”--->“新建”--->“项目”,在项目类型中选择“w ...
- 把应用程序exe 注册成为windows 服务的方法
由于在Windows 服务器上必须要启动一个软件,提供外网访问内网的客户端软件,但是由于每次远程服务器之后会注销当前用户,所以客户端软件就会自动退出,那么我在外网的系统就不能支持访问了. 解决方案:将 ...
随机推荐
- unity3d教程游戏包含的一切文件导入资源
http://www.58player.com/blog-2327-954.html 导入资源 将文件增加至工程文件夹的资源 (Assets) 文件夹后,Unity 将自动检测文件.将任何资源 (As ...
- python 输入和输出
到目前为止我们遇到过两种输出值的方法: 表达式语句和print语句. (第三个方式是使用文件对象的write()方法: 标准输出文件可以引用 sys.stdout.详细内容参见库参考手册. Pytho ...
- 基于php的snmp管理端开发
一.系统环境: 操作系统:CentOS 5.4 内核:Linux_2.6 编译环境:gcc 4.1.2 代码版本:php-5.2.8.tar ...
- uniq命令注意事项,检查重复行的时候,只会检查相邻的行。
今天在使用uniq命令统计数量时,uniq -c总是得不到想要的效果,相同的行没有合并,例如 后来在http://ju.outofmemory.cn/entry/78365才看到,原来uniq检查重复 ...
- linux命令——mutt的安装和使用【转】
linux命令--mutt的安装和使用[转] 首先介绍一下mutt这个软件,它是一款基于文字界面的邮件客户端,非常小巧,但功能强大,可以用它来读写,回复保存和删除你的邮件,能在linux命令行模式下收 ...
- Linux中增加软路由的两种方法/删除的方法
第一种: route add -net 172.16.6.0 netmask 255.255.255.0 gw 172.16.2.254 dev eth0 route del gw 172.1 ...
- HTML——meta标签
<meta> 元素可提供有关页面的元信息(meta-information),比如针对搜索引擎和更新频度的描述和关键词. <meta> 标签位于文档的头部,不包含任何内容.&l ...
- oracle数据库两表数据比较
本文转自http://blog.sina.com.cn/s/blog_3ff4e1ad0100tdl2.html 1 引言 在程序设计的过程中,往往会遇到两个记录集的比较.如华东电网PMS接口中实现传 ...
- poj 1511(spfa)
---恢复内容开始--- http://poj.org/problem?id=1511 一个spfa类的模板水题. 题意:就是求从1到n个点的来回的所有距离和. 对spfa类的题还是不太熟练,感觉还是 ...
- codeforces 501C. Misha and Forest 解题报告
题目链接:http://codeforces.com/problemset/problem/501/C 题目意思:有 n 个点,编号为 0 - n-1.给出 n 个点的度数(即有多少个点跟它有边相连) ...