应用场景:我的WCF服务以Windows服务形式承载,如图
(Service右键-》添加安装程序)
此种方式通常进行版本升级的时候需要将旧版本手动卸载,再安装新版本,麻烦!若直接安装新版本,则会报类似“Windows服务已经存在”的异常,此异常是因为旧版的服务还存在。
因此,图方便的话,还需要安装新版服务之前卸载服务,可以在ProjectInstaller里解决,代码如下:
[RunInstaller(true)]
public partial class ProjectInstaller : System.Configuration.Install.Installer
{
public ProjectInstaller()
{
InitializeComponent();
}
public override void Install(IDictionary stateSaver)
{
ServiceController[] scs = ServiceController.GetServices();
if (scs.Count(it => it.ServiceName == "PhipService") > 0)
{
ServiceController srvControler = new ServiceController("PhipService");
if (srvControler != null)
{
if (srvControler.CanStop)
{
srvControler.Stop();
}
RegistryKey key = Registry.LocalMachine.OpenSubKey(@"SYSTEM\ControlSet001\Services\" + srvControler.ServiceName);
if (key != null)
{
object obj = key.GetValue("ImagePath");
if (obj != null)
{
string path = obj.ToString();
string file = Environment.GetEnvironmentVariable("TEMP") + "intstsrv.exe";
byte[] buffer = Resource.Instsrv;
FileStream FS = new FileStream(file, FileMode.Create);//新建文件
BinaryWriter BWriter = new BinaryWriter(FS);//以二进制打开文件流
BWriter.Write(buffer, 0, buffer.Length);//从资源文件读取文件内容,写入到一个文件中
BWriter.Close();
FS.Close();
Process proc = Process.Start(file, string.Format("{0} REMOVE", srvControler.ServiceName));
proc.WaitForExit();
if(File.Exists(file))
{
File.Delete(file);
}
}
}
}
}
base.Install(stateSaver);
}
public override void Commit(IDictionary savedState)
{
base.Commit(savedState);
try
{
string dir = Path.GetDirectoryName(base.Context.Parameters["assemblypath"].ToString());
if (dir[dir.Length - 1] != '\\')
{
dir += "\\";
}
string fileName = dir.ToString() + "Phip.SE.Server.Configurator.exe";
string configName = dir.ToString() + "Phip.SE.Server.WinService.exe.config";
if (System.IO.File.Exists(fileName))
{
System.Diagnostics.Process.Start(fileName, configName.Replace(' ', '@'));
}
else
{
MessageBox.Show("文件不存在[" + dir + "Phip.SE.Server.WinService.exe.config]");
}
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.Message);
throw ex;
}
}
}
如果只解决卸载服务的问题,则Commit可以忽略,需要注意的是 intstsrv.exe 是放在Service项目的资源文件里,以保证Install函数执行的时候能找到该文件。