2012-07-24 56 views
3

我有一個服務,我需要能夠啓動和停止一個按鈕。我在一個單獨的程序中使用一個ServiceController,當我以管理員身份運行此單獨程序時,一切都按預期工作。不過,我需要能夠像任何人一樣控制這項服務。我如何設置我的服務的權限,以便每個人都可以完全控制它?這需要以編程方式作爲服務的一部分或安裝。這是一個用vb.net寫的本地服務。如何在.net中爲Windows服務設置ACL?

回答

2

您有幾種選擇:

1)您可要求您的應用程序作爲管理員。每次啓動應用程序時,都會提示您使用UAC(在Windows 7和Vista上),並且您的應用程序將升級到所需級別。

Run .NET application as administrator

2)你的應用程序可以請求當需要採取行動,停止和啓動服務的提升。這將通過啓動另一個更高級別的應用程序來完成,而另一個應用程序將執行實際的啓動和停止。

How to elevate privileges only when required?

3)優先選擇,恕我直言 - 你應該建立自己的服務來運行所有的時間,但只是沒有做的比監聽通過TCP/IP請求,命名管道或其他一些通信機制的任何其他。然後,您的服務可以啓動或停止執行實際工作的線程。

4)您可以修改服務權限。這裏有一些帖子,讓對這個(我仍傾向於選擇3)一些信息:

我已經改變了一些文本

Start/Stop a Windows Service from a non-Administrator user account

http://msmvps.com/blogs/erikr/archive/2007/09/26/set-permissions-on-a-specific-service-windows.aspx

http://fstaal01.home.xs4all.nl/swsc-us.html

更新並根據Harry的評論添加了選項4。似乎有辦法調整權限。這些需要最初的管理員權限,但如果您將swsc(第三個鏈接)與您的安裝捆綁在一起,您可以使用它爲您設置權限。我不確定是否有任何許可證影響這樣做。或者,您可以使用他所粘貼的代碼的變體。

+0

這是錯誤的。您可以更改服務ACL,但這並不是特別困難。 – 2012-07-24 22:22:45

+0

謝謝,我已更新我的帖子並向上投票。 – Graymatter 2012-07-24 22:38:52

+0

我不同意你的建議,這個服務最好始終運行。公平地說,這取決於OP未提供的上下文,但作爲一般規則,最好僅在需要時啓動服務。即使在空閒時,他們仍在使用系統資源。 – 2012-07-24 22:44:27

1

我有的代碼是在C中,但它不應該太難以適應VB - 或者你可以把它放在一個DLL中。或者,您可以啓動命令shell並使用命令sc sdset

wchar_t sddl[] = L"D:" 
    L"(A;;CCLCSWRPWPDTLOCRRC;;;SY)"   
     // default permissions for local system 
    L"(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)" 
     // default permissions for administrators 
    L"(A;;CCLCSWLOCRRC;;;AU)"     
     // default permissions for authenticated users 
    L"(A;;CCLCSWRPWPDTLOCRRC;;;PU)"   
     // default permissions for power users 
    L"(A;;RP;;;IU)"       
     // added permission: start service for interactive users 
    ; 

DWORD InstallService() 
{ 
    SC_HANDLE manager, service; 
    PSECURITY_DESCRIPTOR sd; 
    DWORD err; 

    wchar_t apppath[MAX_PATH + 2]; 

    // Note: because this is only called from main() which exits 
    // immediately afterwards, no attempt is made to close the 
    // handles generated. 

    if (!ConvertStringSecurityDescriptorToSecurityDescriptor(sddl, 
     SDDL_REVISION_1, &sd, NULL)) 
    { 
    err = GetLastError(); 
    printf("Error %u creating security descriptor.\n", err); 
    return err; 
    } 

    if (!GetModuleFileName(0, apppath, MAX_PATH + 1)) 
    { 
    err = GetLastError(); 
    printf("Error %u fetching module name.\n", err); 
    return err; 
    } 

    if (_wcsicmp(apppath + wcslen(apppath) - wcslen(exename), exename) != 0) 
    { 
    printf("Application name mismatch: %ls\n", 
     apppath + wcslen(apppath) - wcslen(exename)); 
    return ERROR_INVALID_FUNCTION; 
    } 

    manager = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE); 

    if (!manager) 
    { 
    err = GetLastError(); 
    printf("Error %u connecting to service manager.\n", err); 
    return err; 
    } 

    service = CreateService(manager, 
    servicename, 
    displayname, 
    WRITE_DAC, 
    SERVICE_WIN32_OWN_PROCESS, 
    SERVICE_DEMAND_START, 
    SERVICE_ERROR_NORMAL, 
    apppath, 
    0, 
    0, 
    NULL, 
    NULL, 
    NULL); 

    if (!service) 
    { 
    err = GetLastError(); 
    printf("Error %u installing service.\n", err); 
    return err; 
    } 

    if (!SetServiceObjectSecurity(service, DACL_SECURITY_INFORMATION, sd)) 
    { 
    err = GetLastError(); 
    printf("Error %u setting service security.\n", err); 
    return err; 
    } 

    printf("Service successfully installed.\n"); 
    return 0; 
}