For the Code Blocks as shown in your question, the behavior is normal.
Let's have a look at them...
//[...]
procInfo.CreateNoWindow = false; //That's not what you meant
procInfo.UseShellExecute = false;
process.Start(); //Will show up the console window
process.CloseMainWindow(); //Will close the main window (probably also the whole application)
Between process.Start();
and process.CloseMainWindow();
is a short time frame, where the application is visible.
Like described by @BugFinder, it should be enough to edit the CreateNoWindow
Value from false
to true
.
Check if that works.
Your second try is getting you further away:
process.Start();
while (process.MainWindowHandle == IntPtr.Zero)
{
process.Refresh(); //Let's do this as long as there is no window...
}
var handle = process.MainWindowHandle; //This occurs, when there is *already* a window.
ShowWindow(handle, 0) //ShowWindow from user32.dll
The idea of using Shell Functions is basically not bad, but this code is doing the same like the code above (and is also unmanaged).
Let's try a different way and take the C# Sample from PInvoke.Net: (not more managed than ShowWindow()...)
public static void StartupNotepad()
{
const uint NORMAL_PRIORITY_CLASS = 0x0020;
const uint STARTF_USESHOWWINDOW = 0x1; //IMPORTANT for you
bool retValue;
string Application = Environment.GetEnvironmentVariable("windir") + @"\Notepad.exe";
string CommandLine = @" c:\boot.ini"; //Funny
PROCESS_INFORMATION pInfo = new PROCESS_INFORMATION();
STARTUPINFO sInfo = new STARTUPINFO();
sInfo.wShowWindow = 0; //IMPORTANT for you - See http://pinvoke.net/default.aspx/Enums/ShowWindowCommand.html
sInfo.dwFlags = STARTF_USESHOWWINDOW; //IMPORTANT for you
SECURITY_ATTRIBUTES pSec = new SECURITY_ATTRIBUTES();
SECURITY_ATTRIBUTES tSec = new SECURITY_ATTRIBUTES();
pSec.nLength = Marshal.SizeOf(pSec);
tSec.nLength = Marshal.SizeOf(tSec);
retValue = CreateProcess(Application,CommandLine,
ref pSec,ref tSec,false,NORMAL_PRIORITY_CLASS,
IntPtr.Zero,null,ref sInfo,out pInfo);
Console.WriteLine("Process ID (PID): " + pInfo.dwProcessId);
Console.WriteLine("Process Handle : " + pInfo.hProcess);
}
This example demonstrates the use of CreateProcess (MSDN Link at the bottom) in a very static manner.
I suggest you to write a more dynamic function and play around with it. The PROCESS_INFORMATION
structure allows you to manipulate the newly created process later in your application. If your problem still persists using the CreateProcess() Call, it's to check whether the started application does some tricky stuff on itself. And last but not least whether the problem occurs not only on your computer...
Here are some more references:
EDIT:
Probably a workaround, but if your 3rd party App is designed to show a Window and tries to ignore your requests, STARTUPINFO
also has dwX
and dwY
, which sets the Window's position if dwFlags
specifies STARTF_USEPOSITION
. Same for dwXSize
and dwYSize
.
If all else fails, you could give it a try and pass positions and sizes, which make the proces appear invisible. Cheers.