升级完成后 Clickonce 应用程序不会重新启动

2024-01-25

我在用应用部署 http://msdn.microsoft.com/en-us/library/system.deployment.application.applicationdeployment.aspx类检查升级是否可用,然后升级应用程序,如下所示

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

有人有任何指点吗?


这可能是因为您在 ClickOnce 部署的应用程序中使用 VB 的本机单实例应用程序功能。该功能使用Mutex在后台,它没有及时发布以供应用程序重新启动。因此,您所看到的行为 - 它不会重新启动。

我刚才也遇到了同样的问题。为了解决这个问题,我必须使用 VB 翻译并对我发现的技巧进行轻微修改here http://www.codeproject.com/Articles/32908/。本质上我们需要的是一个共享实例Mutex并暂停 3 秒Application.Restart()给现有版本时间来发布其Mutex。不要忘记取消选中“制作单实例应用程序”在项目属性页的“应用程序”选项卡上。

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

帽子提示#1:devzoo,对于他的代码项目发布 http://www.codeproject.com/Articles/32908/,展示主要概念。

帽子提示#2:NullFX,对于他的WinApi PostMessage() 的想法 http://sanity-free.org/143/csharp_dotnet_single_instance_application.html,正如引用的devzoo.

帽子提示#3:@cmptrs4now为了他的IsRestarting3秒暂停的想法here https://stackoverflow.com/questions/95098/.

帽子提示#4:@pstrjds为了他的澄清here https://stackoverflow.com/questions/7519465/net-mutext-releasemutex-and-mutex-close。根据他的建议我改变了Mutex.ReleaseMutex() to 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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

升级完成后 Clickonce 应用程序不会重新启动 的相关文章

  • 命令式代码与声明式代码[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我试图理解命令式范例和声明式范例之间的区别 因为我必须对 Visual Basic 进行分类 NET 在不同的范式中 除了面向对象之外
  • 如何在.NET 中编写安全/正确的多线程代码?

    今天我必须修复一些使用线程的旧 VB NET 1 0 代码 问题在于从工作线程而不是 UI 线程更新 UI 元素 我花了一些时间才发现可以使用 InvokeRequired 断言来查找问题 除了上面提到的并发修改问题之外 还可能遇到死锁 竞
  • .NET 图形重影

    我正在为我们正在开发的新应用程序制作一个示例 GUI 我已经决定了语言 但我可以使用任何第 3 方 DLL 或插件或任何我需要的东西 以使 GUI 尽可能无缝地工作 他们希望它非常像 mac ubuntu vista Windows 7 所
  • 从空白启动时 VSTO 功能区不显示解决方案

    如果我从 文件 新建项目 菜单创建一个新的 Excel 2013 和 2016 VSTO 加载项 项目 然后单击 项目 添加新项目 gt 功能区 可视化设计器 则一切正常 我启动了应用程序 我的功能区显示在 Excel 中 但是 如果我首先
  • 父窗体中的居中消息框[重复]

    这个问题在这里已经有答案了 有没有一种简单的方法可以在 net 2 0中将MessageBox居中于父窗体中 我在 C 中确实需要这个并发现中心消息框 C http bytes com topic c sharp answers 26712
  • 将字符串转换为双精度 - VB

    VB中有没有一种有效的方法来检查字符串是否可以转换为双精度型 我目前正在尝试将字符串转换为双精度型 然后查看它是否引发异常 但这似乎减慢了我的申请速度 Try if number then format it current CDbl x
  • 如何四舍五入到一半,始终为正方向? [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 如何实现以下舍入 0 0126083
  • 设置表单的背景颜色

    Private Sub HScrollBar1 Scroll ByVal sender As Object ByVal e As ScrollEventArgs Handles HScrollBar1 Scroll Me BackColor
  • 插入具有只读主键列的表

    我正在使用一个使用 sql server 数据库的应用程序 我试图在表中插入一行 如下所示 该表有一个主键 prodNum 这是自动生成的密钥 当我尝试向表中插入一行时 如下所示 在行中intResult oSglProdTableAdap
  • 变量替换为字符串

    我可以做类似的事情吗 s said s blah name blah 在 VB NET 中 写字越来越痛苦name said blah blah 在VB NET 14 对于VS2015 中 您可以使用字符串插值 https msdn mic
  • 如何判断计算机是否已重新启动?

    我曾经使用过一个命令行 SMTP 邮件程序 作为试用版的限制 它允许您在每个 Windows 会话中最多接收 10 封电子邮件 如果您重新启动计算机 您可能还会收到 10 个以上 我认为这种共享软件破坏非常巧妙 我想在我的应用程序中复制它
  • 选项卡索引不适用于面板中的控件?

    我有一个 vb net Windows 窗体 其中包含大约 15 个组合框和 15 个文本框 以及其他几个控件 所有这些TextBoxes and ComboBoxes位于面板中 原因是我需要根据用户选择 输入的内容来调整控件的可见属性 因
  • 使用 JSON.net 反序列化

    我对 json JSON net 等都很陌生 在这里阅读类似的问题后 我无法让我的代码工作 我的错误到底是什么 我监督了什么 出于测试目的是否可以跳过 链接 和 元 类 或者我是否必须定义每个属性 我得到以下 REST 输出 codes h
  • 当用户尝试打开新实例时返回到已打开的应用程序

    这是我有一段时间想不通的问题 防止第二个实例很简单并且有很多方法 但是恢复已经运行的进程则不然 我想 最小化 撤消最小化并将正在运行的实例置于最前面 在其他窗口后面 将应用程序置于最前面 我使用的语言是 VB NET 和 C 我发现这段代码
  • 如何检查主音量是否静音

    如何在 Windows 7 操作系统中检查主音量是否静音我有静音或取消静音的代码 IE Public Const APPCOMMAND VOLUME MUTE As Integer H80000 Public Const APPCOMMAN
  • 将日期时间转换为指定格式

    我有这个日期格式yy MM dd HH mm ss ex 12 02 21 10 56 09 问题是 当我尝试使用以下代码将其转换为不同格式时 CDate 12 02 21 10 56 09 ToString MMM dd yyyy HH
  • 需要将用户名和密码添加到 VB.NET Web 服务客户端中的 SOAP 标头

    我需要查询一个进行基本身份验证的 Web 服务 将用户名和密码放在请求标头中 我的客户端是用 VB NET Visual Basic Express Edition 2010 编写的 我已将 Web 服务添加到服务引用中 它为我自动生成了合
  • VB无法访问不同项目中的类,相同的解决方案

    我正在使用 VB for Visual Studio 工作 并且项目中有一个类需要将变量声明为另一个项目中的类 对于可视化 解决方案 A 包含 Project1 和 Project2 在 Project1 的类中 我需要声明一个变量作为 P
  • ODP.Net - OracleDataReader.读取速度非常慢

    我在 ODP Net 中的 OracleDataReader 方面遇到很多麻烦 基本上 我有一个参数化查询 需要 1 5 秒的时间来运行 返回大约 450 条记录 然后需要 60 90 秒的时间来循环 甚至没有代码在循环中运行 实际上是迭代
  • 非 Web 项目的 XML 序列化程序集

    我正在尝试解决 VS 2010 VB NET 和 C 中自动生成序列化程序集的众所周知的问题 项目设置中的 生成序列化程序集 选项对于非 Web 项目没有任何作用 请参阅http blog devstone com aaron archiv

随机推荐