在后台启动Windows应用程序
本文关键字:应用程序 Windows 启动 后台 | 更新日期: 2023-09-27 18:12:16
我有一个使用winforms用c#编写的Windows应用程序。我想确保无论何时有人从任何其他应用程序使用进程启动它。启动UI没有显示,应用程序应该静默启动。
我不能控制其他应用程序,所以我不能使用:
var p = new Process();
p.StartInfo = new ProcessStartInfo();
p.StartInfo.UseShellExecute = true;
p.StartInfo.WorkingDirectory = ConfigurationManager.AppSettings["exeFolder"].ToString(); p.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
p.StartInfo.FileName = ConfigurationManager.AppSettings["exeName"].ToString();
p.Start();
感谢您的回复。我很抱歉没有早点提供我的解决方案。我已经解决了这个问题,并记录了解决方案,以供其他人将来使用。
你可以在这里找到解决方案。
如何·创建一个新的windows项目,并删除默认表单(Form1)。·在Program.cs中创建一个新的类并从Form中继承它。·请参考以下代码。·现在改变Main方法。在应用程序中。运行将启动对象从Form1更改为ApplicationStartUp。
using System;
using System.Drawing;
using System.Windows.Forms;
using BackgroundApp.Properties;
namespace BackgroundApp
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new ApplicationStartUp());
}
}
public class ApplicationStartUp : Form
{
private NotifyIcon trayIcon;
private ContextMenu trayMenu;
private void InitializeComponent()
{
trayMenu = new ContextMenu();
trayMenu.MenuItems.Add("Exit", OnExit);
trayIcon = new NotifyIcon();
trayIcon.Text = Resources.TrayIcon;
trayIcon.Icon = new Icon(global::BackgroundApp.Properties.Resources.IntegratedServer, 40, 40);
trayIcon.ContextMenu = trayMenu;
trayIcon.Visible = true;
}
//Ctor
public ApplicationStartUp()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e)
{
Visible = false;
ShowInTaskbar = false;
base.OnLoad(e);
}
private void OnExit(object sender, EventArgs e)
{
// Release the icon resource.
trayIcon.Dispose();
Application.Exit();
}
protected override void Dispose(bool isDisposing)
{
if (isDisposing)
{
// Release the icon resource.
trayIcon.Dispose();
}
base.Dispose(isDisposing);
}
}
大多数情况下,当一个应用程序从另一个应用程序启动时,它是不带参数启动的。
因此,可以让应用程序检查起始参数。如果没有参数,则从隐藏窗口开始。如果有参数,在窗口可见的情况下启动应用程序。您必须修改Program.cs文件中的main
方法,使其看起来像这样:
using System.Diagnostics;
static class Program
{
// get the current process
var thisProc = Process.GetCurrentProcess();
// file name of this process
var procFileName = new System.IO.FileInfo(thisProc.MainModule.FileName).Name;
// look for all with the same file name as this one.
foreach (var proc in Process.GetProcessesByName(
procFileName.Substring(0, procFileName.LastIndexOf('.'))))
{
// if there is another process with the same file name and a different id
// it means there is a previous instance of the application running
if (proc.MainModule.FileName == thisProc.MainModule.FileName &&
proc.Id != thisProc.Id)
{
MessageBox.Show("An instance of this application is already running.");
return; // stop running this instance
}
}
static internal bool useGui;
/// <summary>The main entry point for the application.</summary>
[STAThread]
static void Main(string[] args)
{
useGui = (from arg in args where arg.ToLower() == "/gui").Any();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
然后在Form1.Show
的事件处理程序中,通过读取useGui
变量的值,使表单可见或不可见,如下所示
private void Form1_Show(object sender, EventArgs e)
{
this.Visible = Program.useGui;
}
编辑
在Form.Load
事件中设置表单的Visible
属性不会隐藏它。您应该在Form.Shown
事件处理程序中设置它,就像更新后的代码一样。
如果您打算为应用程序提供此功能,您应该考虑以下几点:
- 正常启动应用程序将导致它闪烁并隐藏。这可能使用户在不知情的情况下多次启动应用程序。因此,建议检查程序的副本是否已经在
Program.Main
方法中运行。 - 应用程序在运行时将被隐藏。因此,如果您没有在进程完成所有操作后输入代码关闭它,用户将不得不杀死进程以终止它。
编辑2
更新了class Program
的代码,修复了问题#1。
你的应用程序必须有一个GUI吗?
如果没有,你可以重写它。如果你需要配置GUI,你可以编写第二个应用程序连接到第一个应用程序来配置它。
您可以在应用程序中使用参数。启动您的应用程序的另一个应用程序可以传入一个参数,如/noui
。或者您可以默认不使用gui,并使用/ui
等参数以gui开始。由于您无法控制调用应用程序,因此您可能会选择第二个选项。
所以如果你没有UI,你有一些处理无论如何都要完成,当适当的事件发生时,启动UI的部分(你说的消息框)。
我的建议是从program.cs的Main()
中启动一个线程,并在该线程中进行处理。稍后,当您需要显示某些内容时,您将使用简单的代码MessageBox.Show
来显示它—因为您的新线程将拥有自己的消息循环。
不要尝试在主表单中设置visible=false
,因为有时会出现闪烁