如何取消提升子进程的权限

Dav*_*vy8 30 c# uac process elevation

我知道如何使用以下流程从进程启动具有管理员权限的进程:

proc.StartInfo.UseShellExecute = true;
proc.StartInfo.Verb = "runas";
Run Code Online (Sandbox Code Playgroud)

其中proc是System.Diagnostics.Process.但是,如何做相反的事情呢?

如果您所处的进程已经提升,那么如何在没有管理员权限的情况下启动新进程?更准确地说,我们需要使用与Windows资源管理器相同的权限级别启动新进程,因此如果禁用UAC则无需更改,但如果启用了UAC,但我们的进程正在升级,则需要执行某项操作因为我们正在创建一个虚拟驱动器,如果它是使用提升的权限创建的,并且Windows资源管理器运行速度不高,则不会显示.

随意将标题更改为更好的标题,我无法想出一个好的描述.

mr.*_*123 18

您的解决方案是使用EXPLORER.exe进程.

我们的想法是使用Windows的文件浏览器进程explorer.exe(信息)以UN-ELEVATED模式运行该进程.让我们说我们想要启动的过程正在进行中$TEMP\MyUnElevatedProcess.exe.

所以,对于NSIS代码,我只会写:(但可以用任何语言运行)

 Exec '"$WINDIR\explorer.exe" "$TEMP\MyUnElevatedProcess.exe"'
Run Code Online (Sandbox Code Playgroud)

示例代码(使用NSIS安装程序)

Exec '"$WINDIR\explorer.exe" "$TEMP\MyUnElevatedProcess.exe"'
Run Code Online (Sandbox Code Playgroud)

***代码取自http://mdb-blog.blogspot.com/2013/01/nsis-lunch-program-as-user-from-uac.html

  • 在链接页面上,[来自Microsoft员工(?)的评论是](http://mdb-blog.blogspot.com/2013/01/nsis-lunch-program-as-user-from-uac.html? showComment = 1388694317801#c939517856791332836):"不幸的是,Windows Shell团队回复说"Explorer.exe AppName.exe"的当前行为是一个错误,可能在Windows的未来更新/版本中不起作用.应用程序不应该依赖它". (10认同)
  • 我正在尝试使用此解决方案,但应用程序在Windir文件夹而不是Temp文件夹下运行.对此有什么解决方案?(即文件相对于windir文件夹) (2认同)
  • 要将其用于现代 UI 安装程序中完成页面上的复选框,请使用两行。第一行:`!define MUI_FINISHPAGE_RUN "$WINDIR\explorer.exe"`,第二行:`!define MUI_FINISHPAGE_RUN_PARAMETERS "$TEMP\MyUnElevatedProcess.exe"`。 (2认同)

Dav*_*vy8 8

我们最终使用了此Code Project文章中的示例:高度提升可能对您的应用程序有害:如何在安装结束时启动非提升的进程

它似乎工作到目前为止,我收集它注入RunDll32.exe,我的C++/Win32相当弱,所以我没有看太多的实际实现,只是它的使用.确认它在Vista和Win7中都适用于x86和x64(至少对于我们来说,x86和x64需要不同的dll,在安装时检查并使用正确的dll).


Pau*_*aul 8

Raymond Chen addressed this in his blog:

How can I launch an unelevated process from my elevated process and vice versa?

Searching in GitHub for a C# version of this code, I found the following implementation in Microsoft's Node.js tools for Visual Studio repository: SystemUtilities.cs (the ExecuteProcessUnElevated function).

Just in case the file disappears, here's the file's contents:

// Copyright (c) Microsoft.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.

using System;
using System.Runtime.InteropServices;

namespace Microsoft.NodejsTools.SharedProject
{
    /// <summary>
    /// Utility for accessing window IShell* interfaces in order to use them to launch a process unelevated
    /// </summary>
    internal class SystemUtility
    {
        /// <summary>
        /// We are elevated and should launch the process unelevated. We can't create the
        /// process directly without it becoming elevated. So to workaround this, we have
        /// explorer do the process creation (explorer is typically running unelevated).
        /// </summary>
        internal static void ExecuteProcessUnElevated(string process, string args, string currentDirectory = "")
        {
            var shellWindows = (IShellWindows)new CShellWindows();

            // Get the desktop window
            object loc = CSIDL_Desktop;
            object unused = new object();
            int hwnd;
            var serviceProvider = (IServiceProvider)shellWindows.FindWindowSW(ref loc, ref unused, SWC_DESKTOP, out hwnd, SWFO_NEEDDISPATCH);

            // Get the shell browser
            var serviceGuid = SID_STopLevelBrowser;
            var interfaceGuid = typeof(IShellBrowser).GUID;
            var shellBrowser = (IShellBrowser)serviceProvider.QueryService(ref serviceGuid, ref interfaceGuid);

            // Get the shell dispatch
            var dispatch = typeof(IDispatch).GUID;
            var folderView = (IShellFolderViewDual)shellBrowser.QueryActiveShellView().GetItemObject(SVGIO_BACKGROUND, ref dispatch);
            var shellDispatch = (IShellDispatch2)folderView.Application;

            // Use the dispatch (which is unelevated) to launch the process for us
            shellDispatch.ShellExecute(process, args, currentDirectory, string.Empty, SW_SHOWNORMAL);
        }

        /// <summary>
        /// Interop definitions
        /// </summary>
        private const int CSIDL_Desktop = 0;
        private const int SWC_DESKTOP = 8;
        private const int SWFO_NEEDDISPATCH = 1;
        private const int SW_SHOWNORMAL = 1;
        private const int SVGIO_BACKGROUND = 0;
        private readonly static Guid SID_STopLevelBrowser = new Guid("4C96BE40-915C-11CF-99D3-00AA004AE837");

        [ComImport]
        [Guid("9BA05972-F6A8-11CF-A442-00A0C90A8F39")]
        [ClassInterfaceAttribute(ClassInterfaceType.None)]
        private class CShellWindows
        {
        }

        [ComImport]
        [Guid("85CB6900-4D95-11CF-960C-0080C7F4EE85")]
        [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
        private interface IShellWindows
        {
            [return: MarshalAs(UnmanagedType.IDispatch)]
            object FindWindowSW([MarshalAs(UnmanagedType.Struct)] ref object pvarloc, [MarshalAs(UnmanagedType.Struct)] ref object pvarlocRoot, int swClass, out int pHWND, int swfwOptions);
        }

        [ComImport]
        [Guid("6d5140c1-7436-11ce-8034-00aa006009fa")]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        private interface IServiceProvider
        {
            [return: MarshalAs(UnmanagedType.Interface)]
            object QueryService(ref Guid guidService, ref Guid riid);
        }

        [ComImport]
        [Guid("000214E2-0000-0000-C000-000000000046")]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        private interface IShellBrowser
        {
            void VTableGap01(); // GetWindow
            void VTableGap02(); // ContextSensitiveHelp
            void VTableGap03(); // InsertMenusSB
            void VTableGap04(); // SetMenuSB
            void VTableGap05(); // RemoveMenusSB
            void VTableGap06(); // SetStatusTextSB
            void VTableGap07(); // EnableModelessSB
            void VTableGap08(); // TranslateAcceleratorSB
            void VTableGap09(); // BrowseObject
            void VTableGap10(); // GetViewStateStream
            void VTableGap11(); // GetControlWindow
            void VTableGap12(); // SendControlMsg
            IShellView QueryActiveShellView();
        }

        [ComImport]
        [Guid("000214E3-0000-0000-C000-000000000046")]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        private interface IShellView
        {
            void VTableGap01(); // GetWindow
            void VTableGap02(); // ContextSensitiveHelp
            void VTableGap03(); // TranslateAcceleratorA
            void VTableGap04(); // EnableModeless
            void VTableGap05(); // UIActivate
            void VTableGap06(); // Refresh
            void VTableGap07(); // CreateViewWindow
            void VTableGap08(); // DestroyViewWindow
            void VTableGap09(); // GetCurrentInfo
            void VTableGap10(); // AddPropertySheetPages
            void VTableGap11(); // SaveViewState
            void VTableGap12(); // SelectItem

            [return: MarshalAs(UnmanagedType.Interface)]
            object GetItemObject(UInt32 aspectOfView, ref Guid riid);
        }

        [ComImport]
        [Guid("00020400-0000-0000-C000-000000000046")]
        [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
        private interface IDispatch
        {
        }

        [ComImport]
        [Guid("E7A1AF80-4D96-11CF-960C-0080C7F4EE85")]
        [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
        private interface IShellFolderViewDual
        {
            object Application { [return: MarshalAs(UnmanagedType.IDispatch)] get; }
        }

        [ComImport]
        [Guid("A4C6892C-3BA9-11D2-9DEA-00C04FB16162")]
        [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
        public interface IShellDispatch2
        {
            void ShellExecute([MarshalAs(UnmanagedType.BStr)] string File, [MarshalAs(UnmanagedType.Struct)] object vArgs, [MarshalAs(UnmanagedType.Struct)] object vDir, [MarshalAs(UnmanagedType.Struct)] object vOperation, [MarshalAs(UnmanagedType.Struct)] object vShow);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • Raymond 还发布了一篇后续文章:[How can I launch an unlevated process from mylevated process, redux](https://devblogs.microsoft.com/oldnewthing/20190425-00/?p=102443) 利用 `CreateProcess` 而不是`Shell执行` (2认同)