在后台启动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应用程序

感谢您的回复。我很抱歉没有早点提供我的解决方案。我已经解决了这个问题,并记录了解决方案,以供其他人将来使用。

你可以在这里找到解决方案。

如何·创建一个新的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事件处理程序中设置它,就像更新后的代码一样。

如果您打算为应用程序提供此功能,您应该考虑以下几点:

  1. 正常启动应用程序将导致它闪烁并隐藏。这可能使用户在不知情的情况下多次启动应用程序。因此,建议检查程序的副本是否已经在Program.Main方法中运行。
  2. 应用程序在运行时将被隐藏。因此,如果您没有在进程完成所有操作后输入代码关闭它,用户将不得不杀死进程以终止它。

编辑2
更新了class Program的代码,修复了问题#1。

你的应用程序必须有一个GUI吗?

如果没有,你可以重写它。如果你需要配置GUI,你可以编写第二个应用程序连接到第一个应用程序来配置它。

您可以在应用程序中使用参数。启动您的应用程序的另一个应用程序可以传入一个参数,如/noui。或者您可以默认不使用gui,并使用/ui等参数以gui开始。由于您无法控制调用应用程序,因此您可能会选择第二个选项。

所以如果你没有UI,你有一些处理无论如何都要完成,当适当的事件发生时,启动UI的部分(你说的消息框)。

我的建议是从program.cs的Main()中启动一个线程,并在该线程中进行处理。稍后,当您需要显示某些内容时,您将使用简单的代码MessageBox.Show来显示它—因为您的新线程将拥有自己的消息循环。

不要尝试在主表单中设置visible=false,因为有时会出现闪烁