做这个小程序用了一天时间 ,做完之后,觉得自己真是应该好好重新审视一下写程序的日子,回想起来,这几年竟没有做好过一件事情,人生真的这么没有意义吗?
总体思路:
有了做个自动升级程序的想法之后,就先在网上找了一下,看到大侠们的思路基本上就是:主程序启动之前先启动另一
个程序与服务器连接,通过数据库或者某个文件中的信息来判断当前是否为新的版本.如果不是最新的就从服务器的目录中或者
从数据库中取得更新文件,然后把它们搞下来,覆盖掉原来的,然后再启动主程序.
我想先做个简单一点的试试,然后再进行扩展,于是就在服务器建了个表(id,path,flag) path用来存放最新版本在服
务器上的路径,当然这里一定要是个共享路径,这样直接拷就行了,flag用来记录用户端升级的情况,我没有用版本或者是文件更
新时间来判断是否新版本,我是用flag字段来判断的,如果某个用户升级成功,就记录下它的MAC地址,下次来的时候,如果已经有
了这个MAC地址,说明它已经升级了,就不用再升级.我想这样做能提供针对不同用户的不同版本程序的升级, 也能通过升级数据
记录来进行使用情况的统计等等.
设计过程:
要想正真在项目中应用,可不是这么简单的,我看网上大侠都是说用winsock来传送文件的,我是小虾,没见过大世面,就
先在服务器设个共享文件夹来试试程序流程吧.
于是就启动vb.net,拉开一个新窗体,在上面摆了一个Label,开始写拉.前面我觉得思路既然已经有了,也就没什么难度
吧,于是就没有怎么在乎乱写了一通代码,全写在了form_load里面,原来想当然的以为在form启动的时候就自动执行一段代码去
与服务器相连,然后进行升级等的操作,再在几个关键的点上改变那个LABEL控件的TEXT来提示用户后台进程就算了,可是全写完
了之后,调试,运行,那个form根本就没出来,(说实话我做了这么多年程序竞不知道form_load的真正用意,而且更可笑的是以前
从来没有碰上过这样的事,我真是白写了那么多代码了,程序做的这时,这已是满头大汗,我真是觉得自己这两年浪费了那么多时
间做程序....)
,我于是想到在FormLoad里边是加载窗体时进行的,等里边的代码全执行完成后才加载窗体,这样那不是写的代码也关
了程序了,窗体也加载完了,那当然看不到窗体拉,与是我加了个小按钮先试试,这回窗体 有拉,再点按钮,那个过程也执行过去
拉,可是怎么让程序在窗体启动之后自动执行一段代码呢?我想到了vb里头有个Timer控件,好像有这方面的功能, 于是找了一下
,发现竟是说如何用Timer每隔一段时间执行同一代码段的列子,(程序做到此时,我又上一头大汗,汗我做了这么多年程序竟不知
道怎么用一个小小的Timer控件来实现所需要的功能,)
于是回来自已找了几个Timer的属性,发现有个属性可以让它进行是否每隔一段时间做一件事或者是隔一段时间之后做
一次这样的事的选择,这不正是我要的吗?于是拉了个Timer控件进来,把它的启动放到formload里边,这样设置一番后,终于可以
在隔几秒后自动启动那段程序拉,(可是用这个Timer实现这个过程的时候老觉得有点别别扭扭的,我想软件水平已经发展到今天
这个地步拉,这Timer的功能也太别扭了吧,怎么让它在相同间隔的时间里执行不同的程序段呢?也许是我太笨了,可能很好实现
的,于是我又汗一次......)
直到这时发现那LABEl上的文字一直不变,直到启动了主程序之后,关闭本窗体,也没有变过,我以前在做BS程序时也碰
上过类似的问题,在做进度条时也有过,就是执行完了整段代码之后,各个窗体上的交互控件才会发生变化,比如你在读数据之前
让窗体上的LABEL内容改变,可实际的效果是读完数据之后程序段执行完后,LABEL才变拉.到这时候已经顾不得那么多拉,我随便
找了个社会窗体的me.update属性,就给放上去拉,发现有点变化可是还是太快了,一闪而过,于是上网上查,找了个SYStem.threa
ding.thread.sleep()挂起进程,一试还行,(....大侠您尽管骂我吧,我其实也很骂自已呢,像谐如此类的问题,做程序的人应该
很有经验的,可是我却不知道用什么样的方法解决来最好,...汗呀汗....就先用sleep吧先整个通过再说....)
于是加到各个关键点上,这次行拉,呵呵,我在别的机子上试一下,启动;正在检查更新;正在更新程序;程序更新完毕,正
在启动主程序;还算是附合刚开始的想法做完拉.
此时的我,已经彻底灰心了,就这么一段几行代码的小程序,却出现了这么多的问题,而我还本来想一下子搞定的,回过
头来想想我做程序员的经历,每每总是有了项目,拿过来就写,写完就改,改改就用,完了就再也不去想了.当初在学校里也就没怎
么完整地学过写程序,毕业之后,跟着人流晃来晃去,其实完全对程序是这儿看上点那儿用上点,把手头上的一做完,就以为自已
真的懂拉,其实都是皮毛,这么长时间积累了一堆皮毛下来,还是一张毛皮,想想自已从vb,asp,.net,c,sql,oracle,java ,也用
了不少,也看了不少,可还是没有真正懂得一点点程序,真是让我全身出汗....这都是怎么回事呀,我可怎么办呢?....
这个程序还有很多问题没有解决呢,如:不让用户直接启动主程序;用Winsock进行服务器与用户端文件传递,或者把文
件存到BLOB里边,通过数据库来下载;怎么更好的处理下载后的版本与原版本的更换?还有......;问题很多很多,我的头越来越
大,看着眼前的电脑,想想我的未来,我真的很渺茫.......,
代码:
Private Sub maindisplay_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Timer1.AutoReset = False
Timer1.Enabled = True
Timer1.Interval = 5000
End Sub
Public Sub updateV()
Dim newVer_Path As String
'MessageBox.Show("Application.UserAppDataPath " & Application.UserAppDataPath)
'MessageBox.Show("application.StartupPath " & Application.StartupPath)
'MessageBox.Show("Application.ProductName " & Application.ProductName)
'MessageBox.Show("application.ProductVersion " & Application.ProductVersion)
'MessageBox.Show("ldter路径:" & Application.StartupPath & "/../../ldter/bin/ldter.exe")
'=============检查是否有新版本,如数库设计方式 : sys_newUpdate中最大记录号所对应的版本号进行比较
'?????????????可否按局域网中客户机的IP 或 MAC 地址 作为更新标志?
'=========读取本机IP 或 MAC 地址 ==========
Dim Wmi As New System.Management.ManagementObjectSearcher("SELECT * FROM Win32_NetworkAdapterConfiguration")
Dim MACADDRESS As String
For Each WmiObj As ManagementObject In Wmi.Get
If CBool(WmiObj("IPEnabled")) Then
MACADDRESS = "(" & WmiObj("MACAddress") & ")"
'MessageBox.Show("IP(" & WmiObj("IPAddress")(0) & ")|MAC(" & WmiObj("MACAddress") & ")" & vbCrLf)
End If
Next
'==========================================
Dim conn As OracleConnection
Dim cm As OracleCommand
Dim reader As OracleDataReader
conn = New OracleConnection(global.getOdbserver())
cm = New OracleCommand("SELECT * FROM SYS_NEWUPDATE A WHERE SYS_NU_ID IN (SELECT MAX(SYS_NU_ID) FROM SYS_NEWUPDATE B )", conn)
conn.Open()
Try
reader = cm.ExecuteReader
While reader.Read
Dim flag As String
'flag = IIf(reader.Item("SYS_NU_FLAG") Is Nothing, "HH", reader.Item("SYS_NU_FLAG").ToString)
flag = reader.Item("SYS_NU_FLAG").ToString
If InStr(flag, MACADDRESS) = 0 Then
'最新版程序未在本机上更,copy最新exe 'copy ,delete ,rename EXE文件
'正在更新程序......
Label1.Text = "找到新版本,正在更新程序......"
Me.Update()
System.Threading.Thread.Sleep(3000)
newVer_Path = Trim(reader.Item("SYS_NU_PATH").ToString)
If changeIt(newVer_Path) Then
'签名本地信息
'Dim SQLSTR As StringBuilder = New StringBuilder
'SQLSTR.AppendFormat("UPDATE SYS_NEWUPDATE SET SYS_NU_FLAG:=SYS_NU_FLAG||'{0}' WHERE SYS_NU_ID IN (SELECT MAX(SYS_NU_ID) FROM SYS_NEWUPDATE B ) ", ":MACADDYSL")
'cm = New OracleCommand(SQLSTR.ToString, conn)
cm = New OracleCommand("UPDATE SYS_NEWUPDATE SET SYS_NU_FLAG=SYS_NU_FLAG||'" & MACADDRESS & "' WHERE SYS_NU_ID IN (SELECT MAX(SYS_NU_ID) FROM SYS_NEWUPDATE B ) ", conn)
'cm.Parameters.Add(":MACADDYSL", System.Data.OracleClient.OracleType.VarChar, Len(MACADDRESS)).Value = MACADDRESS
If Not conn.State = ConnectionState.Open Then
conn.Open()
End If
cm.ExecuteNonQuery()
conn.Close()
'已经升级到最新版本,正在启动程序......
Label1.Text = "已经升级到最新版本,正在启动程序......"
Me.Update()
System.Threading.Thread.Sleep(5000)
Shell(Application.StartupPath & "/ldter.exe")
Exit While
Else
'升级失败,请与管理员联系。正在启动程序......
Label1.Text = "升级失败,正在启动旧版本程序......"
Me.Update()
System.Threading.Thread.Sleep(5000)
Shell(Application.StartupPath & "/ldter.exe")
Exit While
End If
Else
'现有版本无需升级,正在启动程序......
Label1.Text = "您已经是最新版本,正在启动程序......"
Me.Update()
System.Threading.Thread.Sleep(2000)
Shell(Application.StartupPath & "/ldter.exe")
Exit While
End If
End While
Catch ex As Exception
Label1.ForeColor = System.Drawing.Color.Red
Label1.Text = "警告:程序无法启动,请与系统管理员联系。"
Me.Update()
System.Threading.Thread.Sleep(5000)
Finally
conn.Close()
Application.Exit()
End Try
End Sub
Private Function changeIt(ByVal sPath As String) As Boolean
Dim fl As File
Dim nfilename As String
'先删除,再复制
Try
fl.Delete(Application.StartupPath & "/" & "ldter.exe")
nfilename = "ldter.exe" '先复制,现删除,再重命名 "ldter_update_tempfile.ysl"
fl.Copy(sPath, Application.StartupPath & "/" & nfilename)
Catch ex As Exception
'MessageBox.Show(ex.Message)
Return False
End Try
Return True
End Function
Private Sub Timer1_Elapsed(ByVal sender As System.Object, ByVal e As System.Timers.ElapsedEventArgs) Handles Timer1.Elapsed
updateV()
End Sub