1. 程式人生 > >C#或 VB.NET通過 ServiceController 程式碼控制Windows服務安裝解除安裝過程出錯,對windows服務程式檔案佔用,無法釋放資源問題

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