2012-10-27 32 views
0

在調用Application.Restart();後,我開始獲取ClickOnce設置和使用下面的代碼,最終得到應用程序的兩個實例(新更新的和先前的版本)。使用ClickOnce在更新後獲取程序的兩個實例

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 

這是我第一次使用點擊一次,而我在它的簡單起見,我不太知道從哪裏把人工檢查(我不希望用戶有選擇的驚訝或看到醜陋的更新窗口)。

我已將它放在我的MainForm.cs和我的Program.cs中,兩者的結果相同。爲了防止相關,我將包含我的Main()

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

構造函數當我使用Click One時,我依靠應用程序檢測是否有更新的版本。但'因爲你不想讓用戶看到窗口或有選擇'我找到了你[抑制ClickOnce的啓動應用程序窗口](http://social.msdn.microsoft.com/forums/en-US/winformssetup /線程/ cd991579-bf49-4bac-b095-e1f5932a47a0 /)。如果順利,請發佈您的結果! –

+0

我列出的代碼已經有幾個例外。這是一個異步檢查(我不擔心它延遲啓動,因爲一切都是內部的,所以它甚至不明顯),並且來自該論壇的發佈代碼也睡眠該線程1.5秒,這沒有改變發生的事情我...可悲的是 – Jared

+0

'它是一個ASync方法' - 你嘗試用它來更新自己後啓動程序的新實例嗎?如果是這樣,恕我直言,它更好地依靠Click Once技術。 –

回答

0

好的,算出來了。由Jeremy Thompson提供的鏈接給了我一些想法...主要是延遲,但是沒有實現睡眠線程(因爲在那個代碼的實例中簡單地延遲了應用程序的啓動)。

我最終做的是在我的默認構造函數中實現一個可選參數,該參數啓動了一個計時器(設置爲1.5秒,但如果應用程序需要更多啓動時間,則可以根據需要進行修改)。當計時器的Tick事件發生時,我撥打Application.Restart()。我的應用程序有一些Active Directory調用和數據庫調用來獲得它自己的設置,我猜這是什麼導致了意想不到的結果,但我不確定。

新的構造......

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(); 
    } 
} 

和我的修改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 

完全CheckForUpdate()方法....

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); 
      } 
     } 

什麼我將最終發佈後做這是切換CheckForUpdate()有一個返回值,然後通過那MainForm構造函數代替Program.cs

+1

我仍然對如何在更新後停止加載兩個實例感到困惑。你能解釋得更清楚嗎?默認的'InstallUpdateSyncWithInfo'方法會導致兩個實例加載?這篇文章的標題有點誤導。我來到這個頁面尋找解決這個問題。 – Adam

+0

我不確定'InstallUpdateSyncWithInfo'方法是什麼。此外,我不再有權訪問代碼,但是如果您的代碼啓動了兩個實例,請關閉「舊」代碼,並且由於它啓動了第二個代碼,那麼它應該可以運行,不需要代碼,我不確定如何提供幫助。 – Jared

相關問題