我有一个使用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();
答案 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
事件处理程序中设置它,就像更新后的代码一样。
如果您打算为应用程序提供此功能,请考虑以下几点。
Program.Main
方法中运行。
编辑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
,因为有时会显示闪烁。