以编程方式有选择地禁用Windows上的特定程序的UAC

时间:2013-03-03 21:29:05

标签: c# windows scheduled-tasks uac

在堆栈和其他论坛上有很多关于禁用/绕过/抑制UAC的帖子问题/答案。也有解决方案。但进步可能不是。我只能看到一个解决方案Disabling UAC programmatically,但也许没有真正的程序化解决方案。

可以有一个程序化的解决方案,用于保存用户每次运行像wamp这样的程序时都会被提示,并且他们总是必须单击是,所以告诉Windows他们的选择总是肯定会更好。我相信会有

我发现Here windows通过GUI在Task Scheduler中提供了这个功能,所以它也必须通过代码才能实现。

更新:我准备了一个正在运行的纯编程解决方案。看到我的回答。

3 个答案:

答案 0 :(得分:12)

快速描述:创建一个新的控制台/窗口应用程序以绕过UAC运行任何应用程序,在下面的指导下选择此应用程序中目标应用程序的路径,编译此程序一次,并随时运行

一步一步

  1. This Codeplex link
  2. 下载Microsoft.Win32.TaskScheduler.dll
  3. 创建一个c#应用程序(Windows或控制台)并添加对上面的dll
  4. 的引用
  5. 将新项目(应用程序清单文件)添加到您的项目(此应用程序)
  6. 更改<requestedExecutionLevel level="asInvoker" uiAccess="false" /><requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
  7. 在program.cs文件中写下以下代码

  8. using System;
    using Microsoft.Win32.TaskScheduler;
    class Program
    {
       static void Main(string[] args)
       {
          TaskService ts = new TaskService();          
          TaskDefinition td = ts.NewTask();
          td.Principal.RunLevel = TaskRunLevel.Highest;
          //td.Triggers.AddNew(TaskTriggerType.Logon);          
          td.Triggers.AddNew(TaskTriggerType.Once);    // 
          string program_path = @"c:\wamp\wampmanager.exe"; // you can have it dynamic
    //even of user choice giving an interface in win-form or wpf application
    
          td.Actions.Add(new ExecAction(program_path, null));
          ts.RootFolder.RegisterTaskDefinition("anyNamefortask", td);          
       }
    }
    

    6.现在编译并运行您的应用程序(此应用程序)


    现在您的应用程序(例如WAMP)将在没有按照您所希望的时间表提示任何UAC对话框的情况下运行(在我的情况下每次登录窗口时)

    <强>来源

    发起人:Can you turn off UAC for a single app?Selectively disabling UAC for specific programs on Windows 7

    基本构思来自:Make Vista launch UAC restricted programs at startup with Task Scheduler

    Creating Scheduled Tasks

    的基本实施

答案 1 :(得分:2)

正确的方法不是忽略用户访问控制(UAC),而是在这些参数内进行测试。这样你就不会破坏安全性,而是在你的范围内工作。

通过禁用安全性,您可能会面临漏洞利用的风险。据Secuna提供的几项安全测试已经注意到,小公司,懒惰的开发人员应用程序以及公然无视安全性的应用程序都是关注的。

这意味着您的申请可能在某些时候成为受害者。

我将采取的方法是在UAC内进行测试。确保存在执行任务的适当权限,这样就不会经常使用提升权限运行。一个例子可能是:

class Elevated_Rights
{
    // Token Bool:
    private bool _level = false;

    #region Constructor:
    protected Elevated_Rights()
    {
           // Invoke Method On Creation:
           Elevate();
     }
     #endregion
     public void Elevate()
     {
           // Get Identity:
           WindowsIdentity user = WindowsIdentity.GetCurrent();

           // Set Principal
           WindowsPrincipal role = new WindowsPrincipal(user);

           #region Test Operating System for UAC:
           if (Environment.OSVersion.Platform != PlatformID.Win32NT ||            Environment.OSVersion.Version.Major < 6)
            {
                 // False:
                 _level = false;
             }
             #endregion
             else
             {
                    #region Test Identity Not Null:
                    if (user == null)
                    {
                        // False:
                        _level = false;
                    }
                    #endregion
                    else
                    {
                        #region Ensure Security Role:
                        if (!(role.IsInRole(WindowsBuiltInRole.Administrator)))
                        {
                            // False:
                            _level = false;
                        }
                        else
                        {
                            // True:
                            _level = true;
                        }
                        #endregion
             } 
      }
} 

沿着这些方向的某些内容将允许您针对UAC进行测试,然后执行任务。我不太清楚你为什么要禁用UAC,但那将是我的方法。

希望这有帮助。

答案 2 :(得分:0)

如果您希望绕过通过以标准用户身份运行获得的保护,那么更好的解决方案是更改文件夹和注册表项的权限,以便允许所有用户修改应用程序的文件夹。

GrantAllUsersFullControlToFileOrFolder("C:\Program Files\Grobtastic");

使用伪代码实现:

void  GrantAllUsersFullControlToFileOrFolder(String path)
{
    PACL oldDACL;
    PACL newDACL;    
    PSECURITY_DESCRIPTOR sd;

    //Get the current DALC (Discretionary Access Control List) and Security Descriptor
    GetNamedSecurityInfo(path, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, 
          nil, nil, ref oldDACL, nil, ref sd);

    //Create an SID for the "Users" group
    PSID usersSid = StringToSid("S-1-5-32-545");

    // Initialize an EXPLICIT_ACCESS structure for the new Access Control Entry (ACE)
    EXPLICIT_ACCESS ea;
    ZeroMemory(@ea, SizeOf(EXPLICIT_ACCESS));
    ea.grfAccessPermissions  = GENERIC_ALL;
    ea.grfAccessMode         = GRANT_ACCESS;
    ea.grfInheritance        = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
    ea.Trustee.TrusteeForm   = TRUSTEE_IS_SID;
    ea.Trustee.TrusteeType   = TRUSTEE_IS_GROUP;
    ea.Trustee.ptstrName     = PChar(usersSID);

    // Create a new ACL that merges the new ACE into the existing ACL.
    // SetEntriesInAcl takes care of adding the ACE in the correct order in the list
    SetEntriesInAcl(1, @ea, oldDACL, ref newDACL); //use LocalFree to free returned newDACL

    //Attach the new ACL as the object's new DACL
    SetNamedSecurityInfo(path, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
          nil, nil, newDACL, nil);

    LocalFree(HLOCAL(sd));
    LocalFree(HLOCAL(newDACL));
    FreeSid(usersSID);
}

即使禁用UAC也是如此(即用户是标准用户,并且没有方便他们提升)。它也适用于Windows XP,它没有UAC便利功能,您必须快速用户切换以管理员身份运行。

然后,您显示可执行文件以运行 asInvoker ,因为您不需要管理权限。

问问自己:

  

我在Windows XP上做了什么?   在禁用UAC的Windows 7上我会做什么?

如果他们是标准用户,您的程序是否已经过时?