2013-10-14 110 views
0

我使用AppplicationDeployment類,以檢查是否升級包,然後再升級像下面ClickOnce應用程序升級後,沒有重新啓動完成

Dim AD As System.Deployment.Application.ApplicationDeployment = System.Deployment.Application.ApplicationDeployment.CurrentDeployment 
Dim info As System.Deployment.Application.UpdateCheckInfo = Nothing 

Me.DialogResult = Windows.Forms.DialogResult.Cancel 
Me.Close() 

AD.Update() 

Application.Restart() // this doesn't work which is still ok. 

重啓不工作,所以我試圖讓該應用程序升級後的應用程序可執行文件路徑並更新註冊表,以便在用戶重新啓動系統時啓動最新的應用程序。

升級後,我無法獲取安裝應用程序的路徑。它會在c \ document ... \ user中創建新文件夾....我知道。但是,需要獲取此路徑並更新註冊表。

任何人有任何指針?

+0

你是什麼意思重啓不起作用?怎麼了? – Daniel

回答

0

你可以嘗試重新啓動應用程序,像這樣:

Dim applicationEntryPoint = ApplicationDeployment.CurrentDeployment.UpdatedApplicationFullName 

Process.Start(applicationEntryPoint) 

// Call any code to shut down the current instance of the application here... 
+0

不,這也行不通。有什麼辦法可以獲得升級的可執行文件路徑嗎? – user2817774

+0

而不是保存應用程序可執行文件路徑,我保存路徑註冊表..這解決了我的問題。 Environment.GetFolderPath(Environment.SpecialFolder.Programs)+「\ Your publisher \ app_name.appref-ms」 – user2817774

0

我建議在某種把一個消息或在它調用Application.Restart,以確保它的真正叫它點跟蹤。如果您確認並且仍然無效,那麼您是否可能鎖定了某些內容,並且在關閉之前不會重新啓動?

0

這很可能是因爲您在ClickOnce部署的應用程序中使用了VB的本機單實例應用程序功能。該功能使用了引擎蓋下的Mutex,該應用程序不能及時發佈以重新啓動應用程序。因此,你看到的行爲 - 它不會重新啓動。

我剛纔也有同樣的問題。爲了解決這個問題,我不得不使用VB翻譯,並且稍微修改了我發現的技巧here。實質上,我們需要的是Mutex的共享實例和Application.Restart()上的3秒暫停,以便讓現有版本發佈其Mutex。不要忘記在項目的Property Pages的Application選項卡上UNCHECK '製作單實例應用程序'

enter image description here

這是我最後的代碼,如下。通過這種方式,我們可以擁有最好的世界 - 我們非常喜歡的VB漂亮的應用程序框架,單實例功能和ClickOnce API重新啓動。一次全部。我很頭暈。

帽子提示#1:到devzoo,他的CodeProject posting,展示了主要概念。

帽尖#2:要NullFX,他WinApi PostMessage() idea,如引述devzoo

帽尖#3:@ cmptrs4nowIsRestarting 3秒的停頓想法here

帽子提示#4:到@pstrjds他的澄清here。根據他的建議,我將Mutex.ReleaseMutex()更改爲Mutex.Close()。這看起來更安全。

HTH

Friend Class Main 
    Inherits System.Windows.Forms.Form 

    Protected Overrides Sub WndProc(ByRef Message As Message) 
    If Message.Msg = SingleInstance.WM_SHOWFIRSTINSTANCE Then 
     ShowWindow() 
    End If 
    MyBase.WndProc(Message) 
    End Sub 

    Private Sub ShowWindow() 
    Me.WindowState = FormWindowState.Normal 
    Me.Focus() 
    End Sub 

    Private Sub cmdUpdate_Click(Sender As Object, e As EventArgs) Handles cmdUpdate.Click 
    If ApplicationDeployment.IsNetworkDeployed Then 
     If ApplicationDeployment.CurrentDeployment.CheckForUpdate(False) 
     ApplicationDeployment.CurrentDeployment.Update() 

     MsgBox("The application has been updated and will now restart.", MsgBoxStyle.Information) 

     My.Settings.IsRestarting = True 
     My.Settings.Save() 

     Application.Restart() 
     End If 
    End If 
    End Sub 
End Class 

Namespace My 
    ' The following events are availble for MyApplication: 
    ' 
    ' Startup: Raised when the application starts, before the startup form is created. 
    ' Shutdown: Raised after all application forms are closed. This event is not raised if the application terminates abnormally. 
    ' UnhandledException: Raised if the application encounters an unhandled exception. 
    ' StartupNextInstance: Raised when launching a single-instance application and the application is already active. 
    ' NetworkAvailabilityChanged: Raised when the network connection is connected or disconnected. 
    Partial Friend Class MyApplication 
    Private Sub MyApplication_Startup(sender As Object, e As ApplicationServices.StartupEventArgs) Handles Me.Startup 
     If My.Settings.IsRestarting Then 
     My.Settings.IsRestarting = False 
     My.Settings.Save() 
     Thread.Sleep(3000) 
     End If 

     If Not SingleInstance.Start() Then 
     SingleInstance.ShowFirstInstance() 
     e.Cancel = True 
     End If 
    End Sub 

    Private Sub MyApplication_Shutdown(sender As Object, e As EventArgs) Handles Me.Shutdown 
     SingleInstance.Stop() 
    End Sub 
    End Class 
End Namespace 

Public NotInheritable Class SingleInstance 
    Public Shared ReadOnly WM_SHOWFIRSTINSTANCE As Integer = WinApi.RegisterWindowMessage("WM_SHOWFIRSTINSTANCE|{0}", ProgramInfo.AssemblyGuid) 
    Private Shared Mutex As Mutex 

    Public Shared Function Start() As Boolean 
    Dim lIsOnlyInstance As Boolean 
    Dim sMutexName As String 

    lIsOnlyInstance = False 
    sMutexName = String.Format("Local\{0}", ProgramInfo.AssemblyGuid) 

    ' If you want your app to be limited to a single instance 
    ' across ALL SESSIONS (multiple users & terminal services), 
    ' then use the following line instead: 
    ' sMutexName = String.Format("Global\\{0}", ProgramInfo.AssemblyGuid); 

    Mutex = New Mutex(True, sMutexName, lIsOnlyInstance) 
    Return lIsOnlyInstance 
    End Function 

    Public Shared Sub ShowFirstInstance() 
    WinApi.PostMessage(New IntPtr(WinApi.HWND_BROADCAST), WM_SHOWFIRSTINSTANCE, IntPtr.Zero, IntPtr.Zero) 
    End Sub 

    Public Shared Sub [Stop]() 
    Mutex.Close() 
    End Sub 
End Class 

Public NotInheritable Class WinApi 
    <DllImport("user32")> _ 
    Public Shared Function RegisterWindowMessage(message As String) As Integer 
    End Function 

    <DllImport("user32")> _ 
    Public Shared Function PostMessage(hwnd As IntPtr, msg As Integer, wparam As IntPtr, lparam As IntPtr) As Boolean 
    End Function 

    <DllImport("user32")> _ 
    Public Shared Function ShowWindow(hWnd As IntPtr, nCmdShow As Integer) As Boolean 
    End Function 

    <DllImport("user32")> _ 
    Public Shared Function SetForegroundWindow(hWnd As IntPtr) As Boolean 
    End Function 

    Public Shared Function RegisterWindowMessage(Template As String, ParamArray Values As Object()) As Integer 
    Return RegisterWindowMessage(String.Format(Template, Values)) 
    End Function 

    Public Shared Sub ShowToFront(Window As IntPtr) 
    ShowWindow(Window, SW_SHOWNORMAL) 
    SetForegroundWindow(Window) 
    End Sub 

    Public Const HWND_BROADCAST As Integer = &HFFFF 
    Public Const SW_SHOWNORMAL As Integer = 1 
End Class 

Public NotInheritable Class ProgramInfo 
    Public Shared ReadOnly Property AssemblyGuid As String 
    Get 
     Dim aAttributes As Object() 

     aAttributes = Assembly.GetEntryAssembly.GetCustomAttributes(GetType(GuidAttribute), False) 

     If aAttributes.Length = 0 Then 
     AssemblyGuid = String.Empty 
     Else 
     AssemblyGuid = DirectCast(aAttributes(0), GuidAttribute).Value 
     End If 
    End Get 
    End Property 
End Class 
相關問題