Hiding the Process Monitor application window - c#

I am creating a scheduled task to run process monitor at its highest privileges. I have a windows service that executes the scheduled task on start. Thus on start of my service, process monitor.exe will be executed shown in a window. But I don't want to see the window. I just want the process monitor.exe to run in the background without displaying any windows.
In AutoIT, there is a command: Run (Procmon.exe,"",#SW_Hide) #SW_Hide = Hidden Window
I tried this:
foreach (Process pr in Process.GetProcesses())
{
if(pr.ProcessName == "procmon")
{
hWnd = pr.MainWindowHandle.ToInt32();
ShowWindow(hWnd, SW_HIDE);
}
}

It's better to tell the process to show no window in the first place, instead of hiding it afterwards.
When running a program from .net you usually already have a ProcessStartInfo. Then just set its WindowStyle property to ProcessWindowStyle.Hidden and that should take care of it.
I haven't tried this myself, but that's the way you usually do it when calling the WinApi functions directly.
http://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.windowstyle.aspx
http://msdn.microsoft.com/en-us/library/system.diagnostics.processwindowstyle.aspx

You need to get Window Handle of Process Monitor first and then you need to call ShowWindow with SW_HIDE to hide it.
You can use FindWindow to get the Window Handle of the ProcMon window.
Edit:
After looking at your code, I tried at my end and it works with the following code:
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
public static void HideWindow()
{
int SW_HIDE = 0;
foreach (Process pr in Process.GetProcesses())
{
if (pr.ProcessName.Contains("Procmon"))
{
//Int32 hWnd = pr.MainWindowHandle.ToInt32();
ShowWindow(pr.MainWindowHandle, SW_HIDE);
}
}
}
static void Main(string[] args)
{
HideWindow();
}
Most likely, the problem with your code is that you are trying to find an exact match of the process name which isn't there.

Procmon has built-in functionality to automatically log at startup, if that's what you're trying to accomplish.

Related

FindWindow in C#(via pinvoke) finds desired window handle, but not in the desired conditions. How do I fix it?

I'm trying to get certain window handle. I was searching for solution for many hours and I understand that my question sounds similar to this one:
FindWindow() doesn't find my window [C++]
But that discussion didn't help.
I was trying to use both FindWindow() and FindWindowEx() like these two:
IntPtr SysPropWndHandler = FindWindow("#32770", "Параметри продуктивності");
IntPtr SysPropWndHandler = FindWindowEx(IntPtr.Zero, IntPtr.Zero, "#32770", "Параметри продуктивності");
Weird part is that when I run the program, it starts new process for certain system settings program from system32 folder and it can't find it's handle during same launch time (if that's correct to say so). I tried to pause it to give it time to create window and assign handle, but that doesn't help.
But! If that system program is launched first and then I run my program - it finds it's handle right away.
Two ways for that "external launch":
I run system program manually before launching my program
I run my program, which launches that system program, then I close my program, system program doesn't close then. After that I run my program again.
But what I'm actually trying to make my program do is this:
launch system program (some productivity settings)
hide window
change some settings via WinApi (kind of checkbox clicking emulation)
click ok
close it
Since my code works, at least in some conditions, looks like it has nothing to do with encoding, which was mansioned in that similar question. Otherwise it wouldn't work at all.
I was trying to launch it hidden, but it didn't work. I tried the same code for notepad for debugging it - it works.
string prog_path = #"C:\Windows\System32\SystemPropertiesPerformance.exe";
Process process = new Process();
process.StartInfo.FileName = prog_path;
process.StartInfo.CreateNoWindow = true; // no need for that, but I tried with it and without it just in case it works
process.StartInfo.UseShellExecute = true;
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
process.Start();
According to Microsoft documentation you need to set UseShellExecute to true in order to use StartInfo.WindowStyle = ProcessWindowStyle.Hidden (which I did), but program still can choose to ignore that. Looks like that's exactly what's happening there.
But I tried to get exect window handle via Spy++ and try to hide it - it works, so I can manipulate it from there and do my thing. The only problem is to find it's handle...
How do I find that handle in this case?
P.S.
Windows 10 x64 Pro Ukrainian (for other languages that window title in the code won't work)
.NET Framework 4.7.2
Code is inside .NET Framework Class Library, which is launched from C# Console Application.
For me this one works fine(on Windows 7):
using System;
using System.Diagnostics;
using System.Text;
using System.Runtime.InteropServices;
namespace findwindow
{
class Program
{
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
public static void Main(string[] args)
{
Process.Start(new ProcessStartInfo(){FileName=#"C:\Windows\System32\SystemPropertiesPerformance.exe"});
System.Threading.Thread.Sleep(100);
IntPtr hwnd = FindWindow("#32770", "Параметры быстродействия");
var sb = new StringBuilder(50);
GetWindowText(hwnd, sb, 49);
Console.WriteLine("hwnd:"+hwnd+", title:"+sb);
Console.ReadKey(true);
}
}
}
Outputs:
hwnd:5636204, title:Параметры быстродействия
Try with that code your title, and say if it works.
Also there is a different approach like in this answer.
Another approach is to use the UI Automation technology that's built in Windows. For example, this sample Console app should work. And because it's event-based, it does not need to use timers which can be context-dependent:
public static void Main(string[] args)
{
Automation.AddAutomationEventHandler(WindowPattern.WindowOpenedEvent, AutomationElement.RootElement, TreeScope.Children, (sender, e) =>
{
var element = sender as AutomationElement;
if (element.Current.Name == "Параметры быстродействия")
{
Console.WriteLine("hwnd:" + element.Current.NativeWindowHandle);
}
});
Process.Start("SystemPropertiesPerformance.exe");
Console.ReadLine(); // wait ...
Automation.RemoveAllEventHandlers(); // cleanup
}
It works fine on my Windows 10 x64 machine. If this doesn't work, make sure your program and SystemPropertiesPerformance.exe run at the same UAC level.

c# Giving focus back to parent form from other app

I'm trying to start and .exe from a child form of my main app, but the issue is that when I open the other .exe and it finish it's work (scan a finger print) and exit, my app gets minimized, so I try this:
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetForegroundWindow(IntPtr hWnd);
void method {
..........more code...........
using (Process proc = new Process())
{
proc.StartInfo.FileName = "WindowsFormsApplication3.exe";
proc.Start();
SetForegroundWindow(proc.MainWindowHandle);
}
............code here..............
}
but it doesnt work, my main app lost the focus, I find many solutions but any of them work for me, the other .exe is an app that I'm doing too.
If you want to active finger print window, your code is right! but add a waiting before SetForegroundWindow... like this:
while (string.IsNullOrEmpty(proc.MainWindowTitle))
{
System.Threading.Thread.Sleep(100);
proc.Refresh();
}
and, If you want to active the caller form (main app) you don't need SetForegroundWindow! You can write:
while (string.IsNullOrEmpty(proc.MainWindowTitle))
{
System.Threading.Thread.Sleep(100);
proc.Refresh();
}
// Then active caller form...
this.Activate();
Anyway, you need wait until finger-print window shown...

Hide multiple windows by Process

I have a process and I would like to hide the window.
It work great if the process have only one window.
But if there is a prompt dialog or an alert dialog or another sub window, the hide method hide only the main window, not the dialog...
Can you help me to hide all windows of a process please ?
Many Thanks
This is my code :
[DllImport("user32.dll")]
private static extern Boolean ShowWindow(IntPtr hWnd, Int32 nCmdShow);
public void Show()
{
ShowWindow(_processHwnd, SwShow);
}
public void Hide()
{
Process[] processRunning = Process.GetProcesses();
foreach (Process pr in processRunning)
{
if (pr.Id == _process.Id)
{
_processHwnd = pr.MainWindowHandle;
}
}
ShowWindow(_processHwnd, SwHide);
}
You need to use a bit more of the Win32 API through P/invoke to obtain the window handles for the other top-level windows.
Call GetWindowThreadProcessId() to get the thread ID of the main window.
Call EnumThreadWindows() to enumerate all the top-level windows of that thread.
It is possible that there are windows associated with a different thread in the process but the probabilities of that are vanishingly small.

How to hide a console application in C#

I have a console application in C#, and I want that the user won't be able to see it.
How can I do that?
Compile it as a Windows Forms application. Then it won't display any UI, if you do not explicitly open any Windows.
On ProjectProperties set Output Type as Windows Application.
Sounds like you don't want a console application, but a windows GUI application that doesn't open a (visible) window.
Create a console application "MyAppProxy" with following code, and put MyAppProxy in start up dir,
public static void main(string[] args)
{
Process p = new Process("MyApp");
ProcessStartUpInfo pinfo = new ProcessStartUpInfo();
p.StartupInfo = pinfo;
pinfo.CreateNoWindow = true;
pinfo.ShellExecute = false;
p.RaiseEvents = true;
AutoResetEvent wait = new AutoResetEvent(false);
p.ProcessExit += (s,e)=>{ wait.Set(); };
p.Start();
wait.WaitOne();
}
You may need to fix certain items here as I didnt check correctness of the code, it may not compile because some property names may be different, but hope you get the idea.
The best way is to start the process without window.
Process p = new Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = "echo Hello!";
//either..
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
//or..
p.StartInfo.CreateNoWindow = true;
p.Start();
See other probable solutions -
Toggle Process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden at runtime
and,
Bring another processes Window to foreground when it has ShowInTaskbar = false
To hide a console applicatin in C# when nothing else works use this code:
[DllImport("kernel32.dll")]
public static extern bool FreeConsole();
Place FreeConsole() anywhere in the code, I placed it in the Init(), and the commandline is hidden.
You can Pinvoke a call to FindWindow() to get a handle to your window and then call ShowWindow() to hide the window
OR
Start your application from another one using ProcessStartInfo.CreateNoWindow
I've got a general solution to share:
using System;
using System.Runtime.InteropServices;
namespace WhateverNamepaceYouAreUsing
{
class Magician
{
[DllImport("kernel32.dll")]
static extern IntPtr GetConsoleWindow();
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
const int HIDE = 0;
const int SHOW = 5;
public static void DisappearConsole()
{
ShowWindow(GetConsoleWindow(), HIDE);
}
}
}
Just include this class in your project, and call Magician.DisappearConsole();.
A console will flash when you start the program by clicking on it. When executing from the command prompt, the command prompt disappears very shortly after execution.
I do this for a Discord Bot that runs forever in the background of my computer as an invisible process. It was easier than getting TopShelf to work for me. A couple TopShelf tutorials failed me before I wrote this with some help from code I found elsewhere. ;P
I also tried simply changing the settings in Visual Studio > Project > Properties > Application to launch as a Windows Application instead of a Console Application, and something about my project prevented this from hiding my console - perhaps because DSharpPlus demands to launch a console on startup. I don't know. Whatever the reason, this class allows me to easily kill the console after it pops up.
Hope this Magician helps somebody. ;)
Create a wcf service and host it as per your need.

Dispose the handle on exit of application using c#

I am using the below code to block the taskbar which is working perfectly.
But since my application is running in background, the only way to exit the application
is by killing the .exe from task manager. So while exiting like this, the blocked task bar remains at the same state. But actually it shud resume the taskbar on exiting the application.
The reason i am doing this is, it is a kiosk application.
what is the way to overcome this.
public class Taskbar
{
[DllImport("user32.dll")]
public static extern int FindWindow(string className, string windowText);
[DllImport("user32.dll")]
public static extern int ShowWindow(int hwnd, int command);
public const int SW_HIDE = 0;
public const int SW_SHOW = 1;
public int _taskbarHandle;
protected static int Handle
{
get
{
return FindWindow("Shell_TrayWnd", "");
}
}
public Taskbar()
{
_taskbarHandle = FindWindow("Shell_TrayWnd", "");
}
public static void Show()
{
ShowWindow(Handle, SW_SHOW);
}
public static void Hide()
{
ShowWindow(Handle, SW_HIDE);
}
}
Why not just use this implementation to run completely fullscreen?
http://www.codeproject.com/KB/cs/FullScreenDotNetApp.aspx
Like the others have said when you killin the application no.
Your post is a bit sparse on why you cannot close your application gracefully, so il suggest this method.
1)
Hotkeys ( http://www.codeproject.com/KB/system/Hotkeys.aspx ) that can be pressed that will close down your application gracefully. I personaly like this method, as i use hotkeys in many of my apps.
2)
Starting a seperate application that will wake up every XXX and check if the main application is running, if its not running run the Show code and then kill itself. This method is very simular to how viruses often work, so its tried and works :)
If your only way to exit is by killing it, then I am afraid you can't reset the property back to normal.
There can be a workaround to this.
Create a service which monitors your application through polling and when it finds your application as 'not running', it restores the TaskBar to normal.
There can be other similar workarounds to this but I can't think of a way of doing this from within your application given the limitation.
For exiting the application, i am registering a hot key combination and resuming the task bar and kill the process from taskbar programatically.
you can make your application check for the existance of a file (or any other thing you can control from outside and the app have access to it), if found: dispose & exit.
it's dirty but gives a little bit more control of how your application terminate than killing it from the task manager.

Categories

Resources