Question

There is any command line or .NET method that runs a process in the background hiding any window it tries to open?

Already tried:

 var process = new Process()
 {
      StartInfo = new ProcessStartInfo()
      {
          CreateNoWindow = true,
          WindowStyle = ProcessWindowStyle.Hidden,
          FileName = TheRealExecutableFileNameHere
      }
 }
 process.Start();

With no success so far

Was it helpful?

Solution

Check out the Matlab Engine.

There's even an interesting article on CodeProject, if this approach fits your needs.

OTHER TIPS

I reviewed my code and it looks nearly identical to yours:

ProcessStartInfo psi = new ProcessStartInfo(fileName, arguments)
{
   CreateNoWindow = true,
   WindowStyle = ProcessWindowStyle.Hidden,
   UseShellExecute = false,
   RedirectStandardOutput = true                                               
};

Process process = Process.Start(psi);

The only notable difference (other than formatting and which PSI constructor we chose) is my use of UseShellExecute and RedirectStandardOutput as I needed to read the result of the ran process.

I have found the code above consistently runs a hidden process on XP and Vista. I have also found, however, and you may be experiencing the same, that a hidden process may kick off another process which by default isn't hidden. In other words, if you start hidden Process A and Process A, in turn, kicks off Process B, you have no control as to how Process B will be displayed. Windows which you have no control over may be displayed.

I hope this helps a little. Good luck.

Have you tried using the Microsoft DOS start command with the /B switch?

Microsoft DOS start command

For example,

START /B cmd.exe

There is no I do not know a pure .Net way to achieve this.

Then I thought about kernel Job Objects, but found no similar option in UI restrictions.

So, the next (yet unverified) idea is to create than process suspended, create a windows hook then, which will monitor CallWndProc and filter out WM_SHOW messages. (Then, surely, resume the process, wait in a separate thread till it terminates, remove the hook)

You may want to try the BackgroundWorker Class in the .Net Framework if you haven't already. It's for executing long running processes on a separate thread to prevent them from impeding the UI. Give it a look.

I realize this has been answered but you could force a window to hide with unmanaged calls to FindWindow and ShowWindow.

[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

psi = new ProcessStartInfo(); // etc..
some_process = Process.Start(psi);
System.Threading.Thread.Sleep(50); // need give the window a chance to be created
IntPtr hWnd = FindWindow(null, "name of the window");
if (hWnd != IntPtr.Zero) ShowWindow(hWnd, 0); // 0 = SW_HIDE

Rather kludgy.

It depends on whether you want to start the application minimized, but allow it to interact with the user if required, or if you want to prohibit all access with the user regardless of what happens.

If the latter, you could run the process under a different desktop context to the current user.

Different Desktop contexts are used, for example, by the Login dialog and by Vista UAC - anything that happens in one desktop context is independent of others.

Might be a sledgehammer approach to your problem though.

I noticed that if CreateNoWindow = false does absolutely nothing when the Filename is pointing to a Windows executable, if you have access to the source code of the winform app then you might be able to provide a command line argument which controls the default visibility of the form, and do something like this in the Winform App startup code:

static void Main(string[] args)
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Form1 form1 = new Form1();

        form1.Load += new EventHandler((s,o) =>
            {
              //check if the form should be shown based on command line arg
                if (args.Contains("dontShowWindow"))
                {
                    //hide it
                    form1.ShowInTaskbar = false;
                    form1.Visible = form1.ShowInTaskbar = false;
                }
            }
        );
        Application.Run(form1);
    }

In you calling code, you can now specify "dontShowWindow" as a process Argument:

 ProcessStartInfo info = new ProcessStartInfo
        {
            CreateNoWindow = false, 
            WindowStyle = ProcessWindowStyle.Hidden,
            UseShellExecute = false, 
            FileName = @"C:\temp\testWinForm.exe",
            Arguments = "dontShowWindow"
        };
        Process.Start(info);

Hope this helps

One very simply way to achieve this is to create a Service Account and run the executable under the context of the Service Account user via the Windows Task Scheduler.

You could use this CodeProject to setup the scheduled task:

http://www.codeproject.com/KB/cs/tsnewlib.aspx

You could create the service account programatically in the Domain or local machine very easily with C#.

http://www.codeproject.com/KB/system/OSUserMangement.aspx http://support.microsoft.com/kb/306273

Processes running as scheduled tasks in the context of another user do not appear interactively unless that user is logged in; hence the use of a service account.

public Form1()
    {
        InitializeComponent();
        Form1 fm = new Form1();
        fm.ShowInTaskbar = false;
        fm.Visible = fm.ShowInTaskbar = false;
    }

Works great !

I assume you want a process that is not visible to users while running.

You can try the following to see whether this is what you want.

  1. Create a simple console app that keeps running (and launch it to test).
  2. Right click on Project --> Properties --> Application tab --> Output type --> Change it from "Console Application" to Windows Application.
  3. Launch the same app one more time (to see whether this is what you want).
  4. Close the app via Windows Task Manager :)

It seems that the process appears in Task Manager, yet, is not visible in the task bar. Alt+TAB cannot bring this process up.

I just hope that you are not making any malicious app, though :)

I think what you might want to try is to create a new Windows Station. Check out this article that explains a bit about them on msdn.

http://msdn.microsoft.com/en-us/library/ms681928(VS.85).aspx

You could make a Windows' service. Any window a service tries to open just runs in session 0, which means no user can see it. That goes for all windows though, so perhaps that's not what you're looking for.

Below code worked for me: Earlier the process (notepad) used to flash the notepad on desktop screen for printing, but it distract the user , so below code hides the notepad process in background.

                System.Windows.Forms.PrintDialog printDialog = new PrintDialog();
                System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo(Application.StartupPath + "/PrintingDocketFile/PrintCustomerOrder.txt");
                psi.Verb = "PRINT";

                //Process.Start(psi);
                //psi.CreateNoWindow = true;
                psi.UseShellExecute = false;
                //---------------------------------------------------

                psi.CreateNoWindow = false;
                psi.UseShellExecute = true;
                psi.FileName = Application.StartupPath + "/PrintingDocketFile/PrintCustomerOrder.txt";
                psi.WindowStyle = ProcessWindowStyle.Hidden;
                psi.Arguments =  @"%windir%\system32\notepad.exe"; 
                //Process.Start(psi);
                //------------------------------------------------------

                /////////////////////----------------------------------

                printProcess.StartInfo = psi;
                /////psi.CreateNoWindow = true;

                //psi.FileName = "Application.StartupPath" + "/PrintingDocketFile/PrintCustomerOrder.txt";
                //p.StartInfo.FileName = "Notepad.EXE";
                //p.StartInfo.Arguments = "/i /q \"" + installationPackages[i] + "\"";

                printProcess.Start();

                /////////////////////////-------------------------------
                while (!printProcess.HasExited) ;


                if (!printProcess.HasExited)
                {
                    printProcess.Close();
                }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top