C#或 VB.NET通过 ServiceController 代码控制Windows服务安装卸载过程出错,对windows服务程序文件占用,无法释放资源问题

一、VS报的错误

二、代码

三、错误分析

1.首先,这个错误是因为文件权限问题引起的,笔者系统为WIN10,VS2017。笔者在给要控制安装启动的windows服务程序文件夹添加上“Everyone”权限后,是可以正常通过代码正常控制windows服务的安装、卸载、启动、停止。错误解决。笔者增加了一个自动给文件夹添加Everyone权限的函数,每次选定要操作的服务程序时,对其文件夹自动添加Everyone,代码如下。

VB.NET

 Sub AddSecurityControll2Folder(dirPath As String)

        '获取文件夹信息
        Dim Dir As DirectoryInfo = New DirectoryInfo(dirPath)
        '获得该文件夹的所有访问权限
        Dim dirSecurity As System.Security.AccessControl.DirectorySecurity = Dir.GetAccessControl(AccessControlSections.All)
        '设定文件ACL继承
        Dim inherit As InheritanceFlags = InheritanceFlags.ContainerInherit Or InheritanceFlags.ObjectInherit
        '添加ereryone用户组的访问权限规则 完全控制权限
        Dim everyoneFileSystemAccessRule As FileSystemAccessRule = New FileSystemAccessRule("Everyone", FileSystemRights.FullControl, inherit, PropagationFlags.None, AccessControlType.Allow)
        '添加Users用户组的访问权限规则 完全控制权限
        Dim usersFileSystemAccessRule As FileSystemAccessRule = New FileSystemAccessRule("Users", FileSystemRights.FullControl, inherit, PropagationFlags.None, AccessControlType.Allow)
        Dim isModified As Boolean = False
        dirSecurity.ModifyAccessRule(AccessControlModification.Add, everyoneFileSystemAccessRule, isModified)
        '设置访问权限
        Dir.SetAccessControl(dirSecurity)
    End Sub

C#

/// <summary>
///为文件夹添加users,everyone用户组的完全控制权限
/// </summary>
/// <param name="dirPath"></param>
static void AddSecurityControll2Folder(string dirPath)
{
    //获取文件夹信息
    DirectoryInfo dir = new DirectoryInfo(dirPath);
    //获得该文件夹的所有访问权限
    System.Security.AccessControl.DirectorySecurity dirSecurity = dir.GetAccessControl(AccessControlSections.All);
    //设定文件ACL继承
    InheritanceFlags inherits = InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit;
    //添加ereryone用户组的访问权限规则 完全控制权限
    FileSystemAccessRule everyoneFileSystemAccessRule = new FileSystemAccessRule("Everyone", FileSystemRights.FullControl, inherits, PropagationFlags.None, AccessControlType.Allow);
    //添加Users用户组的访问权限规则 完全控制权限
    FileSystemAccessRule usersFileSystemAccessRule = new FileSystemAccessRule("Users", FileSystemRights.FullControl, inherits, PropagationFlags.None, AccessControlType.Allow);
    bool isModified = false;
    dirSecurity.ModifyAccessRule(AccessControlModification.Add, everyoneFileSystemAccessRule, out isModified);dirSecurity.ModifyAccessRule(AccessControlModification.Add, usersFileSystemAccessRule, out isModified);
    //设置访问权限
    dir.SetAccessControl(dirSecurity);
}

2.通过这个错误,笔者发现另一个问题,上面标题二中报错时,虽然启动windows服务程序失败,虽然在Catch里对ServiceController的对象control进行了关闭和释放,且还有Using加持,但是当函数执行完时(windows服务因启动失败扔处于停止状态),这个windows服务程序文件(exe)是处于被占用状态【无法删除,笔者使用VS打开的该windows服务项目,也无法编译,显示下图的提示】。

当笔者,关掉控制安装卸载启停windows服务的程序时,时可以删除windows服务程序文件或者重新编译成功的,说明windows服务程序是被这个控制它安装卸载的程序给占用了的。

3.开始Using里的代码是没有Try Catch的,笔者怀疑是control.start(),出错后,直接跳出了函数,导致没有End Using。但是加了Try Catch后依然无效。

四、解决

1.笔者,试了control.close和dispose都无效果,百度了下也没有关于ServiceController类占用windows服务程序文件的条目。

2.开始Using里的代码是没有Try Catch的,笔者怀疑是control.start(),出错后,直接跳出了函数,导致没有End Using。但是加了Try Catch后依然无效。

3.目前应该是处于无头绪状态了,基本觉得可能出问题的点都尝试,调整了下思路,去针对ServiceController windows服务安装,百度下其他人的代码(笔者这个基本也是网上抄来的)。发现了有一个别的程序员并没用Using,OK,那我也删掉试试,因为我自己的观点“如果一个错误,你怎么查都查不出错误点,那它可能发生在你觉得最没问题的地方”。

果断删除Using  End Using。执行代码,报权限错误,Catch错误,关闭释放资源,服务扔未启动。笔者尝试删除或者重新编译该Windows服务,成功。

注:代码中control.close()就可以了,dispose方法没必要再调用一次。

五、原因

不详

可能是原因的相关博文链接:

https://blog.csdn.net/cracklibby/article/details/47335081

https://blog.csdn.net/yellowegg/article/details/7383416

猜你喜欢

转载自blog.csdn.net/iandbeyond/article/details/81412190
今日推荐