I want to hide a window that is created when I call p.Start(). The code I have now does work but my program freezes for about 20-40 seconds because of the while loop that is in there.
Current code:
[System.Runtime.InteropServices.DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
const int SW_HIDE = 0;
//Process p is already created and initialized
p.Start();
while(p.MainWindowHandle == IntPtr.Zero)
{
p.Refresh();
}
ShowWindow(p.MainWindowHandle, SW_HIDE);
Removing the while loop prevents the freezing of my program, but the window doesn't hide then. I did do p.StartInfo.CreateNoWindow = true, but this only works for console windows.
So, my question is: How can I hide a window created by a process without it freezes my program for 20 seconds
Can you try to put this code:
while(p.MainWindowHandle == IntPtr.Zero)
{
p.Refresh();
}
ShowWindow(p.MainWindowHandle, SW_HIDE);
in task and run it? It should remove the program freezing.
Related
How would I make my program check if a certain application like "notepad" has focus and ultimately open my second form when it does have focus, closing that second form when it loses focus.
(I would Also like to include an updater so that if the checkbox is checked while "notepad" is closed keep the checkbox checked, but do not open my second form until "notepad" has been opened) I know this is a very specific question and hence why I couldn't find anything relative to this.
Here is a mockup of what I believe it would look like:
DLL import
getforeground window
Process g = "notepad"
if (g is Foreground window in front && checkbox.checked) // my checkbox i use to enable the program
{
show form two
}
else
{
hide form two
}
My solution for anyone who wants to only make their code run when a specific program is open.
This is great for Mouse events + sending inputs when a specific program is opened. (Removes that craziness from happening when outside of that program)
FirstlyImport DLLs:
[DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);
Second create this string to capture what window is active:
public string GetActiveWindowTitle()
{
const int nChars = 256;
StringBuilder Buff = new StringBuilder(nChars);
IntPtr handle = GetForegroundWindow();
if (GetWindowText(handle, Buff, nChars) > 0)
{
return Buff.ToString();
}
return null;
}
Reminder if you wish to test which application you have open just maker a timer on 1 second repeat and type this inside the timer:
Console.Writeline(GetForegroundWindow());
Once you know your applications name (Also shows the name on taskbar - not task manager) You will want to type:
if (GetActiveWindowTitle() == "Notepad") // change notepad to your program
{
// do what you want to do
}
Hopefully this helps someone like it helped me :)
I'm developing a tiny launcher. Its main idea is to fix the lack of functionality in Viber for Windows.
I want it to make start Viber minimized to tray only.
Normally, when Viber is starting, it appears a Viber main window on desktop and an icon - in system tray. All the time I should close this obsolete window manually.
So, I have written a few lines of code, but I found that it still couldn't close the window:
using System;
using System.Diagnostics;
class ViberStrt {
static void Main() {
Process newProc = Process.Start("c:\\Users\\Dmytro\\AppData\\Local\\Viber\\Viber.exe");
Console.WriteLine("New process has started");
//newProc.CloseMainWindow();
newProc.WaitForExit();
newProc.Close();
newProc.Dispose();
Console.WriteLine("Process has finished");
//newProc.Kill();
}
}
But whatever I tried (Close, Dispose) - it does not work.
Method Kill does not fit, because it kills all. But the only thing I need is to close Viber main window and leave the process in the System Tray.
There is also another way: to start Viber minimized at once:
using System;
using System.Diagnostics;
class LaunchViber
{
void OpenWithStartInfo()
{
ProcessStartInfo startInfo = new ProcessStartInfo("c:\\Users\\Dmytro\\AppData\\Local\\Viber\\Viber.exe");
startInfo.WindowStyle = ProcessWindowStyle.Minimized;
Process.Start(startInfo);
}
static void Main()
{
//Process newProc = Process.Start("c:\\Users\\Dmytro\\AppData\\Local\\Viber\\Viber.exe");
LaunchViber newProc = new LaunchViber();
newProc.OpenWithStartInfo();
}
}
In such a case, we receive a minimized window on the TaskPane and an icon in the SystemTray. But in this case I have absolutely no idea how to get rid of the icon (how to close minimized window) on the TaskPane.
I shall appreciate any help/ ideas in finding a solution for this problem.
Using Pinvoke, you can try getting the handle for the actual window if you know what the window caption will be.
First, import these functions:
[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
And you may want to declare the WM_CLOSE constant:
const UInt32 WM_CLOSE = 0x0010;
Then the code to close the window (but keep the process running the in background):
var startInfo = new ProcessStartInfo(#"c:\Users\Dmytro\AppData\Local\Viber\Viber.exe");
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
var newProc = Process.Start(startInfo);
var name = "Viber +381112223344";
var windowPtr = FindWindowByCaption(IntPtr.Zero, name);
while (windowPtr == IntPtr.Zero)
{
windowPtr = FindWindowByCaption(IntPtr.Zero, name);
}
System.Threading.Thread.Sleep(100);
SendMessage(windowPtr, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
I'm working with windows form and i have a main form and when I click on some button he open a console window that do some work and when its done I want to close the console without closing the all application (main form). I try to close the console with Environment.Exit(1) or the function Destroy() that belongs to the Destroy() and Create() the console window. the Environment.Exit(1) and Destroy() both close the console but close the form too.
I wonder if there is a way to close only the console without closing the whole application
EDIT
private void btSync_Click(object sender, EventArgs e)
{
Create();
ServerSync sycs=new ServerSync();
Thread sync = new Thread(new ThreadStart(sycs.run));
sync.Start();
}
The Create() open a Console window that run a Socket() Thread.
Problem Solved
When im start the thread i add to the end of code a ThreadName.Abort and outside the thread i check if ThreadName.IsAlived==false and inside the if i Hide() the console and then Destroy() And Its Works!
the Hide() method from AppDeveloper answer.
Thanks for your help!
Instead of using Environment.Exit() hide the Console Window
using System.Runtime.InteropServices;
[DllImport("kernel32.dll")]
static extern IntPtr GetConsoleWindow();
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
const int SW_HIDE = 0x0;
const int SW_SHOW = 0x5;
public static void HideConsoleWindow()
{
var handle = GetConsoleWindow();
ShowWindow(handle, SW_HIDE);
}
Maybe there is a console.hide() option? could try that out.
I have a .dll library for c# that loves to pop out a 'Welcome' screen when it starts.
This screen appears as an application in the task manager.
Is there some way to automatically detect this application/form being launched and close it?
Thanks! :)
Here us simple console application that will monitor and close specified window
class Program
{
static void Main(string[] args)
{
while(true)
{
FindAndKill("Welcome");
Thread.Sleep(1000);
}
}
private static void FindAndKill(string caption)
{
Process[] processes = Process.GetProcesses();
foreach (Process p in processes)
{
IntPtr pFoundWindow = p.MainWindowHandle;
StringBuilder windowText = new StringBuilder(256);
GetWindowText(pFoundWindow, windowText, windowText.Capacity);
if (windowText.ToString() == caption)
{
p.CloseMainWindow();
Console.WriteLine("Excellent kill !!!");
}
}
}
[DllImport("user32.dll", EntryPoint = "GetWindowText",ExactSpelling = false, CharSet = CharSet.Auto, SetLastError = true)]
private static extern int GetWindowText(IntPtr hWnd,StringBuilder lpWindowText, int nMaxCount);
}
If it's running within your process and opening a Form (not a Dialog), you can use something like this to close all Forms which aren't opened by your own Assembly.
foreach (Form form in Application.OpenForms)
if (form.GetType().Assembly != typeof(Program).Assembly)
form.Close();
What is your own Assembly is defined by the class Program, you could also use Assembly.GetExecutingAssembly or Assembly.GetCallingAssembly, but I'm not sure it will behave correctly, if you run the Application inside Visual Studio (since it might return the VS Assembly).
I am developing a software for a blind individual in C# .NET.
The software works only with the keyboard and voice to speech.
When the computer starts the program is in the start up menu, but for some reason the program is activated not in focus therefore it does not work properly unless the focus is re transferred to it.
I found a way to hook keyboard keys even when the software is not in focus but I don't see that as a solution.
I want a way to do one or more of the following:
Make sure the program loads on start up and is in focus.
Maintain focus on the program (this computer will be run only using this program).
Find a keyboard shortcut, preferably one key only (not Alt + Tab) to return focus to the program.
There are many ways you can solve this ie you can run on startup console app that will run and focus your program:
[STAThread]
static void Main(string[] args)
{
System.Diagnostics.Process myProcess = new System.Diagnostics.Process();
myProcess.StartInfo.FileName = "calc";
myProcess.Start();
IntPtr hWnd = myProcess.Handle;
SetFocus(new HandleRef(null, hWnd));
}
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern IntPtr SetFocus(HandleRef hWnd);
You can host a windows service application and using timer check if your app is alive and is focused or you can use hotkeys to bring it back focused: http://www.codeproject.com/KB/miscctrl/ashsimplehotkeys.aspx
Edited
this is console application, that will keep your app alive and focused (tested). i need to find walkaround for windows service becouse since vista something changed and form is invisible when stared from service :P
static Process myProcess;
[STAThread]
static void Main(string[] args)
{
for (int i = 0; i < 10000; i++)
{
//count how many procesess with this name are active if more than zero its still alive
Process[] proc = Process.GetProcessesByName("myprog");
if (proc.Length > 0)
{
//its alive check if it has focus
if (proc[0].MainWindowHandle != GetForegroundWindow())
{
SetFocus(proc[0].MainWindowHandle);
}
}
//no process start new one and focus on it
else
{
myProcess = new Process();
myProcess.StartInfo.FileName = "C:\\aa\\myprog.exe";
myProcess.Start();
SetFocus(myProcess.Handle);
}
Thread.Sleep(1000);
}
}
private static void SetFocus(IntPtr handle)
{
SwitchToThisWindow(handle, true);
}
[DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll", SetLastError = true)]
public static extern void SwitchToThisWindow(IntPtr hWnd, bool fAltTab);