What difference does UseShellExecute have?

I am running a small console application from my IIS web application. The code is run from the application pool using this code,

Process process = new Process(); ProcessStartInfo processStartInfo = new ProcessStartInfo(); processStartInfo.CreateNoWindow = true; processStartInfo.WindowStyle = ProcessWindowStyle.Hidden; // .. process.Start(); 

I interrupted the error periodically

 Win32Exception exception has occured Message: No such interface supported ErrorCode: 80004005 NativeErrorCode: 80004002 

I proved that when this happens, the console application will not start at all.

I added the code above this,

 processStartInfo.UseShellExecute = false; 

And the problem is gone (while the fingers are crossed). I understand that making this change does not require a valid desktop to run, but what exactly does this mean. If this means that we cannot run the above code, if there is no desktop (which applies to the IIS application pool running with the system user), then why was it used to run sometimes in the past, and not to fail every time?

Does anyone have any idea why this matters? What does lack of interface support in this context mean?

UPDATE:

I took everything that people said on board and did more research myself. Therefore, to summarize, if you have UseShellExecute = true (which is the default), then it will call ShellExecuteEX in shell32.dll to execute the process. It will actually do it (copied from System.dll using ILSpy)

 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; } 

If you have UseShellExecute = false, it will call CreateProcess in kernel32.dll to start the process.

I was wondering if there is a problem with the ShellExecuteOnSTAThread code above creating a new thread? Can the application pool achieve some thread limit that may indirectly raise Win32Exception?

+6
source share
1 answer

This error can occur when some COM objects are not registered, although for me this is a bit of a mystery why it is intermittent.

In fairness, however, the occurrence of a local executable from IIS is a rather rare thing, and this can actually cause a security problem or at least cause a problem with IIS if the command fails for some reason and does not return control to the system.

In fact, the best practice for something like this is to write down the action that needs to be performed in the registry, database, or some settings file, and run the local application as a scheduled task or Windows service.

For reference, UseShellExec states whether the kernel should run exe directly or should ask Explorer to run the file.

You may have encountered this problem when no one has logged in, so the shell does not have to load to run exe.

Ultimately, however, what you are trying to do now is bad in production - you cannot guarantee the state of IIS when it tries to run this exe and correctly, IIS is not a shell.

+7
source

Source: https://habr.com/ru/post/913667/


All Articles