12

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

在 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()

有什么我可以通过编程方式解决这个问题的吗?

4

3 回答 3

13

当您说您以管理员身份启动应用程序时,您是指在管理员组中的帐户下,还是通过请求管理员凭据的 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;
    }
}
于 2010-10-08T15:52:28.530 回答
3

仅供参考,如果您不明白为什么即使当前用户在管理员组中它也不能在 Vista 或 7 中工作,这就是 MSDN 必须说的

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

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

于 2011-10-12T03:33:48.123 回答
1

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

于 2010-11-24T08:16:21.297 回答