C# UseShellExecute有什么区别?

C# UseShellExecute有什么区别?,c#,iis-7.5,C#,Iis 7.5,我正在从IIS web应用程序中启动一个小型控制台应用程序。代码是从应用程序池中使用以下代码启动的 Process process = new Process(); ProcessStartInfo processStartInfo = new ProcessStartInfo(); processStartInfo.CreateNoWindow = true; processStartInfo.WindowStyle = ProcessWindowStyle.Hidden; // ..

我正在从IIS web应用程序中启动一个小型控制台应用程序。代码是从应用程序池中使用以下代码启动的

Process process = new Process();
ProcessStartInfo processStartInfo = new ProcessStartInfo();

processStartInfo.CreateNoWindow = true;
processStartInfo.WindowStyle = ProcessWindowStyle.Hidden;

// ..

process.Start();
我过去常常间歇性地出错

Win32Exception exception has occured  Message: No such interface supported
ErrorCode: 80004005  NativeErrorCode: 80004002
我证明了当这种情况发生时,控制台应用程序根本不会启动

我在上面的代码中添加了

processStartInfo.UseShellExecute = false;
问题已经解决了(到目前为止,祈求好运)。我明白,进行此更改并不需要有效的桌面上下文才能运行,但这到底意味着什么。如果这意味着如果没有桌面(适用于与系统用户一起运行的IIS应用程序池),我们就无法运行上述代码,那么为什么过去它有时会运行,而不是每次都失败

有人知道为什么这会带来不同吗?在此上下文中,不支持接口意味着什么

更新:

我接受了人们所说的一切,自己也做了更多的研究。因此,总结一下,如果您使用了shellexecute=true(这是默认值),那么它将调用shell32.dll中的ShellExecuteEX来执行该过程。它将实际执行此操作(使用ILSpy从System.dll复制)

如果您的UseShellExecute=false,那么它将调用kernel32.dll中的CreateProcess来启动进程


我想知道上面的代码ShellExecuteonStatThread正在创建一个新线程这一事实是否有问题?应用程序池是否会在线程方面达到某种限制,从而间接导致Win32异常?

当某些COM对象未注册时,可能会发生此错误,尽管我对其间歇性的原因感到有点神秘

不过,公平地说,从IIS中生成本地可执行文件是一件非常罕见的事情,它实际上可能会导致安全问题,或者至少会在命令因某种原因失败且无法将控制权返还给系统时导致IIS出现问题

实际上,这样做的最佳实践是在注册表、数据库或某种设置文件中记录需要执行的操作,并让本地应用程序作为计划任务或windows服务运行

作为参考,UseShellExec声明内核是否应直接启动exe,或者是否应请求资源管理器启动该文件

当没有人登录时,您可能会遇到此问题,因此不必加载shell来启动exe


但最终,您当前尝试的操作在生产中是一件坏事-您无法保证IIS在尝试启动此exe时的状态,因此,IIS不是Shell。

为了确认安全问题,IIS通常以高权限运行,并且以您尝试的方式启动进程将以相同的权限集启动进程。我觉得这很少是件好事。好的,谢谢。我不担心安全问题,我没有时间解释这方面的全部情况。我同意,你说当没有人登录服务器时,我们可能会遇到问题。听起来不错,但事实似乎并非如此。这一定与“加载shell”导致的其他问题有关。除了安全性之外,服务器上的有效状态仍然是一个问题。如果由于活动超时而导致exe暂停,IIS工作进程重新启动或停止,会发生什么情况?我想知道这个exe打算做什么会有所帮助;即使你只能提供一英里高的视野。当然。它获取一个文档,例如pdf文件(作为字节[]),并生成一个“预览”图像。这意味着PNG图像是第一页的图像。这是在一个单独的进程中完成的,因为它使用的是GhostScript库,它是一个C库,并且不是线程安全的。如果预览过程失败,则不会导致软件中严重问题的数据丢失。这仅仅意味着当用户下次加载页面时,当他们单击列表中的文档时,预览将为空。他们必须点击一个按钮下载并查看他们的附件,然后才能确定哪一个是哪一个。在过去的几个月里,我已经多次看到这种特定的故障模式。没有什么可以解释的,但是使用UseShellExecute=false肯定会解决它。谢谢。你还在哪里见过它?我在哪儿都找不到?抱歉,如果我问了一个你无法回答的问题,但我很好奇你是否能找到。这并不能回答Hans的意思,但这个问题有一些有趣的细节:
public bool ShellExecuteOnSTAThread()
{
    if (Thread.CurrentThread.GetApartmentState() != ApartmentState.STA)
    {
        ThreadStart start = new ThreadStart(this.ShellExecuteFunction);
        Thread thread = new Thread(start);
        thread.SetApartmentState(ApartmentState.STA);
        thread.Start();
        thread.Join();
    }
    else
    {
        this.ShellExecuteFunction();
    }
    return this._succeeded;
}