草庐IT

c# - "Console", "cmd.exe", "shell"之间的区别?

coder 2023-11-10 原文

我不太确定控制台(在“Windows控制台应用程序”中),cmd.exe, shell 之间的区别。

  • 我知道cmd.exe是运行时的独立进程,cmd.exe == shell吗?那么shell只是一个过程吗?
  • 是控制台== cmd.exe吗?
  • MSDN说ProcessStartInfo.UseShellExecute == True意味着在启动进程时使用 shell 程序,是否意味着该进程的启动与我运行cmd.exe并从该命令提示符运行程序的方式相同?这样做有什么意义?以这种方式启动的过程是否具有自己的控制台?

  • 提前致谢。

    最佳答案

    - MSDN says ProcessStartInfo.UseShellExecute==True means use the shell when starting the process, does it mean that the process is started just the same as i run a cmd.exe and run the program from that command prompt? What's the point of doing this? Does the process started this way has its own console?


    实际上它是这样的:
  • 如果UseShellExecute为false,则将使用CreateProcess API启动应用程序;通过此API,您可以指定许多启动选项,其中可以重定向stdin/stdout/stderr,但只能启动可执行文件。如果您尝试使用CreateProcess启动文件(例如Word文档),它将失败,因为Word文档不是可执行文件。
  • 如果UseShellExecute为true,则将使用ShellExecuteEx API启动该过程;双击文件夹中的文件时,此功能与Windows资源管理器(至少在Microsoft术语中为“ shell ”)使用的功能相同;它的主要优点是它“知道”如何启动文档(使用关联的程序打开它们),可以识别Shell文件夹,因为它使用了大量的Shell工具。但是它有一些主要的缺点:与裸露的CreateProcess相比,它是重量级的(因为它必须执行很多额外的工作),如果文件关联/shell扩展/...有问题,它甚至无法打开可执行文件。无法重定向stdin/stdout/stderr。从理论上说,这不是不可能的:毕竟,所有ShellExecuteEx在内部都调用CreateProcess;问题在于它没有公开此功能。

  • 因此,创建流程的两种方法实际上是完全不同的。 Process类在展平它们方面做得很出色,但是ShellExecuteEx函数绝对无法复制的功能是IO流重定向,因为ShellExecuteEx函数无法使用它,并且只能在通过CreateProcess的进程启动时启用它。

    已启动程序对控制台的使用是另一个问题。控制台是在CreateProcess内部分配/重用的(实际上是IIRC与Windows PE加载器有关,该Windows PE加载器检查PE header 中所需的子系统);控制台创建/重用的规则指定为here

    如果启动的应用程序是GUI应用程序,则根本不会创建任何控制台。另一方面,如果启动了控制台应用程序,则除非它在CreateProcess调用CREATE_NEW_CONSOLE标志中指定,否则它将重用其父进程的控制台。缺省情况是不指定此标志,但是我不确定ShellExecuteEx对控制台应用程序有什么作用,并且我手边没有Windows框可以检查。我会将其作为练习留给读者。 :P

    其他答案

    Hi, Matteo, another question. If i create a new process as a detached process which don't have a console attached. Where is the process's stdout now? Where does's the process's output go? Is the process's stdout differnt from console's ouput?


    我不清楚您的意思。当您使用CreateProcess/ShellExecuteEx启动新进程时,将根据需要分配控制台,即,如果exe是控制台可执行文件(如PE header 中所指定),则Windows将为其提供一个控制台(这取决于新控制台还是父控制台)。根据我在上面指定的规则);如果exe是GUI应用程序,则不会为其分配控制台。

    IIRC,对于GUI应用程序stdout/stdin/stderr只是位存储桶,也就是说,它们指向的是无用的东西,并且所有给它们的IO都将被丢弃;顺便说一句,nothing stops是一个GUI应用程序,它分配了一个控制台并将其自己的std *流重定向到该控制台。

    请记住,控制台,Windows std流和CRT std流是三个独立的部分。控制台只是一个接口(interface),对于控制台应用程序,默认情况下可以方便地将其绑定(bind)到Windows std流。

    Windows std流是在CreateProcess中指定stdin/stdout/stderr重定向时重定向的流。您可以使用GetStdHandle函数获取它们的句柄,并使用SetStdHandle重定向它们。

    最后,CRT stdin/stdout/stderr是由C运行时库构建的另一个抽象。它们默认情况下绑定(bind)到Windows std流。

    所有这些通常都可以无缝地正常工作,您甚至不必理会Windows std流和CRT流之间的差异。但是,当您开始考虑流重定向时,这种区别变得很重要。

    If process's stdout stream is differnt from console's output, And Shell make the binding of these 2 streams for us. Would the ouput of a process be copied from process.stdout to console.output? is that efficient?


    Shell不参与此过程,而是按照CreateProcess中使用的说明(或随后使用其他API在新过程内部进行修改)执行工作的内核。对于您的性能问题,采用这样的分层结构是唯一的方法。而且,复制部分(如果真的是复制的话,我怀疑整个过程只是传递指针的问题)是该过程中最快的部分,真正的瓶颈是控制台窗口的绘制/滚动等。实际上,如果您要运行控制台应用程序以使其全速生成数据,则通常会将其标准输出重定向到文件或通过管道。

    Many many thanks. Matteo Italia. You are a good problem sovler. :D


    谢谢你。 :)

    关于c# - "Console", "cmd.exe", "shell"之间的区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2339848/

    有关c# - "Console", "cmd.exe", "shell"之间的区别?的更多相关文章

    1. ruby-on-rails - rails : "missing partial" when calling 'render' in RSpec test - 2

      我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou

    2. ruby-on-rails - 由于 "wkhtmltopdf",PDFKIT 显然无法正常工作 - 2

      我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-

    3. ruby - 检查 "command"的输出应该包含 NilClass 的意外崩溃 - 2

      为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar

    4. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

      exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

    5. ruby-on-rails - Rails 应用程序之间的通信 - 2

      我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此

    6. ruby - 触发器 ruby​​ 中 3 点范围运算符和 2 点范围运算符的区别 - 2

      请帮助我理解范围运算符...和..之间的区别,作为Ruby中使用的“触发器”。这是PragmaticProgrammersguidetoRuby中的一个示例:a=(11..20).collect{|i|(i%4==0)..(i%3==0)?i:nil}返回:[nil,12,nil,nil,nil,16,17,18,nil,20]还有:a=(11..20).collect{|i|(i%4==0)...(i%3==0)?i:nil}返回:[nil,12,13,14,15,16,17,18,nil,20] 最佳答案 触发器(又名f/f)是

    7. ruby-on-rails - 如何在 ruby​​ 交互式 shell 中有多行? - 2

      这可能是个愚蠢的问题。但是,我是一个新手......你怎么能在交互式ruby​​shell中有多行代码?好像你只能有一条长线。按回车键运行代码。无论如何我可以在不运行代码的情况下跳到下一行吗?再次抱歉,如果这是一个愚蠢的问题。谢谢。 最佳答案 这是一个例子:2.1.2:053>a=1=>12.1.2:054>b=2=>22.1.2:055>a+b=>32.1.2:056>ifa>b#Thecode‘if..."startsthedefinitionoftheconditionalstatement.2.1.2:057?>puts"f

    8. ruby-on-rails - 迷你测试错误 : "NameError: uninitialized constant" - 2

      我遵循MichaelHartl的“RubyonRails教程:学习Web开发”,并创建了检查用户名和电子邮件长度有效性的测试(名称最多50个字符,电子邮件最多255个字符)。test/helpers/application_helper_test.rb的内容是:require'test_helper'classApplicationHelperTest在运行bundleexecraketest时,所有测试都通过了,但我看到以下消息在最后被标记为错误:ERROR["test_full_title_helper",ApplicationHelperTest,1.820016791]test

    9. ruby-on-rails - 相关表上的范围为 "WHERE ... LIKE" - 2

      我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que

    10. 使用 ACL 调用 upload_file 时出现 Ruby S3 "Access Denied"错误 - 2

      我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file

    随机推荐