AppWinStyle does not work with Process.start - c#

I am trying to use AppWinStyle with Process.start but it does not work as i expected.
The below code will open file 1.txt and it will be minimized with no focus to it.
Shell("notepad D:\1.txt", AppWinStyle.MinimizedNoFocus)
But below code will open 1.txt with focus on it.It will not be minimized.
Process.Start("D:\1.txt", AppWinStyle.MinimizedNoFocus)
Why does it happen? Please help me to solve this

A boilerplate example:
using System;
using System.Diagnostics;
class Program {
static void Main(string[] args) {
var psi = new ProcessStartInfo("notepad.exe");
//psi.WindowStyle = ProcessWindowStyle.Hidden;
Process.Start(psi);
}
}
Run it once to make sure it works, then remove the comment and observe the outcome. You'll briefly see the Notepad window flash but it immediately terminates again. Might depend on the Windows version, I described what happened for Windows 8.1
A GUI app gets the ProcessWindowStyle you specify through its WinMain() entry point, the nCmdShow argument passes the value you specified. What the app actually does with that value is entirely up to the app. Boilerplate implementation is to pass it to the ShowWindow() call, the one that makes its main window visible.
Using ProcessWindowStyle.Hidden is in general very problematic and a properly written GUI app will ignore it, like Notepad did. Because what you asked it to do is to start the program but not display any window, not even a taskbar button. In other words, you asked it to turn into a zombie, a process that runs without any way for the user to get to it. The only possible thing the user could do is run Task Manager and kill the process.
So sure, definitely expect this to not work. It shouldn't.

No such overload with Process.Start:
Process.Start("D:\1.txt", AppWinStyle.MinimizedNoFocus)
See all overloads here: Process.Start Method
In order to achieve it using the Process.Start, use the ProcessStartInfo.WindowStyle, setting it to ProcessWindowStyle.Minimized.
By the way, the AppWinStyle enumerator is specific for the Shell function:
Indicates the window style to use for the invoked program when calling
the Shell function.

Related

How can I start multiple vscode from c# and keep track of when they terminate?

I want to start vscode as an external editor in a program that Im writing in c#. I use the Process class. I can do that but I also like to be notified when a particular instance is closed. Now I run into problems. If I only start one instance of vscode, the process terminates when that window is closed which is what I want. However, if I start a second vscode that process will terminate immediately. This becomes an issue when the user already has an instance open and use my program.
Anyone with an idea on how this can be solved?
Two parts are necessary to answer your question.
The first is the pure C# one: How to start a process and wait for it to end
Everything you need for this is in the Process class.
To start a process: Process.Start
Once started, to wait for exit, you have a few options:
Process.WaitForExit
Process.WaitForExitAsync
Process.Exited (this is an event handler that you can subscribe to)
Then there is another part needed to answer the question: How VS Code behaves when started from the command line and its options
By default, VS Code will return immediately after starting (so as not to block a shell if it was started from CLI). So, you'll need to pass a few parameters.
Based on the previous link, those would be:
-w or --wait => Wait for the file to be closed before returning.
-n or --new-window => Opens a new session of VS Code instead of restoring the previous session. (this is default behaviour, but you might want to specify it anyways in case this ever changes [or the user changes this])

C# - Open an app as second process in the Task Manager

I want to open an different app and to appears like it's an process of the app itself and don't appear as a different one in the task manager processes list.
Something like:
Can Process.Start() do it?
Solved!
Well it seems that always when an app starts a process, the main app it'll be its parent. I didn't knew that :)
Using Process.Start with a ProcessStartInfo and ensuring UseShellExecute is false should probably do it. However, the process being launched may do something that breaks this behavior. It could, for example, just be a stub launcher that starts another process then quits.

How can I force another program to not show any dialog when I run it with Process.Start()

I'm not sure if it's possible anyway. But my question is, can I force a program to not show any dialogs when I run it with process.Start()?
I have a program where I call another program in a foreach loop. It is a fileconverter. Unfortunately some files don't exist any more or the user gives the wrong filepath. If that happens, the converter shows an error with a messagebox. But i don't want to see that box, because if the user wants to convert 10000 files, but has the wrong path in settings, 10000 messagboxes appear and force the system to crash.
I have tried to kill these processes but they have the same name in the processes as the converter itself. I can handle it with a Thread.Sleep but then my mouse is flickering all the time while my thread is running. This is just a little bit better than the messageboxes.
If there is a way, I would be very thankful if you could tell me :)
Regards Schlinger
Most probably it's not possible. There is no built-in way to prevent any executable to show any dialog box.
Depending on the executable you're running, with some luck it might expose a command line version that accepts some quiet or noui parameter, but it's unlikely.
Or you could try programmatically closing those dialog boxes, as suggested.

C# - Use a console in the background without showing it

I've been thinking of giving the in Windows implemented cmd a fresh look and make a WinForm out of it(C# .net4.0 or later or latest mono# distribution).
Now, what I plan on doing is:
only showing the form, no console visible(even in the task bar)
telling the cmd what to do by virtually typing into it
catching the consoles output and using the form to make the user interact
I thought of some kind of "return" thing, like a dll would do, but I have not used consoles and forms together in a single project, so there's my question:
How do I not show a console window but write commands into it's line and receive the output with a WinForms application?
Thanks in advance.
--EDIT
I should maybe add that my main problem is typing catching the consoles output and also typing into it while it's not visible and thus not focusable.
You may well run into difficulties other than simply suppressing the appearance of a console window. But as far as that particular requirement goes, it's not hard.
You'll use the System.Diagnostics.Process class to start the process. Before starting the process, you'll need to see ProcessStartInfo.CreateNoWindow property to true. Note that you also need to set ProcessStartInfo.UseShellExecute to false, otherwise the CreateNoWindow property is ignored.
As for the broader problem: it seems likely that you'll need to start the console process using "cmd.exe /k" to instantiate a new command-line interpreter process without it exiting before you're done with it. Then you'll also need to use the redirection features in the Process class to read from stdout and stderr, and to write to stdin.

How to create a Process that outlives its parent

I'm trying to launch an external updater application for a platform that I've developed. The reason I'd like to launch this updater is because my configuration utility which handles updates and license configuration for the platform has shared dependencies with other assemblies in the folder where the update will be deployed. So, while I can rename the configuration utility and overwrite it when deploying the update, I can't rename or overwrite the DLLs it depends on. Hence, the external updater application.
I'm handling all of the update gathering logic in the configuration utility, then attempting to launch the updater to handle the actual file copy/overwrite operations. Obviously, because of the file in use issues, I need the configuration utility to exit right after the updater begins.
The problem I'm having is that I'm using the standard Process.Start method of launching the updater, and as soon as the configuration utility exits, the updater process gets killed too.
Is there any way that I can create a Process that outlives its parent, or launch an external application that can run beyond the program that launched it?
EDIT:
Apparently, in my updater application, I miscalculated the number of command line arguments which are passed to it. Because of this, the updater would exit immediately. I misinterpreted this to mean that the launcher application was killing the "child" process, when in fact, it wasn't.
The answers below are correct.
It seems that the problem you are seeing has a different reason because the Process class will not kill any processes started using Process.Start when your application exits.
See this simple sample program, the calculator will stay open:
using System.Diagnostics;
class Program
{
static void Main(string[] args)
{
Process.Start(#"C:\windows\system32\calc.exe");
}
}
There's no reason why a process started with Process.Start should automatically die when the launcher exits. My guess is that you're doing something odd in the updater.
I've written an updater doing exactly this kind of thing before, and it's been fine.
For example:
Launcher.cs:
using System;
using System.Diagnostics;
class Launcher
{
static void Main()
{
Console.WriteLine("Launching launchee");
Process.Start("Launchee.exe");
Console.WriteLine("Launched. Exiting");
}
}
Launchee.cs:
using System;
using System.Threading;
class Launchee
{
static void Main()
{
Console.WriteLine(" I've been launched!");
Thread.Sleep(5000);
Console.WriteLine(" Exiting...");
}
}
Compile both of them, separately, and run Launcher.exe. The "launchee" process definitely lasts longer than the launcher.
Just a thought from my foggy memory, but I seem to remember having a discussion a while back that when the Process.Start method is called from Form that the spawned process has some sort of dependency (not sure what, why or how, memory is a bit foggy).
To deal with it, a flag was set that was actually called from the Main() method of the application after the main form/app exited and that if the process was launched from the Main() method, eveything worked out just fine.
Just a thought, like I said, this is purely from memory, but some of the examples posted here all being called from the Main() method of a console app seemed to jog something.
Hope all works out well for you.

Categories

Resources