3

我有一项服务,我需要能够通过按钮启动和停止。我在一个单独的程序中使用 ServiceController,当我以管理员身份运行这个单独的程序时,一切都按预期工作。但是,我需要能够像任何人一样控制这项服务。如何为我的服务设置权限,以便每个人都可以完全控制它?这需要作为服务或安装的一部分以编程方式完成。它是用 vb.net 编写的本地服务。

4

2 回答 2

3

你有几个选择:

1)您可以要求您的应用程序以管理员身份运行。每次您的应用程序启动时,系统都会提示您使用 UAC(在 Windows 7 和 Vista 上),并且您的应用程序将被提升到所需的级别。

以管理员身份运行 .NET 应用程序

2) 当需要停止和启动服务的操作时,您的应用程序可以请求提升。它将通过在更高级别启动另一个应用程序来做到这一点,而这个另一个应用程序将执行实际的启动和停止。

如何仅在需要时提升权限?

3)首选选项,恕我直言 - 您应该构建您的服务以始终运行,但除了通过 TCP/IP、命名管道或其他一些通信机制侦听请求之外,不要做任何事情。然后,您的服务可以启动或停止执行实际工作的线程。

4) 可以修改服务权限。以下是一些提供有关此信息的帖子(我仍然更喜欢选项 3):

从非管理员用户帐户启动/停止 Windows 服务

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(第三个链接)之类的东西与您的安装捆绑在一起,您可以使用它来为您设置权限。我不确定这样做是否对许可证有任何影响。或者,您可以使用他粘贴的代码的变体。

于 2012-07-24T19:22:49.457 回答
2

我的代码是用 C 语言编写的,但适应 VB 应该不会太难——或者你可以把它放在一个 DLL 中。或者,您可以启动命令外壳并使用该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;
}
于 2012-07-24T22:33:26.270 回答