這可以使用ClickOnce來完成,但可能不會達到您想要的程度。
看看這個類
Imports System.Deployment.Application
Imports System.ComponentModel
Public Class UpdateChecker
Public Enum UpdateType
Automatic
Manual
End Enum
Private Shared MyInstance As UpdateChecker
Public Shared ReadOnly Property Current() As UpdateChecker
Get
If MyInstance Is Nothing Then
MyInstance = New UpdateChecker
End If
Return MyInstance
End Get
End Property
Private WithEvents CurrDeployment As ApplicationDeployment
Private CurrType As UpdateType
Private _checking As Boolean = False
Private _lastErrorSentOnCheck As DateTime?
Public ReadOnly Property LastUpdateCheck() As DateTime?
Get
If CurrDeployment IsNot Nothing Then
Return CurrDeployment.TimeOfLastUpdateCheck
End If
Return Nothing
End Get
End Property
Public Sub CheckAsync(ByVal checkType As UpdateType)
Try
Dim show As Boolean = (checkType = UpdateType.Manual)
If ApplicationDeployment.IsNetworkDeployed AndAlso _
Not WindowActive(show) AndAlso Not _checking AndAlso _
(checkType = UpdateType.Manual OrElse Not LastUpdateCheck.HasValue OrElse LastUpdateCheck.Value.AddMinutes(60) <= Date.UtcNow) Then
_checking = True
CurrDeployment = ApplicationDeployment.CurrentDeployment
CurrType = checkType
Dim bw As New BackgroundWorker
AddHandler bw.RunWorkerCompleted, AddressOf CurrDeployment_CheckForUpdateCompleted
AddHandler bw.DoWork, AddressOf StartAsync
If CurrType = UpdateType.Manual Then ShowWindow()
bw.RunWorkerAsync()
ElseIf checkType = UpdateType.Manual AndAlso _checking Then
CurrType = checkType
WindowActive(True)
ElseIf checkType = UpdateType.Manual AndAlso Not ApplicationDeployment.IsNetworkDeployed Then
MessageBox.Show(MainForm, "Cannot check for updates.", "Update", MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
Catch ex As Exception
If Not _lastErrorSentOnCheck.HasValue OrElse _lastErrorSentOnCheck.Value.AddHours(1) <= Now Then
_lastErrorSentOnCheck = Now
My.Application.LogError(ex, New StringPair("Update Check", checkType.ToString))
End If
End Try
End Sub
Private Sub StartAsync(ByVal sender As Object, ByVal e As DoWorkEventArgs)
e.Result = CurrDeployment.CheckForDetailedUpdate
End Sub
Private Sub ShowWindow()
My.Forms.frmUpdates.MdiParent = MainForm
AddHandler My.Forms.frmUpdates.FormClosing, AddressOf frmUpdates_FormClosing
My.Forms.frmUpdates.Show()
End Sub
Protected Sub frmUpdates_FormClosing(ByVal sender As Object, ByVal e As Windows.Forms.FormClosingEventArgs)
My.Forms.frmUpdates = Nothing
End Sub
Private Function WindowActive(ByVal onTop As Boolean) As Boolean
If Not My.Forms.frmUpdates Is Nothing Then
If Not My.Forms.frmUpdates.Visible AndAlso onTop Then
My.Forms.frmUpdates.MdiParent = MainForm
My.Forms.frmUpdates.Show()
ElseIf onTop Then
My.Forms.frmUpdates.Activate()
End If
Return True
End If
Return False
End Function
Private Sub CurrDeployment_CheckForUpdateCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs)
If MainForm.InvokeRequired Then
MainForm.Invoke(New RunWorkerCompletedEventHandler(AddressOf CurrDeployment_CheckForUpdateCompleted), sender, e)
Else
If e.Error IsNot Nothing Then
If WindowActive(True) Then My.Forms.frmUpdates.ShowError("Please try again later.")
If Not _lastErrorSentOnCheck.HasValue OrElse _lastErrorSentOnCheck.Value.AddHours(1) <= Now Then
_lastErrorSentOnCheck = Now
My.Application.LogError(e.Error, New StringPair("Update Check Async", CurrType.ToString))
End If
Else
Dim updateInfo As UpdateCheckInfo = DirectCast(e.Result, UpdateCheckInfo)
Select Case CurrType
Case UpdateType.Manual
If WindowActive(False) Then My.Forms.frmUpdates.ShowCheckComplete(updateInfo)
Case UpdateType.Automatic
If updateInfo.UpdateAvailable Then
If Not WindowActive(True) Then ShowWindow()
My.Forms.frmUpdates.ShowCheckComplete(updateInfo)
End If
End Select
End If
_checking = False
End If
DirectCast(sender, BackgroundWorker).Dispose()
End Sub
Public Sub UpdateAsync()
If ApplicationDeployment.IsNetworkDeployed Then
CurrDeployment = ApplicationDeployment.CurrentDeployment
Dim bw As New BackgroundWorker
AddHandler bw.RunWorkerCompleted, AddressOf CurrDeployment_UpdateCompleted
AddHandler bw.DoWork, AddressOf StartUpdateAsync
My.Forms.frmUpdates.ShowUpdateStart()
bw.RunWorkerAsync()
End If
End Sub
Public Sub StartUpdateAsync()
CurrDeployment.Update()
End Sub
Private Sub CurrDeployment_UpdateCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs) Handles CurrDeployment.UpdateCompleted
If MainForm.InvokeRequired Then
MainForm.Invoke(New AsyncCompletedEventHandler(AddressOf CurrDeployment_UpdateCompleted), sender, e)
Else
If e.Error IsNot Nothing Then
If WindowActive(True) Then My.Forms.frmUpdates.ShowError("Please try again later or close and re-open the application to automatically retrieve updates.")
My.Application.LogError(e.Error, New StringPair("Update Async", CurrType.ToString))
Else
If WindowActive(True) Then My.Forms.frmUpdates.ShowUpdateComplete()
End If
End If
End Sub
End Class
下面的代碼是否需要新的更新檢查。你會在計時器上運行此,也許每5分鐘
UpdateChecker.Current.CheckAsync(UpdateChecker.UpdateType.Automatic)
那麼這裏下載更新的代碼。
UpdateChecker.Current.UpdateAsync()
用戶將必須退出並啓動應用程序,以獲得新的版本或 更新完成後,你也可以使用Application.Restart重新啓動應用程序
這不會更新時後程序沒有運行,但通過ClickOnce,您可以在程序啓動時檢查更新。
不要忘記保護Web服務和更新包。在互聯網上自動執行不受信任的代碼,特別是作爲特權服務運行時,這是非常不好的事情。 – ChrisV 2011-01-21 19:30:10
由於ChrisV說,這是一個好主意。您可以使用updrader spawned進程來停止並恢復服務控制管理器的服務。 – 2011-01-21 19:43:39
'分叉'過程可能是最好的另一個Windows服務。這個Windows服務可能負責啓動/停止並檢查更新。這是病毒檢查程序(如Norton Anti Virus)如何與Live Update服務配合使用。在UNIX中,確實很容易,因爲分支子進程的機制已經存在很長時間了。就像我之前所說的那樣,有兩個服務在責任清晰分離的情況下運行,使得updater服務成爲可用於其他服務的可重用代碼,因爲它不具有依賴關係。 – CodeMonkeyKing 2011-01-31 21:59:24