在后台启动Windows应用程序

时间:2011-10-24 06:35:49

标签: .net c# winforms

我有一个使用winforms用C#编写的Windows应用程序。我想确保每当有人使用process.start从任何其他应用程序启动它时,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();

5 个答案:

答案 0 :(得分:4)

大多数情况下,当应用程序从另一个应用程序启动时,它将以无参数启动。

因此,您可以让您的应用程序检查起始参数。如果没有参数,则在隐藏窗口的情况下启动它。如果有参数,请在窗口可见的情况下启动应用程序。

您必须修改 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;
}

修改

Visible事件中设置表单的Form.Load属性不会隐藏它。您应该在Form.Shown事件处理程序中设置它,就像更新后的代码一样。

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

  1. 正常启动应用程序会使其闪烁并隐藏。这可能使用户在不知情的情况下多次启动应用程序。因此,建议检查程序的副本是否已在Program.Main方法中运行。
  2. 应用程序将在运行时隐藏。因此,如果您在完成所有操作后没有输入代码来关闭它,则用户必须终止该进程才能终止它。
  3. 编辑2
    更新了class Program的代码,修复了问题#1。

答案 1 :(得分:4)

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

您可以找到解决方案here

如何 ·创建一个新的Windows项目并删除默认窗体(Form1)。 ·在Program.cs中创建一个新类并从Form继承它。 ·请参考下面的代码。 ·现在更改Main方法。在Application.Run中将启动对象从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);
    }
}

答案 2 :(得分:0)

您的应用程序是否必须具有GUI?

如果没有,你可以在没有它的情况下重写它。如果您需要配置GUI,则可以编写第二个连接到第一个应用程序的应用程序。

答案 3 :(得分:0)

您可以使用您的应用程序的参数。启动您的应用程序的其他应用程序可以传入/noui之类的参数。或者你可以默认为没有gui并使用诸如/ui之类的参数来启动gui。由于您无法控制调用应用程序,因此您可以选择第二个选项。

答案 4 :(得分:0)

如果您没有UI,那么您仍然需要进行一些处理,并且当发生适当的事件时,启动部分UI(您说的是消息框)。

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

请勿尝试在主表单中设置visible=false,因为有时会显示闪烁。

相关问题