WinForm应用程序重启?

时间:2010-08-23 13:14:29

标签: c# winforms clickonce

我的应用程序可以在我的计算机和同事的计算机上运行。我有时推出此应用程序的更新,并希望应用程序自动检测(可能通过数据库)并关闭并重新打开以安装新的更新。

我知道如何关闭应用程序,但不知道如何重新打开它,因为当它没有运行时,我不知道如何执行任何代码......

5 个答案:

答案 0 :(得分:3)

ClickOnce可以很好地处理更新应用程序。我没有在这里看到问题,如果用户发现应用程序不能正常工作(因为你已经做了更改服务器端,保证他们更新客户端),他们将重新启动应用程序并由ClickOnce提示更新机制,一旦应用程序再次启动,就说可以使用更新(如果已经设置)。

在有问题的应用程序仍在运行时,您可以判断应用程序是否应该进行更新的唯一方法是轮询服务器上的ClickOnce部署文件,并将版本号与当前部署进行比较。不可取。

编辑:

确保用户始终拥有最新版本的另一种方法是不包含持久性部署文件,并使用户始终从您网站上的启动页面运行。这只会出现最新最好的版本。

答案 1 :(得分:1)

如何创建小型更新应用。当您的应用程序检测到更新时,它会启动更新应用程序并自行关闭。更新应用程序下载并安装更新,然后重新启动主应用程序并自行关闭。

或者,如果应用程序在打开时可以自行更新,为什么需要关闭?它不能只是释放它正在使用的任何资源等并执行更新。

答案 2 :(得分:1)

您真正需要的过程是这样的:

  1. 应用程序检测到需要更新并执行更新应用程序然后退出
  2. 更新应用程序下载并安装更新
  3. 更新应用程序重新启动“主”应用程序
  4. 如果您因为UAC更新Vista / Windows7计算机上的文件,“更新应用程序”可能需要管理权限才能运行,因此您可能希望嵌入清单以帮助解决此问题。

    要启动另一个流程,您要执行的代码为System.Diagnostics.Process.Start(),例如:

    Process p = new Process();
    p.StartInfo.FileName = "C:\\Windows\\System32\cmd.exe";
    p.Start();
    

答案 3 :(得分:0)

如果您使用的是ClickOnce(并且您的标签表明您是?),那么您可以对其进行配置,以便您的应用程序在启动时检查更新。

答案 4 :(得分:0)

我有一个类似的问题,但我的是与无法管理的内存泄漏有关,我无法在一个必须全天候运行的应用程序上找到。对于客户,我同意如果内存消耗超过定义值,则重启应用程序的安全时间是03:00 AM。

我尝试Application.Restart,但由于它似乎使用某种机制在它已经运行时启动新实例,我去了另一个方案。我使用了文件系统处理的技巧,直到创建它们的进程死掉。因此,从应用程序中,我将文件删除到磁盘,并没有Dispose()句柄。我使用该文件发送'我自己'的可执行文件和启动目录(以增加灵活性)。

代码:

_restartInProgress = true;
string dropFilename = Path.Combine(Application.StartupPath, "restart.dat");
StreamWriter sw = new StreamWriter(new FileStream(dropFilename, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite));
sw.WriteLine(Application.ExecutablePath);
sw.WriteLine(Application.StartupPath);
sw.Flush();
Process.Start(new ProcessStartInfo
{
    FileName = Path.Combine(Application.StartupPath, "VideoPhill.Restarter.exe"),
    WorkingDirectory = Application.StartupPath,
    Arguments = string.Format("\"{0}\"", dropFilename)
});
Close();
最后

Close()将启动应用程序关闭,我在此处用于StreamWriter的文件句柄将保持打开状态,直到进程真正死亡。然后...

Restarter.exe开始运行。它试图以独占模式读取文件,阻止它在主应用程序没有死之前获得访问权限,然后启动主应用程序,删除文件并存在。我想这不可能更简单:

static void Main(string[] args)
{
    string filename = args[0];
    DateTime start = DateTime.Now;
    bool done = false;
    while ((DateTime.Now - start).TotalSeconds < 30 && !done)
    {
        try
        {
            StreamReader sr = new StreamReader(new FileStream(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite));
            string[] runData = new string[2];
            runData[0] = sr.ReadLine();
            runData[1] = sr.ReadLine();
            Thread.Sleep(1000);
            Process.Start(new ProcessStartInfo { FileName = runData[0], WorkingDirectory = runData[1] });
            sr.Dispose();
            File.Delete(filename);
            done = true;
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
        Thread.Sleep(1000);
    }
}