This question already has answers here:
How to start WinForm app minimized to tray?
(6 answers)
Closed 8 years ago.
I have developed a windows form application and installer for it. I had installed that app on my machine. Now when I restart my PC or Log in on machine the App gets launched and shown on desktop. A sys tray icon is also shown in sys-tray. Now I want to keep app hidden and only sys tray icon should be visible. Means app should not be displayed on screen but sys tray icon should be visible. I have used "CreateProcessAsCurrentUser" method in which I have set the value of "STARTF_USESHOWWINDOW" to different values. But still its not working. Also I am not getting which method of Application gets called on System startup. Is it Main() function from Program.cs file. Please tell me the solution and also the Function which gets called.
[STAThread]
Main() function code: `static void Main()
{
Mutex mutex = new Mutex(false, "Application Name");
try
{
if (mutex.WaitOne(0, false))
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
Application.Run(new MainForm());
}
else
{
IntPtr pf = NativeMethods.FindWindow(null, "Application Name");
NativeMethods.ShowWindow(pf, 0);
NativeMethods.SetForegroundWindow(pf);
}
}
I have set the value of flag as below.
[Flags]
public enum CreateProcessFlags : uint
{
STARTF_USESHOWWINDOW = 0x00000000,
}
try this.... put this in your form:
protected override void SetVisibleCore(bool value)
{
base.SetVisibleCore(false);
}
this will always now make the form invisible.
you will need some logic though to determine if it should be shown or not from other parts of your app. for example, set a global bool value and modify the code above to use that.
alternatively, you can use this:
protected override void OnVisibleChanged(EventArgs e)
{
base.OnVisibleChanged(e);
this.Visible = false;
}
but you will see a bit of a flash when you run the app straight away. you then, again, need to control when to make it visible so check the global bool value for the visible property so you can eventually display the form
have you try this?
private void Form1_Load(object sender, EventArgs e)
{
this.WindowState = FormWindowState.Minimized;
this.Hide();
this.ShowInTaskbar = true;
}
then use notifyicon
Related
This question already has answers here:
Communicate between two windows forms in C#
(12 answers)
Closed 7 years ago.
I am making a game, and I have 3 main forms that I am using, one is the start menu, one is the main game form, and the other is a create map form. My question is directed to how can I send variables between them. I know of the classic form setup, where you show one form from the other, and pass information like this...
Form1 form = new Form1();
form.Show();
form.varible = ...
But i don't like how the previous form is still showing, and form.ShowDialog isn't what I am going for either. I have a system where you cycle through forms, where it opens your new form and closes the old one, and it works great, except I don't know how to send information to the new form. I changed the Program.cs code to look like this
public static bool OpenForm1OnClose { get; set; }
public static bool OpenForm2OnClose { get; set; }
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
OpenForm1OnClose = true;
OpenForm2OnClose = false;
while (OpenForm1OnClose || OpenForm2OnClose)
{
if(OpenForm1OnClose)
Application.Run(new Form1());
if (OpenForm2OnClose)
Application.Run(new Form2());
}
}
This is just a testing program right now that switches between two forms - click one button and it goes to the other form and closes the one you were on. Here's what the button click code looks like
private void button1_Click(object sender, EventArgs e) // form1's button
{
Program.OpenForm2OnClose = true;
this.Close();
}
That is all the code right there, nothing more to it really. Any Idea's on how to pass variables would be awesome, or if its straight up impossible, advice on a good way to switch between forms would be helpful. Thanks for reading
If you're asking what I think, the answer is simple. You just need to have your constructor take the information as its args.
private var myInfo;
public Form1(var myInfo_)
{
InitializeComponent();
myInfo = myInfo_;
}
I hope this is in fact what you want.
I have created setup of my application using Windows Installer.
Now I want to Start application at Windows Start-Up and move it system minimize tray as i don't want to display GUI(View) at Windows Start-Up.
I have searched in Google and i found to use Registry key But that is not enough for me as i also want to move to system minimize tray and application run.
My purpose to do it is, user do not feels annoying when application starts every time when he/she starts system.
Can anyone have answer?
Thanks..
In your application, add an event handler for the FrameworkElement.Loaded event. In that handler, add the following code:
WindowState = WindowState.Minimized;
This will minimise the application when it starts.
To start the application when the computer starts, you'll need to add your program into Windows Scheduler and set it to run at startup. You can find out more on the Schedule a task page at MSDN.
You also have to set this property to remove it from the taskbar
ShowInTaskbar= false;
Maybe this answer is late, but I still want to write it down to help those who haven't found solutions yet.
Firstly you need to add a function to minimize your app to tray when it autostarts as system startup.
In your App.xaml file, change the original StartupUri=... to Startup="App_Startup" as below. App_Startup is your function name and can be changed.
<Application x:Class="Yours.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Startup="App_Startup">
In your App.xaml.cs file. Add the function below:
public partial class App : Application
{
private void App_Startup(object sender, StartupEventArgs e)
{
// Process command line args
var isAutoStart = false;
for (int i = 0; i != e.Args.Length; ++i)
{
if (e.Args[i] == "/AutoStart")
{
isAutoStart = true;
}
}
// Create main application window, starting minimized if specified
MainWindow mainWindow = new MainWindow();
if (isAutoStart)
{
mainWindow.WindowState = WindowState.Minimized;
}
mainWindow.OnAutoStart();
}
}
In your MainWindow.xaml.cs, add a function as below:
public void OnAutoStart()
{
if (WindowState == WindowState.Minimized)
{
//Must have this line to prevent the window start locatioon not being in center.
WindowState = WindowState.Normal;
Hide();
//Show your tray icon code below
}
else
{
Show();
}
}
Then you should set you app utostart as system start.
Now if you have a switch to decide whether you app to autostart as system start, you can just add the function below as your switch status changed event function.
private void SwitchAutoStart_OnToggled(object sender, RoutedEventArgs e)
{
const string path = #"SOFTWARE\Microsoft\Windows\CurrentVersion\Run";
var key = Registry.CurrentUser.OpenSubKey(path, true);
if (key == null) return;
if (SwitchAutoStart.IsOn)
{
key.SetValue("Your app name", System.Reflection.Assembly.GetExecutingAssembly().Location + " /AutoStart");
}
else
{
key.DeleteValue("Your app name", false);
}
}
If you want to automatically start the application for all users on Windows startup, just replace the forth line with
RegistryKey key = Registry.LocalMachine.OpenSubKey(path, true);
^_^
I have a list of report names displayed as Tree hierarchy in ReportViewer control. When user clicks on a report name, an input form loads, user enters some values and presses OK. At this point, Splash screen should load while the backend process is happening (connecting to DB, retrieving values etc). Once the report is loaded in Reportviewer editor, the splashscreen should close.
So far, I am able to display the splash screen however it gets stuck at that point, the actual report does not load and the splash screen stays on forever.
Is it possible to use splashscreen in the middle of application, not at app launch? If so, how do I continue with loading report?
static class Program
{
[STAThread]
static void Main(string[] args)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new SnapPlusReports());
//new SplashScreenApp().Run(args);
}
}
public class SplashScreenApp : WindowsFormsApplicationBase
{
private static SplashScreenApp _application;
public static void Run(Form form)
{
_application = new SplashScreenApp { MainForm = form };
_application.Run(Environment.GetCommandLineArgs());
}
protected override void OnCreateSplashScreen()
{
this.SplashScreen = new ShowProgress();
base.OnCreateSplashScreen();
}
}
I have done this before by making a new form at run time dynamically with code. Make sure you set all the options up, especially FormBorderStyle to none, or something like that so the user can't close it. Then simply manipulate labels that appear on that form, and eventually close it once your process is complete.
This way you don't have to worry about threading and a nice side effect is that the initial form won't be clickable.
For example I have an about form that pops up during run time (granted I don't change anything on it but the idea is there:
AboutForm aboutForm = new AboutForm();
aboutForm.StartPosition = FormStartPosition.CenterParent;
Label lblAbout = new Label();
Version applicationVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
lblAbout.Text = applicationVersion.ToString();
lblAbout.Location = new Point(145,104);
aboutForm.Controls.Add(lblAbout);
aboutForm.ShowDialog();
This shows the current programs version number, etc. There are other labels that already exist on the form (I created it visually first and then called an instance of it).
Hope this helps!
...Catch other instances and gracefully exit if you need only one copy of your app in memory at a given time
static void Main()
{
Application.EnableVisualStyles();
bool exclusive;
System.Threading.Mutex appMutex = new System.Threading.Mutex(true, "MY_APP", out exclusive);
if (!exclusive)
{
MessageBox.Show("Another instance of xxxx xxxBuilder is already running.","MY_APP",
MessageBoxButtons.OK,
MessageBoxIcon.Exclamation );
return;
}
Application.SetCompatibleTextRenderingDefault(false);
xxxWindowsApplication.InitializeApplication();
Application.Run(new frmMenuBuilderMain());
GC.KeepAlive(appMutex);
}
In the main form load you could do something like:
private void frmMenuBuilderMain_Load(object sender, EventArgs e)
{
//Show Splash with timeout Here--
if(!SystemLogin.PerformLogin())
{
this.Close();
return;
}
tmrLoad.Enabled = true;
}
How to show/hide an application that's running like:
Visible = false;
ShowInTaskBar = false;
using C#?
I tried unsuccessfully, using:
ShowWindow(handle, SW_SHOWNORMAL);
but it does not show it if the application is running in this above situation.
UPDATE; My scenery:
I have an application(written by me) that when WindowState is FormWindowState.Minimized I hide application of TaskBar and put it in "tray icon mode".
I'm using the following method for ensure application single instance:
[STAThread]
static void Main()
{
bool createdNew;
Mutex m = new Mutex(true, "...", out createdNew);
if (!createdNew)
{
Process currentProc = Process.GetCurrentProcess();
foreach (Process proc in Process.GetProcessesByName(currentProc.ProcessName))
{
if (proc.Id != currentProc.Id)
{
IntPtr handle = currentProc.Handle;
SetForegroundWindow(handle);
break;
}
}
}
else
{
Application.SetCompatibleTextRenderingDefault(false);
Application.EnableVisualStyles();
Application.Run(new Form1());
}
}
the problem is,it works fine for ensure the single instance,but I want show application(exit of tray icon mode) if application is running.
I thought to do communication in applications,something like send message from app1(1) to app2, app2 read the message that's 1 and do some action. but I have no idea how do this, ShowWindow() seemed at ago hours the best way to do this,but #Hans Passant pointed some points,that it's not possible. I hope this is clear.
Different ways to solve this is very appreciated. Thanks again!
Changing the ShowInTaskbar property changes the Handle value. It is one of several Form class properties that can only be specified in the native CreateWindowEx() call and can't be changed later. So changing the property requires Winforms to re-create the window. And that gives it a different handle, making it very likely that the ShowWindow() call uses the wrong value.
You didn't find out that this was the problem because you are not checking the ShowWindow() return value. Very important when you pinvoke Windows calls, you don't have a friendly .NET exception to whack you over the head when the call failed.
I was looking for how to do this without single instance, and I just found the solution.
[STAThread]
static void Main()
{
string proc = Process.GetCurrentProcess().ProcessName;
Process[] processes = Process.GetProcessesByName(proc);
// No form has been created
if (processes.Length <= 1)
{
Form1 form = new Form1();
Application.Run(form);
}
// Form has been created
else
{
for (int i = 0; i < processes.Length; i++)
{
IntPtr formhwnd = FindWindow(null, "Form1");// get HWND by the text name of form
// Use WIN32 methods
int style = GetWindowLong(formhwnd, GWL_EXSTYLE);// Get EX-Style of the window
style |= WS_EX_APPWINDOW;// Add the APP style that shows icon in taskbar
style &= ~(WS_EX_TOOLWINDOW);// Delete the tool style that does not show icon in taskbar
SetWindowLong(formhwnd, GWL_EXSTYLE, style);// Set the EX-Style
ShowWindow(formhwnd, SW_SHOW);// Show the Window
SwitchToThisWindow(formhwnd, true);// Focus on the window
}
}
}
If you want to show/hide a window from another app. This can still be a reference.Just get the handle of that window and use the win32 methods (import from C++ dll) to set the window styles.
I just want a c# application with a hidden main window that will process and respond to window messages.
I can create a form without showing it, and can then call Application.Run() without passing in a form, but how can I hook the created form into the message loop?
Is there another way to go about this?
Thanks in advance for any tips!
Excellent! That link pointed me in the right direction. This seems to work:
Form f = new Form1();
f.FormBorderStyle = FormBorderStyle.FixedToolWindow;
f.ShowInTaskbar = false;
f.StartPosition = FormStartPosition.Manual;
f.Location = new System.Drawing.Point(-2000, -2000);
f.Size = new System.Drawing.Size(1, 1);
Application.Run(f);
To keep it from showing up in Alt-Tab, you need it to be a tool window. Unfortunately, this prevents it from starting minimized. But setting the start position to Manual and positioning it offscreen does the trick!
In the process of re-writing a VC++ TaskTray App, in C# .NET, I found the following method truly workable to achieve the following.
No initial form dislayed at startup
Running Message Loop that can be used with Invoke/BeginInvoke as needed as IsWindowHandle is true
The steps I followed:
Used an ApplicationContext in Application.Run() Instead of a form. See http://www.codeproject.com/Articles/18683/Creating-a-Tasktray-Application for the example I used.
Set the Form's ShowInTaskbar property to true within the GUI Designer. (This seems counter productive but it works)
Override the OnLoad() method in your Form Class setting Visible and ShowInTaskbar to false as shown below.
protected override void OnLoad(EventArgs e)
{
Visible = false;
ShowInTaskbar = false;
base.OnLoad(e);
}
I know this is old question, but it ranks well in google, so I will provide my solution anyway.
I do two things:
private void Form_Load(object sender, EventArgs e)
{
Opacity = 0;
}
private void Form_Shown(object sender, EventArgs e)
{
Visible = false;
Opacity = 100;
}
The best way is to use the following 1-2 lines in the constuctor:
this.WindowState = FormWindowState.Minimized;
this.ShowInTaskbar = false; // This is optional
You can even set the Minimized property in the VS Property window.
You can create a class that inherits from System.Windows.Forms.NativeWindow (which provides basic message loop capability) and reference the Handle property in its constructor to create its handle and hook it into the message loop. Once you call Application.Run, you will be able to process messages from it.
I solved the problem like this:
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Main main = new Main();
Application.Run();
//Application.Run(new Main());
}
This code resides in the Program.cs file, and you can see the original Application.Run method call commented out. I just create a Main class object (my main form class is named Main) and start application message loop w/o any parameters. This starts the application, initializes any form components but doesn't show the form.
Note: you have to have some method to get your window showing (like system tray icon, hotkey or timer or anything you might like).
public partial class Form1 : Form
{
private bool _isApplicationRun;
public Form1(bool applicationRun)
{
InitializeComponent();
_isApplicationRun = applicationRun;
}
protected override void SetVisibleCore(bool value)
{
if (_isApplicationRun)
{
_isApplicationRun = false;
base.SetVisibleCore(false);
return;
}
base.SetVisibleCore(value);
}
}
static class Program
{
[STAThread]
static void Main()
{
Application.Run(new Form1(true));
}
}
Why can't you just pass the form when you call Application.Run? Given that it's clearly a blocking call, on what event do you want to show the form? Just calling form.Show() should be enough.
Using Kami's answer as an inspiration, I created a more complete concept. If you use this solution, don't ever show the hidden window. If you do, the user might close it and then you've lost the ability to control the application exit in an orderly way. This approach can be used to manage a Timer, NotifyIcon, or any other component that is happy living on an invisible form.
using System;
using System.Windows.Forms;
namespace SimpleHiddenWinform
{
internal class HiddenForm : Form
{
private Timer _timer;
private ApplicationContext _ctx;
public HiddenForm(ApplicationContext ctx)
{
_ctx = ctx;
_timer = new Timer()
{
Interval = 5000, //5 second delay
Enabled = true
};
_timer.Tick += new EventHandler(_timer_Tick);
}
void _timer_Tick(object sender, EventArgs e)
{
//tell the main message loop to quit
_ctx.ExitThread();
}
}
static class Program
{
[STAThread]
static void Main()
{
var ctx = new ApplicationContext();
var frmHidden = new HiddenForm(ctx);
//pass the application context, not the form
Application.Run(ctx);
}
}
}
Form1 f1=new Form1();
f1.WindowState = FormWindowState.Minimized;
f1.ShowInTaskbar = false;
in the Form1 code file add this.Visible = false; to the constructor.
This will hide the window but it will flash for a sec before it is hidden. Alternatively you can write your own Application.Run command.
for more info http://social.msdn.microsoft.com/forums/en-US/winforms/thread/dece45c8-9076-497e-9414-8cd9b34f572f/
also you may want to set the this.ShowInTaskbar to false.
You should look at creating a 'service' as this is an application without a form.
See http://support.microsoft.com/kb/816169