我正在从我的IIS应用程序中启动一个小型控制台应用程序。代码是从应用程序池中开始的,使用如下代码:
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应用程序池),我们就不能运行上面的代码,那么为什么它过去有时会运行,而不是每次都失败?
有没有人知道为什么这会有所不同?在此上下文中,无接口支持是什么意思?
更新:
我已经接受了人们所说的一切,并自己做了更多的研究。因此,总而言之,如果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;
}
如果UseShellExecute = false,那么它将调用kernel32.dll中的CreateProcess来启动进程。
我想知道上面的代码ShellExecuteOnSTAThread是不是创建了一个新线程,有没有问题?应用程序池是否会达到线程的某些限制,从而间接导致Win32Exception?
发布于 2012-04-20 07:57:15
当某些COM对象未注册时,可能会发生此错误,尽管这对我来说有点神秘,为什么它是间歇性的。
不过,公平地说,从IIS内部派生本地可执行文件是一件非常罕见的事情,它实际上可能会导致安全问题,或者至少在命令由于某种原因失败并且没有将控制权交还给系统的情况下,会导致IIS出现问题。
实际上,这样做的最佳实践是记录您需要在注册表、数据库或某种设置文件中发生的操作,并让您的本地应用程序作为计划任务或windows服务运行。
作为参考,UseShellExec声明内核是否应该直接启动exe,或者是否应该要求资源管理器启动文件。
当没有人登录时,您可能会遇到此问题,因此不一定需要加载shell来启动exe。
但是,最终,您当前尝试做的事情在生产环境中是一件坏事-您无法保证IIS在尝试启动此exe时的状态,因此,IIS不是Shell。
https://stackoverflow.com/questions/10238384
复制相似问题