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服务安装时,系统会自动将windows服务的程序文件复制到系统目录下,通常是System32目录下,windows服务的运行目录就是系统目录,有时候,windows服务在运行时需要知道自己的安装目录,比如,windows服务运行时所需要的一些资源文件,通常可能是一些声音或图像文件,这些资源文件是位于安装目录下的,只有windows服务知道了安装目录,才能对这些资源文件进行访问,那么windows服务如何知道自己的安装目录的信息呢,一种比较简单的做法是通过访问注册表。

/*

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盘升级的更多相关文章

  1. (25)C#windows服务

    http://www.cnblogs.com/knowledgesea/p/3616127.html http://jingyan.baidu.com/article/fa4125acb71a8628 ...

  2. windows服务安装卸载

    到C盘下找到对应的开发VS的installutil.exe文件,复制到程序的执行文件(*.exe)相同目录下在开始程序中找到VS命令提示工具 转到程序的执行文件(*.exe)目录下 C:\>cd ...

  3. C# windows服务制作(包括安装及卸载)

    开篇语 因工作内容需要做一个windows服务,此前并没有相关经验,所以做了一个demo来跑跑这个梗(高手跳过,需要的来踩)- 效果如下:打开服务,可以找到我们新增的一个windows服务,这个dem ...

  4. 以 Console 方式运行、调试、编译 .Net 编写的 Windows 服务

    经常看到一些人在调试 Windows 服务时,很执著的在附加进程后调试!其实 .Net 编写的 Windows 应用程序,包括 Windows 服务都可以编译成 Console 程序!甚至于 ASP. ...

  5. .Net创建windows服务入门

    本文主要记录学习.net 如何创建windows服务. 1.创建一个Windows服务程序 2.新建安装程序 3.修改service文件 代码如下 protected override void On ...

  6. 不用写Windows服务实现定时器功能(FluentScheduler )

    MacBook Pro 只有四个 USB Type-C 接口是否错了? 一项新技术的诞生总会对已存在的事物造成冲击或影响,如果大家都害怕冲击与影响,那这个世界永远像现在不变就行了,大家都好好的,待在自 ...

  7. .net开发windows服务小结

        今天学习了在.net下创建一个windows服务,总结一下学习心得.     开发环境:visual studio 2012   一.编写程序 (1)创建一个空解决方法 (2)添加一个控制台应 ...

  8. C# 生成windows 服务打包程序

    c# 开发windows服务程序. 一个简单的服务程序示例. 归纳了几点.有不足之处,请赐教. 一.创建服务程序 1. 菜单栏“文件”--->“新建”--->“项目”,在项目类型中选择“w ...

  9. 把应用程序exe 注册成为windows 服务的方法

    由于在Windows 服务器上必须要启动一个软件,提供外网访问内网的客户端软件,但是由于每次远程服务器之后会注销当前用户,所以客户端软件就会自动退出,那么我在外网的系统就不能支持访问了. 解决方案:将 ...

随机推荐

  1. unity3d教程游戏包含的一切文件导入资源

    http://www.58player.com/blog-2327-954.html 导入资源 将文件增加至工程文件夹的资源 (Assets) 文件夹后,Unity 将自动检测文件.将任何资源 (As ...

  2. python 输入和输出

    到目前为止我们遇到过两种输出值的方法: 表达式语句和print语句. (第三个方式是使用文件对象的write()方法: 标准输出文件可以引用 sys.stdout.详细内容参见库参考手册. Pytho ...

  3. 基于php的snmp管理端开发

    一.系统环境: 操作系统:CentOS 5.4                内核:Linux_2.6 编译环境:gcc 4.1.2                代码版本:php-5.2.8.tar ...

  4. uniq命令注意事项,检查重复行的时候,只会检查相邻的行。

    今天在使用uniq命令统计数量时,uniq -c总是得不到想要的效果,相同的行没有合并,例如 后来在http://ju.outofmemory.cn/entry/78365才看到,原来uniq检查重复 ...

  5. linux命令——mutt的安装和使用【转】

    linux命令--mutt的安装和使用[转] 首先介绍一下mutt这个软件,它是一款基于文字界面的邮件客户端,非常小巧,但功能强大,可以用它来读写,回复保存和删除你的邮件,能在linux命令行模式下收 ...

  6. 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 ...

  7. HTML——meta标签

    <meta> 元素可提供有关页面的元信息(meta-information),比如针对搜索引擎和更新频度的描述和关键词. <meta> 标签位于文档的头部,不包含任何内容.&l ...

  8. oracle数据库两表数据比较

    本文转自http://blog.sina.com.cn/s/blog_3ff4e1ad0100tdl2.html 1 引言 在程序设计的过程中,往往会遇到两个记录集的比较.如华东电网PMS接口中实现传 ...

  9. poj 1511(spfa)

    ---恢复内容开始--- http://poj.org/problem?id=1511 一个spfa类的模板水题. 题意:就是求从1到n个点的来回的所有距离和. 对spfa类的题还是不太熟练,感觉还是 ...

  10. codeforces 501C. Misha and Forest 解题报告

    题目链接:http://codeforces.com/problemset/problem/501/C 题目意思:有 n 个点,编号为 0 - n-1.给出 n 个点的度数(即有多少个点跟它有边相连) ...