升级完成后 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 应用程序不会重新启动 的相关文章

  • 带分页的自定义数据表

    我正在使用我的自定义DataTable as a DataSource to my ListView 现在 我面临的问题是Paging不管用 我想做的是当我点击页面时1 2等等 我应该一次只能获取 10 行 我的意思是 当页面加载时 我只想
  • vb.net中如何读取串口数据?

    我创建了一个类 有一个名为 SendUSSD 的子类 当调用它时 它会向连接 gsm 手机的 COM 端口发送一个 ussd 代码 如 123 此 usd 应该返回移动余额 If IsOpen True Then checks if the
  • 自动加载 linq2entities 中的关系

    当我的模型中的两个实体之间存在关系时 组成员 1 用户 并尝试使用 LINQ 从该关系中选择项目 从 user GroupMember 中的实体选择实体 除非我首先使用以下语句加载关系 否则我总是得到空结果 user GroupMember
  • VB.NET 空合并运算符? [复制]

    这个问题在这里已经有答案了 可能的重复 VB NET 中的合并运算符和条件运算符 https stackoverflow com questions 629036 coalesce operator and conditional oper
  • 如何正确发布我的应用程序?

    我正在使用 Visual Studio 创建我的第一个 Windows 桌面 c wpf 应用程序 我正处于想要发布 部署 构建它的阶段 在 Visual Studio Express 2013 中 我右键单击我的项目并单击 发布 单击 下
  • 写入 SQL 时遇到问题

    我已经用 VB Net 编写了几个月了 并且在我的代码中成功地使用了 SQL 命令很多次 但是在写入数据库中的一个特定表时遇到了问题 我相信问题在于我有一个正在尝试写入的数字列 我得出这个结论是因为它是我不经常使用的唯一一个 并且我的代码不
  • VB换行转义字符?

    在C中我使用 1st line 1 n2nd line 对于换行符 但是 VB 呢 我知道 1st line VbCrLf 2nd line 但它太冗长了 VB中换行符的转义字符是什么 我要打印 1st line 2nd line 我尝试使
  • 中继器按钮命令参数为空字符串

    我对这个失去了理智 即使命令参数已设置 我的按钮也会获得空字符串的命令参数 我已经验证它在调试模式下设置为正确的 ID 但是当我稍后在中继器 ItemCommand 事件中访问此命令参数时 命令参数是空字符串 我不知道为什么 我最终得到了
  • 如何将外部文件添加到应用程序文件(clickonce / .NET)

    我在用着 发布 vs2008 中的选项 我很高兴它的工作原理 现在我想添加 2 个外部 exe 文件到已安装的包中我注意到按钮 应用程序文件 在发布选项卡上 但似乎不允许手动添加新文件 我已经玩过这个并找到了存档的方法 1 将EXE文件作为
  • 将网格视图列的宽度设置为动态,而不影响控件的最小宽度

    我在用着
  • 在本地安全存储用于 Web 服务的密码

    我有一个应用程序 通过发送用户名和密码来对第三方 Web 服务进行身份验证 目前 我每次启动应用程序时都会在 winform 上输入密码 但我需要它自动登录 我想比更安全地存储用户名 密码 Dim username as String us
  • 模式弹出窗口上的按钮单击事件,在网格视图内未触发

    我遇到以下问题 场景 我有一个 asp 网格 其中有一些绑定到数据的列 最后一列已转换为模板字段 在这个模板字段中有一个按钮 上面附加了一个模式弹出扩展器 该字段中隐藏着一个模式弹出窗口 此模式弹出窗口用于添加新帐户 它包含 2 个文本框
  • Datagridview 单元格焦点

    我有一个从数据库加载数据的数据网格视图 这是未绑定的 datagridview 这些列是描述 价格 数量和总计 说明 U价格来自数据库 然后输入数量 我希望这样当我的数据网格加载时 光标会转到 数量 列 并且它会像我们在文本框中那样闪烁显示
  • 无法使用 dataformatstring 格式化日期时间

    由于某种原因 我无法在网格视图中格式化日期文本
  • XAML解析异常

    我有一个简单的 XAML 页面 当它作为 Visual Studio 中任何应用程序的一部分加载时 加载效果良好 但是 当我使用 ClickOnce 部署此应用程序时 出现以下异常 Type System Windows Markup Xa
  • VB - 如何读取和写入二进制文件?

    如何从任何文件读取原始字节数组 Dim bytes as Byte 然后将该字节数组写回到新文件中 我需要它作为字节数组来在两者之间进行一些处理 我目前正在使用 To read Dim fInfo As New FileInfo dataP
  • 在 Google Colab 中重新启动内核

    我正在尝试通过单元重新启动 Google Colab Jupyter Notebook 中的内核 前面给出的选项 import os os exit 00 没问题 但在我看来 这不是一种非常 Pythonic 的重新启动内核的方式 另一种选
  • 将 PDF 嵌入到 WPF 应用程序中

    我正在尝试在 WPF 应用程序中嵌入 显示 PDF 到目前为止 我已经尝试过这些解决方案 但没有成功 在 a 中显示 PDFWindowsFormsHost主持一个AxAcroPdf控制 类似于显示的内容here http hugeonio
  • C# 的最佳替代“错误继续下一步”是什么?

    如果我为 C 代码放置空的 catch 块 它是否与 VB NET 的 On Error Resume Next 语句等效 try C code catch exception 我问这个问题的原因是因为我必须将 VB NET 代码转换为 C
  • 使一个对象只能被同一程序集中的另一个对象访问?

    每个业务对象都有一个包含 sql 调用的匹配对象 我想限制这些 sql 对象 使其只能由匹配的业务对象使用 如何才能实现这一目标 Update 格雷格提出了关于可测试性的观点 由于 SqlObjects 将包含非常特定于业务流程的 sql

随机推荐