Windows 7 中的 ServiceController 权限

发布于 2024-09-26 20:36:10 字数 879 浏览 7 评论 0原文

我有一个由服务和可执行文件组成的应用程序。本质上,它是一个表单应用程序,负责在特定情况下启动和停止服务。

在 Windows XP 上,应用程序使用以下代码可以很好地管理此问题:

ServiceController controller = new ServiceController();
controller.MachineName = ".";
controller.ServiceName = "XXXXXXXXXX";
controller.Stop();
controller.WaitForStatus(ServiceControllerStatus.Stopped, new TimeSpan(0, 0, 10));
controller.Start();

但在 Windows 7 上,即使我以管理员身份启动了该应用程序,我也会遇到以下异常:

System.InvalidOperationException: Cannot open XXXXXXXXXXXXX service on computer '.'. ---> System.ComponentModel.Win32Exception: Access is denied
   --- End of inner exception stack trace ---
   at System.ServiceProcess.ServiceController.GetServiceHandle(Int32 desiredAccess)
   at System.ServiceProcess.ServiceController.Start(String[] args)
   at System.ServiceProcess.ServiceController.Start()

我可以通过编程方式解决此问题吗?

I have an application which consists of a service and an executable. Essentially it's a forms application that is responsible for starting and stopping a service under specific circumstances.

On Windows XP the application manages this fine using the following code:

ServiceController controller = new ServiceController();
controller.MachineName = ".";
controller.ServiceName = "XXXXXXXXXX";
controller.Stop();
controller.WaitForStatus(ServiceControllerStatus.Stopped, new TimeSpan(0, 0, 10));
controller.Start();

But on Windows 7, even though I've started the application as an administrator, I get the following exception:

System.InvalidOperationException: Cannot open XXXXXXXXXXXXX service on computer '.'. ---> System.ComponentModel.Win32Exception: Access is denied
   --- End of inner exception stack trace ---
   at System.ServiceProcess.ServiceController.GetServiceHandle(Int32 desiredAccess)
   at System.ServiceProcess.ServiceController.Start(String[] args)
   at System.ServiceProcess.ServiceController.Start()

Is there anything I can do programmatically to resolve this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

青萝楚歌 2024-10-03 20:36:10

当您说您以管理员身份启动应用程序时,您的意思是在管理员组中的帐户下,还是通过请求管理员凭据的 UAC 提示?如果没有 UAC 凭据提示(或实际上以管理员帐户运行,而不是管理员组中的帐户),您的应用程序没有修改服务的权限,因此您看到的异常是正确的。

这段示例代码可以检查您的应用程序是否以管理员身份运行,如果没有,则启动 UAC 提示。

public static class VistaSecurity
{
    public static bool IsAdministrator()
    {
        WindowsIdentity identity = WindowsIdentity.GetCurrent();

        if (null != identity)
        {
            WindowsPrincipal principal = new WindowsPrincipal(identity);
            return principal.IsInRole(WindowsBuiltInRole.Administrator);
        }

        return false;
    }

    public static Process RunProcess(string name, string arguments)
    {
        string path = Path.GetDirectoryName(name);

        if (String.IsNullOrEmpty(path))
        {
            path = Environment.CurrentDirectory;
        }

        ProcessStartInfo info = new ProcessStartInfo
        {
            UseShellExecute = true,
            WorkingDirectory = path,
            FileName = name,
            Arguments = arguments
        };

        if (!IsAdministrator())
        {
            info.Verb = "runas";
        }

        try
        {
            return Process.Start(info);
        }

        catch (Win32Exception ex)
        {
            Trace.WriteLine(ex);
        }

        return null;
    }
}

When you say that you started the application as Administrator, do you mean under an account in the Administrators group, or via a UAC prompt that requests administrator credentials? Without the UAC credentials prompt (or actually running as the Administrator account, not an account within the Administrators group), your application does not have permissions to modify services, so the exception you're seeing is correct.

This bit of example code can check if your application is running as an administrator, and if not, launch a UAC prompt.

public static class VistaSecurity
{
    public static bool IsAdministrator()
    {
        WindowsIdentity identity = WindowsIdentity.GetCurrent();

        if (null != identity)
        {
            WindowsPrincipal principal = new WindowsPrincipal(identity);
            return principal.IsInRole(WindowsBuiltInRole.Administrator);
        }

        return false;
    }

    public static Process RunProcess(string name, string arguments)
    {
        string path = Path.GetDirectoryName(name);

        if (String.IsNullOrEmpty(path))
        {
            path = Environment.CurrentDirectory;
        }

        ProcessStartInfo info = new ProcessStartInfo
        {
            UseShellExecute = true,
            WorkingDirectory = path,
            FileName = name,
            Arguments = arguments
        };

        if (!IsAdministrator())
        {
            info.Verb = "runas";
        }

        try
        {
            return Process.Start(info);
        }

        catch (Win32Exception ex)
        {
            Trace.WriteLine(ex);
        }

        return null;
    }
}
晨光如昨 2024-10-03 20:36:10

仅供参考,如果您不明白为什么它在 Vista 或 7 中不起作用,即使当前用户位于管理员组中,这里是 MSDN 所说的

在 Windows Vista 中,用户帐户控制 (UAC) 确定用户的权限。如果您是内置管理员组的成员,则会为您分配两个运行时访问令牌:标准用户访问令牌和管理员访问令牌。默认情况下,您具有标准用户角色。当您尝试执行需要管理权限的任务时,您可以使用“同意”对话框动态提升您的角色。执行 IsInRole 方法的代码不会显示“同意​​”对话框。如果您处于标准用户角色,即使您位于内置管理员组,该代码也会返回 false。在执行代码之前,您可以通过右键单击应用程序图标并表明您要以管理员身份运行来提升权限。

我记得我第一次使用 7 时感到非常惊讶(我从未使用过 Vista)。

FYI, if you don't understand why it's not working in Vista or 7 even if the current user is in the administrator group, here is what MSDN has to say

In Windows Vista, User Account Control (UAC) determines the privileges of a user. If you are a member of the Built-in Administrators group, you are assigned two run-time access tokens: a standard user access token and an administrator access token. By default, you are in the standard user role. When you attempt to perform a task that requires administrative privileges, you can dynamically elevate your role by using the Consent dialog box. The code that executes the IsInRole method does not display the Consent dialog box. The code returns false if you are in the standard user role, even if you are in the Built-in Administrators group. You can elevate your privileges before you execute the code by right-clicking the application icon and indicating that you want to run as an administrator.

I remember I was quite surprised at 1st when using 7 (I never used Vista).

枯叶蝶 2024-10-03 20:36:10

您还可以尝试将应用程序的 UAC 设置为 "在代码中以管理员身份运行”

You can also try setting the UAC for your application to "Run as Administrator" in code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文