0

我正在使用AppplicationDeployment类来检查升级是否可用,然后像下面这样升级应用程序

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.... 中创建新文件夹。我知道。但是,需要获取此路径并更新注册表。

有人有任何指示吗?

4

3 回答 3

1

这可能是因为您在 ClickOnce 部署的应用程序中使用了 VB 的本机单实例应用程序功能。该功能使用Mutex引擎盖下的 a,它不会及时发布以使应用程序重新启动。因此,您看到的行为 - 它不会重新启动。

我刚才也有同样的问题。为了修复它,我不得不使用 VB 翻译并对我在这里找到的技巧进行轻微修改。本质上,我们需要的是一个共享实例Mutex并暂停 3 秒,Application.Restart()以便为现有版本提供时间来发布其Mutex. 不要忘记在项目属性页的应用程序选项卡上取消选中“制作单实例应用程序” 。

在此处输入图像描述

这是我最终得到的代码,如下所示。这样我们就可以拥有世界上最好的——我们非常喜欢的 VB 漂亮的应用程序框架、单实例功能和 ClickOnce API 重新启动。一次全部。我晕了

帽子提示 #1:致devzoo,为他的CodeProject 发帖,展示主要概念。

帽子提示 #2:致NullFX,感谢devzoo引用的WinApi PostMessage() 想法

帽子提示 #3:致@cmptrs4now在这里提出他的IsRestarting3 秒暂停想法。

帽子提示#4:致@pstrjds在这里澄清。根据他的建议,我改为Mutex.ReleaseMutex()下面Mutex.Close()。这看起来更安全。

高温高压

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
于 2014-03-24T08:37:22.337 回答
0

I recommend putting in some kind a messagebox or tracing at the point where it calls Application.Restart to make sure it's really calling it. If you verify that, and it still doesn't work, then could you possibly have something locked and it won't restart until it's closed?

于 2013-10-18T18:23:23.230 回答
0

您可以尝试像这样重新启动应用程序:

Dim applicationEntryPoint = ApplicationDeployment.CurrentDeployment.UpdatedApplicationFullName

Process.Start(applicationEntryPoint)

// Call any code to shut down the current instance of the application here...
于 2013-10-14T19:14:53.687 回答