我的应用有默认设置,可让您在启动计算机时在图标托盘上运行。 如果单击图标托盘中的图标,则应用程序将显示在桌面窗口中。 此外,如果用户尝试在旧应用程序运行时尝试启动我的应用程序的新实例,我只会显示另一个实例正在运行的消息,然后退出新实例。
现在我希望New实例不仅可以退出,还可以在桌面上激活/显示Old实例。 这是我现在的代码
if (System.Diagnostics.Process.GetProcessesByName(
System.Diagnostics.Process.GetCurrentProcess().ProcessName).Length > 1)
{
MessageBox.Show(kingCobra.Properties.Resources.Msg_Multiple_Starts,
kingCobra.Properties.Resources.Multiple_Starts,
MessageBoxButtons.OK, MessageBoxIcon.Warning);
System.Diagnostics.Process.GetCurrentProcess().Kill();
return;
}
答案 0 :(得分:2)
您需要做的是将其添加到您的主类:
[DllImport("user32.dll")]
static extern bool SetForegroundWindow(IntPtr hWnd);
然后你需要获得对已经运行的进程的引用,然后像这样调用SetForegroundWindow方法:
SetForegroundWindow(SameProcess.MainWindowHandle);
您不需要像当前那样杀死当前进程,只需在关注其他进程的主窗口后返回,如上所示
这是一个完整的工作示例:
[DllImport("user32.dll")]
static extern bool SetForegroundWindow(IntPtr hWnd);
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
var currentProcess = Process.GetCurrentProcess();
foreach (Process p in Process.GetProcessesByName(currentProcess.ProcessName))
{
if (p.Id != currentProcess.Id)
{
MessageBox.Show("Already running");
SetForegroundWindow(p.MainWindowHandle);
return;
}
}
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
答案 1 :(得分:2)
这是我见过完成这项工作的最佳方式。
public class SingleInstanceController : WindowsFormsApplicationBase
{
public SingleInstanceController()
{
IsSingleInstance = true;
}
protected override void OnStartupNextInstance(StartupNextInstanceEventArgs eventArgs)
{
Form1 form = MainForm as Form1;
form.Text = "I will run only once!";
form.Activate();
base.OnStartupNextInstance(eventArgs);
}
protected override void OnCreateMainForm()
{
MainForm = new Form1();
}
}
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
string[] args = Environment.GetCommandLineArgs();
SingleInstanceController controller = new SingleInstanceController();
controller.Run(args);
}
}
本文中的实际代码Single Instance Application。
注意:这需要您添加 Microsoft.VisualBasic.dll
的引用答案 2 :(得分:1)
我终于从Here获得了我想要的东西。我的主要问题是在关闭新的
时从Icon托盘中带来旧实例 static class Program
{
[STAThread]
static void Main()
{
if (!SingleInstance.Start()) {
SingleInstance.ShowFirstInstance();
return;
}
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
try {
MainForm mainForm = new MainForm();
Application.Run(mainForm);
} catch (Exception e) {
MessageBox.Show(e.Message);
}
SingleInstance.Stop();
}
}
//And secondly within your main form, the following code must be added:
protected override void WndProc(ref Message message)
{
if (message.Msg == SingleInstance.WM_SHOWFIRSTINSTANCE) {
Show
Window();
}
base.WndProc(ref message);
}
public void ShowWindow()
{
// Insert code here to make your form show itself.
WinApi.ShowToFront(this.Handle);
}
答案 3 :(得分:0)
您可以使用Threading Mutex和user32.dll
试试这个
第1步: 声明以下constantes:
private const int SW_NORMAL = 1; // see WinUser.h for definitions
private const int SW_SHOWMAXIMIZED = 3;
private const int SW_RESTORE = 9;
[DllImport("User32", EntryPoint = "FindWindow")]
static extern IntPtr FindWindow(string className, string windowName);
[DllImport("User32", EntryPoint = "SendMessage")]
private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
[DllImport("User32", EntryPoint = "SetForegroundWindow")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("User32", EntryPoint = "SetWindowPlacement")]
private static extern bool SetWindowPlacement(IntPtr hWnd, [In] ref WINDOWPLACEMENT lpwndpl);
[DllImport("User32", EntryPoint = "GetWindowPlacement")]
private static extern bool GetWindowPlacement(IntPtr hWnd, [In] ref WINDOWPLACEMENT lpwndpl);
private struct WINDOWPLACEMENT
{
public int length;
public int flags;
public int showCmd;
}
第2步: 添加此方法:
public void application_run(Form form1)
{
bool createdNew;
System.Threading.Mutex m = new System.Threading.Mutex(true, form1.Name, out createdNew);
if (!createdNew)
{
MessageBox.Show("...", "...", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);//Alert message
try
{
// see if we can find the other app and Bring it to front
IntPtr hWnd = FindWindow(null, form1.Text);
if (hWnd != IntPtr.Zero)
{
LoaderDomain.WINDOWPLACEMENT placement = new LoaderDomain.WINDOWPLACEMENT();
placement.length = Marshal.SizeOf(placement);
GetWindowPlacement(hWnd, ref placement);
placement.showCmd = SW_SHOWMAXIMIZED;
SetWindowPlacement(hWnd, ref placement);
SetForegroundWindow(hWnd);
}
}
catch
{
//rien
}
}
else
{
Application.Run(form1);
}
// keep the mutex reference alive until the normal termination of the program
GC.KeepAlive(m);
}
第3步: 替换主
Application.run(forms);
通过调用之前的方法