在Windows中,程序化地选择性禁用UAC针对特定程序

8
有很多关于禁用/绕过/抑制UAC的问题/答案在Stack和其他论坛上。也有一些解决方案。但是从编程角度来看,也许没有。我只能看到一个解决方案通过程序禁用UAC但也许没有真正的编程解决方案。
是否可以有一个程序化的解决方案,使用户每次运行像wamp这样的程序时不必提示,并且他们总是必须点击“是”,因此最好告诉Windows他们的选择始终是“是”。我相信会有这种解决方案。
我发现Windows通过GUI在任务计划程序中提供了这个功能,在这里所以也可能可以通过代码实现。
更新:我准备了一个纯粹的程序化解决方案,它正在工作。请看我的回答。

你为什么要尝试绕过用户账户控制(UAC)? - Jakob Bowyer
@JakobBowyer 因为无论我在哪里部署我的c#,mysql桌面应用程序(需要系统上运行wamp),当wamp启动时用户都会感到烦恼并出现UAC对话框。 - Sami
3
@JakobBowyer,你太过激进了。我认为在个人电脑上运行桌面应用程序不会存在安全风险,但也许你是对的。你可以给我投反对票,可以阻止其他人指导我。这是你的权利。但是,你的措辞和论点并不令人信服,就像表现出一种厌恶的样子。抱歉,但这就是我的感受。 - Sami
在互联网上争论就像和鸽子下棋,你可能会赢,但鸽子仍然会在棋盘上到处走动拉屎,感觉自己是胜利者。 - Jakob Bowyer
2
这个问题得到了-4的评分,而另一个问题https://dev59.com/KnRB5IYBdhLWcg3wQFLu?lq=1则得到了10的评分。两个问题都是关于禁用UAC的;其中一个有真正的答案,而另一个只有意见。这很遗憾。http://stackoverflow.com/faq#etiquette - daniloquio
显示剩余5条评论
3个回答

13

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

步骤

  1. 此链接下载Microsoft.Win32.TaskScheduler.dll => 原始来源 => dllme.com
  2. 制作C#应用程序(Windows或控制台),并添加对上述dll的引用
  3. 将“New Item(应用程序清单文件)”添加到您的项目(此应用程序)中
  4. <requestedExecutionLevel level="asInvoker" uiAccess="false" />更改为<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
  5. 在program.cs文件中编写以下代码

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 dynamic value for 'program_path'
      //even of user choice giving an interface in win-form app

      td.Actions.Add(new ExecAction(program_path, null));
      ts.RootFolder.RegisterTaskDefinition("anyNamefortask", td);          
   }
}

6.现在编译和运行你的应用程序(此应用程序)。


现在你的应用程序(例如WAMP)将在你所需的计划(每次登录Windows时,在我的情况下)不提示任何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


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,但这是我的方法。

希望这能帮到你。


谢谢您的回答,不过它并不依赖于任务计划程序,但是如何在主应用程序中使用这个类还不太清楚! - FLICKER

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上会做什么?

如果他们是标准用户,你的程序是否会崩溃?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接