使用ClickOnce获得更新后的程序的两个实例 [英] Using ClickOnce getting two instances of the program after update

查看:99
本文介绍了使用ClickOnce获得更新后的程序的两个实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经开始收到的ClickOnce 设置和使用电话后 Application.Restart()低于code; 我最终与应用程序的两个实例(最近更新的一个和previous版)。

 私有静态无效的checkForUpdate(){
            ApplicationDeployment UpdateCheck的= ApplicationDeployment.CurrentDeployment;
            UpdateCheckInfo信息= updateCheck.CheckForDetailedUpdate();
            如果(info.UpdateAvailable){
                updateCheck.Update();
                的MessageBox.show(应用程序已经升级,现在将重新启动。);
                Application.Restart();
            }
    } //这有try / catch语句,但没想到会是有关
     //因为没有异常被抛出
 

这是我第一次使用点击一次,而我惊讶于它的简单起见,我不太确定在何处放置人工检查(我不希望用户有选择或看到丑陋更新窗口)。

我已经把它放在我的两个 MainForm.cs 和我的的Program.cs 用相同的结果都。我包括我的主要()以防万一它是相关的。

  [STAThread]
静态无效的主要(){
    检查更新();
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(假);
    Application.Run(新的MainForm());
}
 

解决方案

好了,理解了它。由杰里米·汤普森提供的链接给了我一些想法......主要的延迟,但没有实现休眠线程(在那个code中的实例,因为只是拖延了应用程序的启动)。

我最终什么做什么是执行一个可选的参数在我的默认构造函数启动一个定时器(集1.5秒,但如果应用程序需要更多的启​​动时间根据需要可以修改)。当计时器的勾选触发的事件就在那个时候我叫 Application.Restart()。我的应用程序有一定的Active Directory调用和数据库调用来获得自己像它应该和我猜这是什么原因造成了意想不到的效果设置,但我不知道。

新的构造......

 公开的MainForm(布尔WasUpdated = FALSE){
    的InitializeComponent();
    如果(!WasUpdated){
        例如=这一点;
        图标= DesktopInterface.MainForm.Properties.Resources.favicon;
        的TabPages = DesktopInterface.MainForm.Setup.TabSetup.GetTabs();
        的foreach(VAR页的TabPages){
            tabControl1.TabPages.Add(页);
        }
    } 其他 {
        restartTimer.Start();
    }
}
 

和我的修改的Program.cs

  [STAThread]
静态无效的主要(){
    检查更新();
    SetAddRemoveProgramsIcon();
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(假);
    Application.Run(新的MainForm(WasUpdated));
}
// WasUpdated是被设定的checkForUpdate方法在类级别的变量
 

完全的checkForUpdate()方法......

 私有静态无效的checkForUpdate(){
            尝试 {
                ApplicationDeployment UpdateCheck的= ApplicationDeployment.CurrentDeployment;
                UpdateCheckInfo信息= updateCheck.CheckForDetailedUpdate();
                如果(info.UpdateAvailable){
                    updateCheck.Update();
                    WasUpdated = TRUE;
                    的MessageBox.show(应用程序已经升级,现在将重新启动。);
                }
            }赶上(DeploymentDownloadException前){
                的MessageBox.show(自动更新失败错误:+前);
            }赶上(InvalidDeploymentException前){
                的MessageBox.show(自动更新失败错误:+前);
            }赶上(DeploymentException前){
                的MessageBox.show(自动更新失败错误:+前);
            }赶上(例外前){
                的MessageBox.show(自动更新失败错误:+前);
            }
        }
 

我将最终发布,这是转换后,做的checkForUpdate()有一个返回值,然后就递过来的的MainForm 构造,而不必在的Program.cs

一类级别标志

I've started getting ClickOnce setup and using the code below after calling Application.Restart(); I end up with two instances of the application (the newly updated one and the previous version).

    private static void CheckForUpdate() {
            ApplicationDeployment updateCheck = ApplicationDeployment.CurrentDeployment;
            UpdateCheckInfo info = updateCheck.CheckForDetailedUpdate();
            if(info.UpdateAvailable) {
                updateCheck.Update();
                MessageBox.Show( "The application has been upgraded, and will now restart." );
                Application.Restart();
            }
    }//this has try/catch but didn't think it would be relevant 
     //since no exception is being thrown

This is my first time using click once and while I'm amazed at the simplicity of it I wasn't quite sure WHERE to put the manual check (I don't want the users to have a choice or see the ugly update window).

I've placed it both in my MainForm.cs and my Program.cs with the same results for both. I'm including my Main() just in case it's relevant.

[STAThread]
static void Main() {
    CheckForUpdate();
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault( false );
    Application.Run( new MainForm() );
}

解决方案

Ok, figured it out. The link provided by Jeremy Thompson gave me some ideas...mainly the delay, but without implementing a sleeping thread (since in the instance of that code simply delayed the start of the app).

What I ended up doing was implementing an optional Parameter in my default constructor that started a timer (set for 1.5 seconds, but could be modified as needed if app needed more startup time). When the Timer's Tick event fired THAT'S when I called Application.Restart(). My app has some Active Directory calls and Database Calls to get itself setup like it should and I'm guessing this is what caused the unexpected results, but I'm not sure.

NEW CONSTRUCTOR...

public MainForm(bool WasUpdated = false) {
    InitializeComponent();
    if(!WasUpdated) {
        instance = this;
        Icon = DesktopInterface.MainForm.Properties.Resources.favicon;
        tabPages = DesktopInterface.MainForm.Setup.TabSetup.GetTabs();
        foreach(var page in tabPages) {
            tabControl1.TabPages.Add( page );
        }
    } else {
        restartTimer.Start();
    }
}

and my modified Program.cs

[STAThread]
static void Main() {
    CheckForUpdate();
    SetAddRemoveProgramsIcon();
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault( false );
    Application.Run( new MainForm(WasUpdated) );
}
//WasUpdated is a class level variable that gets set inside of the CheckForUpdate method

Full CheckForUpdate() Method....

private static void CheckForUpdate() {
            try {
                ApplicationDeployment updateCheck = ApplicationDeployment.CurrentDeployment;
                UpdateCheckInfo info = updateCheck.CheckForDetailedUpdate();
                if(info.UpdateAvailable) {
                    updateCheck.Update();
                    WasUpdated = true;
                    MessageBox.Show( "The application has been upgraded, and will now restart." );
                }
            } catch(DeploymentDownloadException ex) {
                MessageBox.Show( "Automatic Update Failed.  Error: " + ex );
            } catch(InvalidDeploymentException ex) {
                MessageBox.Show( "Automatic Update Failed.  Error: " + ex );
            } catch(DeploymentException ex) {
                MessageBox.Show( "Automatic Update Failed.  Error: " + ex );
            } catch(Exception ex) {
                MessageBox.Show( "Automatic Update Failed.  Error: " + ex );
            }
        }

What I'll end up doing after posting this is switching the CheckForUpdate() to have a return value and then just passing that to the MainForm Constructor instead of having a class level flag in Program.cs

这篇关于使用ClickOnce获得更新后的程序的两个实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆