Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 卸载Windows服务的正确方法?_C#_Visual Studio 2008_Setup Project - Fatal编程技术网

C# 卸载Windows服务的正确方法?

C# 卸载Windows服务的正确方法?,c#,visual-studio-2008,setup-project,C#,Visual Studio 2008,Setup Project,我有一个windows服务,使用C#构建,通过VS2008安装项目安装,卸载过程中出现了几个问题: 卸载前不会停止服务 当卸载例程运行时,它会抛出一个有关正在使用的文件的错误。单击“继续”可正确完成安装程序,但该服务仍显示在列表中,因此无法正确卸载 (目前,我不得不使用sc delete servicename手动删除它) 我试图在使用以下代码卸载之前停止该服务,但它似乎没有生效: protected override void OnBeforeUninstall(IDictionary sav

我有一个windows服务,使用C#构建,通过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)不会被删除,其中包含应用程序创建的文件,但安装程序实际安装的所有其他文件已成功删除

卸载过程是否可以删除安装文件夹,包括该文件夹中生成的所有文件,如果可以,如何删除


谢谢。

这项服务很可能只是花了一点时间才关闭,而您在服务完全停止之前仍在继续。尝试调用该方法


这将导致代码等待服务处理“停止”消息并关闭。一旦该服务实际关闭,它将不再保留任何文件句柄。

为了方便任何寻求这些问题答案的人:

卸载前不会停止服务

目前还没有找到解决办法

卸载后未删除安装文件夹

需要覆盖项目安装程序中的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.
}
请记住,安装文件夹必须作为参数传入:

  • 右键单击安装项目,然后选择查看->自定义操作
  • 自定义操作将在主窗口中打开。右键单击卸载节点下的“来自XXX的主要输出”,然后选择“属性窗口”
  • 在“属性”窗口中的CustomActionData下,输入以下内容:/TargetDir=“[TargetDir]|”(请注意末端的管道,不要移除该管道)

这将安装文件夹作为参数传递给卸载例程,以便您知道应用程序的安装位置,并可以删除生成的文件和文件夹。

只需按照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();

我试过了,运气不好。进一步的调试显示,在Windows弹出“正在使用的文件”警告之前,没有调用任何卸载(OnBeforeUninstall、OnAfterUninstall、uninstall)方法,这就是服务没有停止的原因。啊,好的。另一个问题是,当您说“由应用程序创建的文件”时,您的意思是安装程序完成安装时不存在文件,而是在应用程序运行时创建的文件?这些文件可能需要手动清理(onafterinstall?)。。。许多安装程序在“自动”删除内容时会非常小心。是的,我通过将安装目录作为自定义参数传递,并重写OnAfterUninstall方法来删除应用程序创建的文件,成功地解决了这个问题。如果文件夹在此之后为空,安装程序会自动将其删除。我想亲自回答您的第一个问题。如果您有任何发现,请将其发布。@Mun我在卸载后将其添加到
OnAfterUninstall
方法中,但它表示该文件正被另一个进程或access deniedI使用。我建议不要使用这种方法。
sc.exe
实用程序是某些资源工具包的一部分,通常不会安装在客户端计算机上,因此此代码不会起任何作用。作为卸载过程的一部分,服务也应该被删除,并且不需要以这种方式删除。