C# C语言中的应用程序启动#
我们有一个小小的C#startup应用程序,用户启动该应用程序可以从网络共享运行最新版本的主C#WinForms应用程序。这是一种简化的ClickOnce安排(我们的It人员不允许我们使用ClickOnce) 启动应用程序在调用Process.Start(“MainApplication.exe”)后退出,但主应用程序可能需要几秒钟的时间才能显示出来,给用户留下一个空白屏幕C# C语言中的应用程序启动#,c#,C#,我们有一个小小的C#startup应用程序,用户启动该应用程序可以从网络共享运行最新版本的主C#WinForms应用程序。这是一种简化的ClickOnce安排(我们的It人员不允许我们使用ClickOnce) 启动应用程序在调用Process.Start(“MainApplication.exe”)后退出,但主应用程序可能需要几秒钟的时间才能显示出来,给用户留下一个空白屏幕 是否有一种方法可以让starup应用程序在退出之前轮询操作系统,以确定主应用程序是否正在运行?还是用其他方法来处理 您可以
是否有一种方法可以让starup应用程序在退出之前轮询操作系统,以确定主应用程序是否正在运行?还是用其他方法来处理 您可以调用以查看是否已创建新流程。另一种选择是让主应用程序在加载完成后终止启动应用程序。您可以调用以查看是否已创建新进程。另一种选择是让主应用程序在加载完成后终止启动应用程序。使用Davids的建议,或者您可以在主应用程序中添加一个。它将只是一个简单的表单,在一个单独的工作线程上运行一个映像。将其作为启动时调用的第一项。您的应用程序可以继续在主线程上初始化&几秒钟后或在主应用程序完成初始化之前杀死工作线程。使用Davids的建议,或者您可以在主应用程序中放置一个。它将只是一个简单的表单,在一个单独的工作线程上运行一个映像。将其作为启动时调用的第一项。你的应用程序可以在主线程上继续初始化&几秒钟后或在主应用程序完成初始化之前杀死工作线程。我认为David的第二个选择就是这样。进程可能正在运行,但没有可见的UI。因此,一旦主窗体显示在第二个应用程序中,请终止第一个进程。可以想象,在启动新流程时,您甚至可以通过StartInfo将原始流程的流程id传递到中。我认为David的第二个选择就是这样。进程可能正在运行,但没有可见的UI。因此,一旦主窗体显示在第二个应用程序中,请终止第一个进程。您甚至可以在启动新进程时,通过StartInfo将原始进程的进程id传递进来。您可以使用
process.WaitForInputIdle()
等待应用程序进入空闲状态
Process appProcess = Process.Start("MainApplication.exe");
appProcess.WaitForInputIdle();
来自MSDN:
…您刚刚开始了一个过程
要使用其主窗口句柄,
考虑使用WaitForInputIdle
方法以允许进程完成
启动,确保主
窗口句柄已创建
属性的备注部分。您可以使用
Process.waitForInputId()
等待应用程序进入空闲状态
Process appProcess = Process.Start("MainApplication.exe");
appProcess.WaitForInputIdle();
来自MSDN:
…您刚刚开始了一个过程
要使用其主窗口句柄,
考虑使用WaitForInputIdle
方法以允许进程完成
启动,确保主
窗口句柄已创建
属性中的备注部分。这涉及到一些问题,但您可以通过使用使启动时间足够快,从而使此问题变得毫无意义。这涉及到一些问题,但是,您可以通过使用使启动时间足够快,从而使此问题成为现实。解决此问题的一种简单方法是使用全局事件向启动应用程序发出主应用程序已达到预定状态的信号。要执行此操作,请在启动应用程序中创建命名事件句柄,并等待发出信号:
static void Main(string[] args)
{
const string globalName = "MyProgramName";//something unique
bool isNew = false;
ManualResetEvent mreExited = new ManualResetEvent(false);
EventWaitHandle mreStarted = new EventWaitHandle(false, EventResetMode.ManualReset, globalName, out isNew);
try
{
if (!isNew)//already running, just exit?
return;
//start and monitor for exit
Process pstarted = Process.Start("...");
pstarted.Exited += delegate(object o, EventArgs e) { mreExited.Set(); };
pstarted.EnableRaisingEvents = true;
int index = WaitHandle.WaitAny(new WaitHandle[] { mreExited, mreStarted });
if (index == 0)//mreExited signaled
throw new ApplicationException("Failed to start application.");
}
finally
{
mreExited.Close();
mreStarted.Close();
}
}
然后,在主程序中,一旦您准备好启动应用程序退出,您将发出事件信号:
static void Main(string[] args)
{
const string globalName = "MyProgramName";//same unique name
bool isNew = false;
EventWaitHandle mreStarted = new EventWaitHandle(false, EventResetMode.ManualReset, globalName, out isNew);
try
{
if (!isNew)
mreStarted.Set();
Application.Run(new Form());
}
finally
{
mreStarted.Close();
}
}
解决这一问题的一种简单方法是使用全局事件向启动应用程序发出主应用程序已达到预定状态的信号。要执行此操作,请在启动应用程序中创建命名事件句柄,并等待发出信号:
static void Main(string[] args)
{
const string globalName = "MyProgramName";//something unique
bool isNew = false;
ManualResetEvent mreExited = new ManualResetEvent(false);
EventWaitHandle mreStarted = new EventWaitHandle(false, EventResetMode.ManualReset, globalName, out isNew);
try
{
if (!isNew)//already running, just exit?
return;
//start and monitor for exit
Process pstarted = Process.Start("...");
pstarted.Exited += delegate(object o, EventArgs e) { mreExited.Set(); };
pstarted.EnableRaisingEvents = true;
int index = WaitHandle.WaitAny(new WaitHandle[] { mreExited, mreStarted });
if (index == 0)//mreExited signaled
throw new ApplicationException("Failed to start application.");
}
finally
{
mreExited.Close();
mreStarted.Close();
}
}
然后,在主程序中,一旦您准备好启动应用程序退出,您将发出事件信号:
static void Main(string[] args)
{
const string globalName = "MyProgramName";//same unique name
bool isNew = false;
EventWaitHandle mreStarted = new EventWaitHandle(false, EventResetMode.ManualReset, globalName, out isNew);
try
{
if (!isNew)
mreStarted.Set();
Application.Run(new Form());
}
finally
{
mreStarted.Close();
}
}
我的建议是在你的应用程序中加入闪屏,它会给你一个很好的感觉,而不是如果你不想使用闪屏,那么在加载完成后终止这个过程。或者可以使用Process.GetProcessByName() 对于初始屏幕,只需制作一个窗口屏幕,在启动类中,只需从Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase继承该类即可,该类为您提供了一个方法OnCreateSplashScreen()如下重写此方法:-
protected override void OnCreateSplashScreen()
{
base.OnCreateSplashScreen();
//yourSplashScreen is the screen you made as a window form either it would be a image or form
SplashScreen = yourSplashScreen();
}
谢谢…Saurabh Singh很高兴编写代码
我的建议是在你的应用程序中加入闪屏,它会给你一种良好的感觉,而不是如果你不想使用闪屏,那么在加载完成后终止这个过程。或者可以使用Process.GetProcessByName() 对于初始屏幕,只需制作一个窗口屏幕,在启动类中,只需从Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase继承该类即可,该类为您提供了一个方法OnCreateSplashScreen()如下重写此方法:-
protected override void OnCreateSplashScreen()
{
base.OnCreateSplashScreen();
//yourSplashScreen is the screen you made as a window form either it would be a image or form
SplashScreen = yourSplashScreen();
}
谢谢…Saurabh Singh很高兴编写代码
除了使用此方法之外,我还建议添加一个启动或加载屏幕,这样用户就不会感觉到应用程序挂起。使用GetProcessByName的问题是,主应用程序的进程可能会启动(他会得到一个进程名)但是GUI可能还没有在屏幕上绘制。除了使用此方法,我建议添加一个启动或加载屏幕,这样用户就不会感觉到应用程序挂起。使用GetProcessByName的问题是,主应用程序的进程可能会启动(他会得到一个进程名)但图形用户界面可能还没有在屏幕上绘制。+1我也会有入门应用程序pr