我从我的IIS Web应用程序中启动一个小型控制台应用程序.代码是使用这样的代码从应用程序池中启动的,
Process process = new Process();
ProcessStartInfo processStartInfo = new ProcessStartInfo();
processStartInfo.CreateNoWindow = true;
processStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
// ..
process.Start();
Run Code Online (Sandbox Code Playgroud)
我曾经间歇性地得到一个错误,
Win32Exception exception has occured Message: No such interface supported
ErrorCode: 80004005 NativeErrorCode: 80004002
Run Code Online (Sandbox Code Playgroud)
我证明了当发生这种情况时,控制台应用程序根本无法启动.
我在上面的代码中添加了
processStartInfo.UseShellExecute = false;
Run Code Online (Sandbox Code Playgroud)
问题已经消失(到目前为止,手指交叉).我知道通过进行此更改它不需要运行有效的桌面上下文,但这究竟是什么意思.如果这意味着如果没有桌面(适用于与系统用户一起运行的IIS应用程序池),我们就无法运行上面的代码,那么为什么以前有时会运行它而不是每次都失败?
有没有人知道为什么这会有所作为?在这种情况下,没有支持接口意味着什么?
更新:
我已经接受了人们所说的一切,并且自己做了更多的研究.总结一下,如果你有UseShellExecute = true(这是默认值),那么它将调用shell32.dll中的ShellExecuteEX来执行该过程.它实际上会这样做(使用ILSpy从System.dll复制),
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;
}
Run Code Online (Sandbox Code Playgroud)
如果您有UseShellExecute = false,那么它将调用kernel32.dll中的CreateProcess来启动该进程.
我想知道上面的代码ShellExecuteOnSTAThread创建一个新线程是否存在问题?应用程序池是否可以在线程上达到某些限制,这可能会间接导致Win32Exception?
当某些COM对象没有注册时会发生此错误,尽管这对我来说有点神秘,为什么它是间歇性的.
但公平地说,从IIS中生成本地可执行文件是一件非常罕见的事情,它实际上可能会导致安全问题,或者至少导致IIS出现问题,如果命令由于某种原因而失败并且不会给予控制权到系统.
实际上,类似这样的事情的最佳实践是记录您需要在注册表,数据库或某种设置文件中发生的操作,并将本地应用程序作为计划任务或Windows服务运行.
作为参考,UseShellExec说明内核是否应该直接启动exe,或者它是否应该要求Explorer启动该文件.
当没有人登录时你可能会遇到这个问题所以没有必要加载shell来启动exe.
但最终,你目前正在尝试做的是生产中的一件坏事 - 你无法保证IIS在尝试启动这个exe时的状态,因此,IIS不是Shell.
| 归档时间: |
|
| 查看次数: |
2752 次 |
| 最近记录: |