我有一个使用C#构建的Windows服务,它是通过VS2008安装项目安装的,并且在卸载过程中遇到了一些问题:
卸载前未停止服务
当卸载例程运行时,它会引发有关正在使用的文件的错误。单击“继续”正确完成安装程序,但该服务仍显示在列表中,因此未正确卸载。
(目前,我不得不使用 sc delete servicename 手动删除它。)
我正在尝试在使用以下代码卸载之前停止服务,但它似乎没有生效:
protected override void OnBeforeUninstall(IDictionary savedState)
{
base.OnBeforeUninstall(savedState);
ServiceController serviceController = new ServiceController(MyInstaller.ServiceName);
serviceController.Stop();
}
何时调用此代码,如何在卸载之前停止服务?
卸载后未删除安装文件夹
应用程序在执行时还会在其安装文件夹中创建一些文件。卸载后,安装文件夹(C:\ Program Files \ MyApp)不会被删除,并且包含应用程序创建的文件,但安装程序实际安装的所有其他文件都已成功删除。
卸载过程是否可以删除安装文件夹,包括该文件夹中的所有生成文件,如果是,如何删除?
感谢。
答案 0 :(得分:7)
为了寻找这些问题答案的人的利益:
卸载前未停止服务
尚未找到解决方案。
卸载后未删除安装文件夹
需要覆盖项目安装程序中的OnAfterUninstall方法,并且必须删除任何创建的文件。如果应用程序安装程序文件夹在此步骤后不包含任何文件,则会自动删除该文件夹。
protected override void OnAfterUninstall(IDictionary savedState)
{
base.OnAfterUninstall(savedState);
string targetDir = Context.Parameters["TargetDir"]; // Must be passed in as a parameter
if (targetDir.EndsWith("|"))
targetDir = targetDir.Substring(0, targetDir.Length-1);
if (!targetDir.EndsWith("\\"))
targetDir += "\\";
if (!Directory.Exists(targetDir))
{
Debug.WriteLine("Target dir does not exist: " + targetDir);
return;
}
string[] files = new[] { "File1.txt", "File2.tmp", "File3.doc" };
string[] dirs = new[] { "Logs", "Temp" };
foreach (string f in files)
{
string path = Path.Combine(targetDir, f);
if (File.Exists(path))
File.Delete(path);
}
foreach (string d in dirs)
{
string path = Path.Combine(targetDir, d);
if (Directory.Exists(d))
Directory.Delete(d, true);
}
// At this point, all generated files and directories must be deleted.
// The installation folder will be removed automatically.
}
请记住,安装文件夹必须作为参数传递:
这会将安装文件夹作为参数传递给卸载例程,以便您知道应用程序的安装位置,并可以删除生成的文件和文件夹。
答案 1 :(得分:1)
这项服务很可能只需要一点时间就可以关闭,而且您会在服务完全停止之前继续服务。尝试调用WaitForStatus(ServiceControllerStatus)方法。
这将导致您的代码等待服务处理“停止”消息,然后关闭。一旦服务实际关闭,它将不再保留任何文件句柄。
答案 2 :(得分:0)
按照Mun的回答,通过在“OnAfterUninstall”功能中添加以下代码,Windows服务将被删除。
var process = new System.Diagnostics.Process();
process.StartInfo.FileName = "sc.exe";
process.StartInfo.Arguments = "delete \"" + serviceName + "\"";
process.StartInfo.CreateNoWindow = true;
process.Start();