.net 将windows service应用程序配置为用户不可编辑

.net 将windows service应用程序配置为用户不可编辑,.net,windows,winapi,service,.net,Windows,Winapi,Service,我有一个windows服务应用程序,安装在用户计算机上,并显示在服务页面(services.msc)下。我希望用户(通过服务UI)无法配置启动选项,如下面的屏幕截图所示(对于Windows Defender防病毒服务): 提前谢谢。@RbMm说得对 下面是一个使用C++中的WiAPI的例子。 #include <windows.h> #include <sddl.h> #pragma comment(lib, "Advapi32") int main() {

我有一个windows服务应用程序,安装在用户计算机上,并显示在服务页面(services.msc)下。我希望用户(通过服务UI)无法配置启动选项,如下面的屏幕截图所示(对于Windows Defender防病毒服务):

提前谢谢。

@RbMm说得对

下面是一个使用C++中的WiAPI的例子。

#include <windows.h>
#include <sddl.h>

#pragma comment(lib, "Advapi32")

int main()
{
    SC_HANDLE sHdl = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_ACCESS);
    if (sHdl == NULL)
        printf("OpenSCManager error: %d\n", GetLastError());

    SC_HANDLE serviceHdl = OpenService(sHdl, L"MyTestDirectXService", READ_CONTROL | WRITE_OWNER | WRITE_DAC);
    if (sHdl == NULL)
        printf("OpenService error: %d\n", GetLastError());

    char buf[1024];
    DWORD retLen = 0;

    // ### Query
    if(!QueryServiceObjectSecurity(serviceHdl, OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, buf, sizeof(buf), &retLen))
        printf("QueryServiceObjectSecurity error: %d\n", GetLastError());

    LPWSTR strBuf = NULL;
    unsigned long strLen = 0;
    if (!ConvertSecurityDescriptorToStringSecurityDescriptor(buf, SDDL_REVISION_1, OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, &strBuf, &strLen))
        printf("ConvertSecurityDescriptorToStringSecurityDescriptor error: %d\n", GetLastError());

    wprintf(strBuf);

    // ### Set
    PSECURITY_DESCRIPTOR sDescriptor = {0};
    if(!ConvertStringSecurityDescriptorToSecurityDescriptor(L"O:BAD:(A;;GA;;;SY)(A;;GRGX;;;IU)", SDDL_REVISION_1, &sDescriptor, NULL))
        printf("ConvertStringSecurityDescriptorToSecurityDescriptor error: %d\n", GetLastError());

    if (!SetServiceObjectSecurity(serviceHdl, OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, sDescriptor))
        printf("SetServiceObjectSecurity error: %d\n", GetLastError());

    // ### Check
    if (!QueryServiceObjectSecurity(serviceHdl, OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, buf, sizeof(buf), &retLen))
        printf("QueryServiceObjectSecurity error: %d\n", GetLastError());

    strBuf = NULL;
    strLen = 0;
    if (!ConvertSecurityDescriptorToStringSecurityDescriptor(buf, SDDL_REVISION_1, OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, &strBuf, &strLen))
        printf("ConvertSecurityDescriptorToStringSecurityDescriptor error: %d\n", GetLastError());

    wprintf(strBuf);

    getchar();
}

通过
SetServiceObjectSecurity
在您的服务上设置一些安全描述符。说:
O:BAD:(A;;GA;;;SY)(A;;GRGX;;;IU)
Hi hecate,你试过我答案中的样本了吗?如果它对您不起作用,请随时告诉我。@RbMM
SetServiceObjectSecurity()
函数不是解决此要求的推荐方法,因为它已被弃用。MSFT建议在aclapi.h@hecate-
SetServiceObjectSecurity
中使用
SetNamedSecurityInfoA()
函数,比较
SetNamedSecurityInfoW
更好、更有效,我建议准确地使用
SetServiceObjectSecurity
SetServiceObjectSecurity()函数不是解决此要求的推荐方法,因为它已被弃用。MSFT建议使用
aclapi.h
@hecate Update with
SetNamedSecurityInfo
函数示例中的
setnamedsecuritynfoa()
函数。
// ### Set
PSECURITY_DESCRIPTOR sDescriptor = { 0 };
if (!ConvertStringSecurityDescriptorToSecurityDescriptor(L"O:BAD:(A;;GA;;;SY)(A;;GRGX;;;IU)", SDDL_REVISION_1, &sDescriptor, NULL))
    printf("ConvertStringSecurityDescriptorToSecurityDescriptor error: %d\n", GetLastError());

char daclBuf[100];
char ownerBuf[100];
char abBuf[100];

DWORD abLen = sizeof(abBuf);
DWORD dLen = sizeof(daclBuf);
DWORD oLen = sizeof(ownerBuf);
DWORD sLen = 0;
DWORD gLen = 0;

// Only owner and DACL security information valid in String security descriptor so here set DACL and Primary Group buffer to NULL. 
BOOL returnVal = MakeAbsoluteSD(sDescriptor, abBuf, &abLen, (PACL)daclBuf, &dLen, NULL, &sLen, ownerBuf, &oLen, NULL, &gLen);
if ((!returnVal) && (ERROR_INSUFFICIENT_BUFFER) == GetLastError())
    printf("One or more of the buffers is too small.\n");

WCHAR serviceName[] = L"MySecondService";
DWORD result = SetNamedSecurityInfo(serviceName, SE_SERVICE, OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, ownerBuf, NULL, (ACL*)daclBuf, NULL);
if(ERROR_SUCCESS != result)
    printf("ConvertStringSecurityDescriptorToSecurityDescriptor error: %d\n", result);