首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何以编程方式关闭或打开“Windows功能”

如何以编程方式关闭或打开“Windows功能”
EN

Stack Overflow用户
提问于 2022-11-26 19:05:49
回答 2查看 73关注 0票数 1

当我试图更新UseShellExecute特性时;当我将UseShellExecute更新为“true”时;“Process对象必须将UseShellExecute属性设置为false,以便重定向IO流。”我犯了个错误。当我将其设置为False时;无法更新。我该怎么做呢?你还有其他建议吗?

代码语言:javascript
复制
 static void InstallIISSetupFeature()
        {
            var featureNames = new List<string>() {

                 "IIS-WebServerRole",
                "IIS-WebServer",
                "IIS-CommonHttpFeatures",
                "IIS-HttpErrors",
                "IIS-HttpRedirect",
                "IIS-ApplicationDevelopment",
                "IIS-Security",
                "IIS-RequestFiltering",
                "IIS-NetFxExtensibility",
                "IIS-NetFxExtensibility45",
                "IIS-HealthAndDiagnostics",
                "IIS-HttpLogging",
                "IIS-LoggingLibraries",
                "IIS-RequestMonitor",
                "IIS-HttpTracing",
                "IIS-URLAuthorization",
                "IIS-IPSecurity",
                "IIS-Performance",
                "IIS-HttpCompressionDynamic",
                "IIS-WebServerManagementTools",
                "IIS-ManagementScriptingTools",
                "IIS-IIS6ManagementCompatibility",
                "IIS-Metabase",
                "IIS-HostableWebCore","IIS-StaticContent", 
                "IIS-DefaultDocument",
                "IIS-DirectoryBrowsing",
                "IIS-WebDAV",
                "IIS-WebSockets",
                "IIS-ApplicationInit",
                "IIS-ASPNET",
                "IIS-ASPNET45",
                "IIS-ASP",
                "IIS-CGI",
                "IIS-ISAPIExtensions",
                "IIS-ISAPIFilter",
                "IIS-ServerSideIncludes",
                "IIS-CustomLogging",
                "IIS-BasicAuthentication",
                "IIS-HttpCompressionStatic",
                "IIS-ManagementConsole",
                "IIS-ManagementService",
                "IIS-WMICompatibility",
                "IIS-LegacyScripts",
                "IIS-LegacySnapIn",
                "IIS-FTPServer",
                "IIS-FTPSvc",
                "IIS-FTPExtensibility",
                "IIS-CertProvider",
                "IIS-WindowsAuthentication",
                "IIS-DigestAuthentication",
                "IIS-ClientCertificateMappingAuthentication",
                "IIS-IISCertificateMappingAuthentication",
                "IIS-ODBCLogging",
                "NetFx4-AdvSrvs",
                "NetFx4Extended-ASPNET45",
                "NetFx3",
                "WAS-WindowsActivationService",
                "WCF-HTTP-Activation",
                "WCF-HTTP-Activation45",
                "WCF-MSMQ-Activation45",
                "WCF-NonHTTP-Activation",
                "WCF-Pipe-Activation45",
                "WCF-TCP-Activation45",
                "WCF-TCP-PortSharing45",
                "WCF-Services45",
            };
               ManagementObjectSearcher obj = new ManagementObjectSearcher("select * from Win32_OperatingSystem");
                foreach (ManagementObject wmi in obj.Get())
                {
                    string Name = wmi.GetPropertyValue("Caption").ToString();
                    Name = Regex.Replace(Name.ToString(), "[^A-Za-z0-9 ]", "");
                    if (Name.Contains("Server 2008 R2") || Name.Contains("Windows 7"))
                    {
                        featureNames.Add("IIS-ASPNET");
                        featureNames.Add("IIS-NetFxExtensibility");
                        featureNames.Add("WCF-HTTP-Activation");
                        featureNames.Add("WCF-MSMQ-Activation");
                        featureNames.Add("WCF-Pipe-Activation");
                        featureNames.Add("WCF-TCP-Activation");
                        featureNames.Add("WCF-TCP-Activation");
                    }
                    string Version = (string)wmi["Version"];
                    string Architecture = (string)wmi["OSArchitecture"];
                }         
            foreach (var featureName in featureNames)
            {
                Run(string.Format("dism/online/Enable-Feature:{0}", featureName));
            }
         
        }  
        static void Run(string arguments)
        {
            try
            {
                string systemPath = Path.Combine(Environment.ExpandEnvironmentVariables("%windir%"), "system32");

                var dism = new Process();
                dism.StartInfo.WorkingDirectory = systemPath;
                dism.StartInfo.Arguments = arguments;
                dism.StartInfo.FileName = "dism.exe";
                dism.StartInfo.Verb = "runas";

                dism.StartInfo.UseShellExecute = true;
                dism.StartInfo.RedirectStandardOutput = true;
                dism.Start();
                var result = dism.StandardOutput.ReadToEnd();
                dism.WaitForExit();
            }
            catch (Exception ex)
            {
            }

        }`

我尝试用dism.exe和cmd.exe更新这个特性,当它出现授权错误时,我使用了谓词属性

EN

回答 2

Stack Overflow用户

发布于 2022-11-27 04:01:31

  • 由于.Verb = "RunAs"的使用需要.UseShellExecute = true,而且后者不能与RedirectStandardOutput = true组合,所以不能直接捕获内存中提升的进程的输出。
代码语言:javascript
复制
- It seems that **the system itself, by security-minded design, prevents a non-elevated process from directly capturing an elevated process' output**.
  • (**dism.exe**,解决方案是通过 shell,启动目标可执行文件(在您的例子中是),然后使用shell,的重定向功能(**>**)捕获目标可执行文件的输出(无一例外),如下所示。
代码语言:javascript
复制
string systemPath = Path.Combine(Environment.ExpandEnvironmentVariables("%windir%"), "system32");

// Create a temp. file to capture the elevated process' output in.
string tempOutFile = Path.GetTempFileName();

var dism = new Process();
dism.StartInfo.WorkingDirectory = systemPath;
// Use cmd.exe as the executable, and pass it a command line via /c
dism.StartInfo.FileName = "cmd.exe" ;
// Use a ">" redirection to capture the elevated process' output.
// Use "2> ..." to also capture *stderr* output.
// Append "2>&1" to capture *both* stdout and stderr in the file targeted with ">"
dism.StartInfo.Arguments = 
  String.Format(
    "/c {0} {1} > \"{2}\"", 
    "dism.exe", arguments, tempOutFile
  );
dism.StartInfo.Verb = "RunAs";
dism.StartInfo.UseShellExecute = true;

dism.Start();
dism.WaitForExit();
// Read the temp. file in which the output was captured...
var result = File.ReadAllText(tempOutFile);
// ... and delete it.
File.Delete(tempOutFile);
票数 0
EN

Stack Overflow用户

发布于 2022-11-27 13:32:10

首先,您可以使用WindowsPrincipal::IsInRole()来检查是否正在运行高架。详情请参见微软学习

其次,这可能是使用本机PS比cmdlet方法更容易的情况之一(诚然,仍然不是很好)。

如果脚本应该在客户端和服务器操作系统上运行:使用Get-WmiObjectGet-CimInstance获取您正在运行的内容的引用。ActiveDirectory也有这个信息(在operatingSystem属性中)。

对于服务器,请在Get-WindowsFeature模块中使用ServerManager。对于客户端,可以在DISM模块中使用带有开关Get-WindowsOptionalFeature-Online,如果确实需要支持6.3.xxx以上的OSes,可以从拥有它的机器上复制它,并在 C:\Windows和C:\Windows\System32 32之前添加到$Env:Path

对于任何一个平台,只需传递要配置的特性列表。

如果在(二进制) cmdlet中,您必须调用外部工具,那么它们的优势基本上就消失了。使用托管API访问Windows可能是可能的,但即使这样,基于脚本的方法也能获得更快的结果,特别是因为您只需将一个快速包装器放在dism.exe上即可。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74584885

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档