PB实现自动更新客户端文件

C/S相较B/S结构的缺点是客户端文件更新比较烦琐,现用PB12.5实现客户端文件自动更新。

基本思路是:先将需要更新的文件上传到服务器数据库,文件最后修改时间存入字段[UpTime];客户端扫描数据库如果发现文件修改日期晚于本地文件的修改日期则下载更新该文件。

例程下载:https://download.csdn.net/download/nhwatertao/11807209

-- 数据库存储文件的表T_appdata
CREATE TABLE [dbo].[T_appdata](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [app] [varchar](50) NULL,
    [FileName] [varchar](100) NULL,
    [UpTime] [smalldatetime] NULL,
    [Uppsn] [varchar](50) NULL,
    [FileData] [image] NULL,
    [FileBytes] [int] NULL);

申明win32 API读取/设置文件日期函数,有关功能封装在自定对象中n_cst_filetime(附:n_cst_filetime.sru)。

$PBExportHeader$n_cst_filetime.sru
$PBExportComments$与文件时间有关的外部函数
forward
global type n_cst_filetime from nonvisualobject
end type
type os_filedatetime from structure within n_cst_filetime
end type
type os_fileopeninfo from structure within n_cst_filetime
end type
type os_finddata from structure within n_cst_filetime
end type
type os_securityattributes from structure within n_cst_filetime
end type
type os_systemtime from structure within n_cst_filetime
end type
end forward

type os_filedatetime from structure 
    unsignedlong        ul_lowdatetime 
    unsignedlong        ul_highdatetime 
end type 

type os_fileopeninfo from structure 
    character        c_length 
    character        c_fixed_disk 
    unsignedinteger        ui_dos_error 
    unsignedinteger        ui_na1 
    unsignedinteger        ui_na2 
    character        c_pathname[128] 
end type 

type os_finddata from structure 
    unsignedlong        ul_fileattributes 
    os_filedatetime        str_creationtime 
    os_filedatetime        str_lastaccesstime 
    os_filedatetime        str_lastwritetime 
    unsignedlong        ul_filesizehigh 
    unsignedlong        ul_filesizelow 
    unsignedlong        ul_reserved0 
    unsignedlong        ul_reserved1 
    character        ch_filename[260] 
    character        ch_alternatefilename[14] 
end type 

type os_securityattributes from structure 
    unsignedlong        ul_length 
    string        ch_description 
    boolean        b_inherit 
end type 

type os_systemtime from structure 
    unsignedinteger        ui_wyear 
    unsignedinteger        ui_wmonth 
    unsignedinteger        ui_wdayofweek 
    unsignedinteger        ui_wday 
    unsignedinteger        ui_whour 
    unsignedinteger        ui_wminute 
    unsignedinteger        ui_wsecond 
    unsignedinteger        ui_wmilliseconds 
end type 

global type n_cst_filetime from nonvisualobject autoinstantiate
end type

type prototypes
//  打开文件,返回文件句柄 =0失败
FUNCTION ulong CreateFile(ref string lpFileName, long dwDesiredAccess, long dwShareMode, long lpSecurityAttr, long dwCreationDisposition, long dwFlagsAndAttributes, long hTemplateFile) LIBRARY "kernel32.dll" ALIAS FOR "CreateFileA;ANSI"
FUNCTION boolean CloseHandle(long file_hand) LIBRARY "kernel32.dll" 

Function ulong GetFileTime(long hFile, ref os_filedatetime  lpCreationTime, ref os_filedatetime  lpLastAccessTime, ref os_filedatetime  lpLastWriteTime  )  library "kernel32.dll" 
Function ulong SetFileTime(long hFile, ref os_filedatetime  lpCreationTime, ref os_filedatetime  lpLastAccessTime, ref os_filedatetime  lpLastWriteTime  )  library "kernel32.dll" 

Function boolean FileTimeToSystemTime(ref os_filedatetime lpFileTime, ref os_systemtime lpSystemTime) library "kernel32.dll" 
Function boolean SystemTimeToFileTime(os_systemtime lpSystemTime, ref os_filedatetime lpFileTime) library "kernel32.dll" 
Function boolean FileTimeToLocalFileTime(ref os_filedatetime lpFileTime, ref os_filedatetime lpLocalFileTime) library "kernel32.dll" 
Function boolean LocalFileTimeToFileTime(ref os_filedatetime lpLocalFileTime, ref os_filedatetime lpFileTime) library "kernel32.dll" 

//  文件操作根据文件名查找文件。 
Function long    FindFirstFileA (ref string filename, ref os_finddata findfiledata) library "kernel32.dll" ALIAS FOR "FindFirstFileA;ANSI"
Function boolean FindNextFileA (long handle, ref os_finddata findfiledata) library "kernel32.dll" 
Function boolean FindClose (long handle) library "kernel32.dll" 
//Function long    OpenFile (ref string filename, ref os_fileopeninfo of_struct, ulong action) LIBRARY "kernel32.dll" 


//  取硬盘序列号 of_GetVolumeSerialNumber()
Function boolean GetVolumeInformationA(ref String ls_Rootpath, ref String ls_volumnename, Ulong lul_VolumeNameSize, ref Ulong lul_VolumeSerialNumber,&
   ref Ulong lul_MaximumComponentLength, ref Ulong lul_FileSystemFlags, ref String ls_FileSystemNameBuffer,Ulong lul_FileSystemNameSize) &
   Library "Kernel32.dll" Alias for "GetVolumeInformationA;ansi"
//  取计算机名	of_GetComputerName()
Function boolean GetComputerNameA(ref string cname,ref long nbuf) Library "kernel32.dll" ALIAS FOR "GetComputerNameA;ANSI"



end prototypes

type variables
PROTECTED: 
//  CreateFile()
CONSTANT Long GENERIC_READ = 2147483648 
CONSTANT Long GENERIC_WRITE= 1073741824
CONSTANT Long OPEN_EXISTING =3
CONSTANT Long FILE_SHARE_READ =1
CONSTANT Long FILE_SHARE_WRITE =2

end variables
forward prototypes
public function integer of_getcreatedatetime (string as_filename, ref datetime adt)
public function integer of_getlastwritedatetime (string as_filename, ref datetime adt)
public function integer of_setlastwritedatetime (string as_filename, datetime adt)
private function integer of_convertfiledatetimetopb (os_filedatetime astr_filetime, ref datetime adt)
private function integer of_convertpbdatetimetofile (datetime adt, ref os_filedatetime astr_filetime)
public function string of_getvolumeserialnumber ()
public function string of_getcomputername ()
public function integer of__setfiletime (string as_filename, datetime adt)
end prototypes

public function integer of_getcreatedatetime (string as_filename, ref datetime adt);// of_GetCreateDatetime( string as_filename, ref datetime)
//	得到文件创建的时间 
long   ll_handle 
os_finddata    lstr_FindData 
 
// Get the file information 
ll_handle = FindFirstFileA(as_FileName, lstr_FindData) 
If ll_handle <= 0 Then Return -1 
FindClose(ll_handle) 
 
// Convert the date and time 
Return of_ConvertFileDatetimeToPB(lstr_FindData.str_CreationTime, adt) 

end function

public function integer of_getlastwritedatetime (string as_filename, ref datetime adt);// of_GetLastwriteDatetime( string as_filename, ref datetime)
//	得到文件最后修改的时间 
long   ll_handle 
os_finddata    lstr_FindData 
 
// Get the file information 
ll_handle = FindFirstFileA(as_FileName, lstr_FindData) 
If ll_handle <= 0 Then Return -1 
FindClose(ll_handle) 
 
// Convert the date and time 
Return of_ConvertFileDatetimeToPB(lstr_FindData.str_LastWriteTime, adt) 

end function

public function integer of_setlastwritedatetime (string as_filename, datetime adt);//  ====================================================================
//  Event/Fun:   of_setlastwritedatetime(string as_filename,datetime adt)  
//  Returns:     integer 1:OK ; <0:error 
//  Description: 修改文件时间
//  --------------------------------------------------------------------
//  Copyright (c) 2018-2025 GuangZhou Software Co.Ltd(TM), All rights reserved.
//  --------------------------------------------------------------------
//  Written in: 2018-9-20
//  Modified in:
//  ====================================================================

ulong ll_hFile 
os_filedatetime los_LastWriteTime, los_empty

of_ConvertPBDatetimeToFile(adt, los_LastWriteTime)
//写方式打开文件 
ll_hFile = CreateFile(as_filename,GENERIC_WRITE,FILE_SHARE_WRITE,0,OPEN_EXISTING,0,0)
//写文件时间
if SetFileTime(ll_hFile,los_empty, los_empty, los_LastWriteTime)=0 then
	CloseHandle(ll_hFile)
	Return -1
end if
CloseHandle(ll_hFile)
Return 1


end function

private function integer of_convertfiledatetimetopb (os_filedatetime astr_filetime, ref datetime adt);//转换文件系统时间为PB时间
//of_convertfiledatetimetopb(os_filedatetime astr_filetime, ref datetime adt)
os_filedatetime  lstr_LocalTime 
os_systemtime    lstr_SystemTime 
 
If Not FileTimeToLocalFileTime(astr_FileTime, lstr_LocalTime) Then Return -1 
If Not FileTimeToSystemTime(lstr_LocalTime, lstr_SystemTime) Then Return -1 
 
adt = datetime(blob(String(lstr_SystemTime.ui_wyear) + "-" + & 
                    String(lstr_SystemTime.ui_WMonth) + "-" + & 
                    String(lstr_SystemTime.ui_WDay) + ' ' + & 
                    String(lstr_SystemTime.ui_wHour) + ":" + & 
                    String(lstr_SystemTime.ui_wMinute) + ":" + & 
                    String(lstr_SystemTime.ui_wSecond) + ":" + & 
                    String(lstr_SystemTime.ui_wMilliseconds) ) ) 
Return 1 

end function

private function integer of_convertpbdatetimetofile (datetime adt, ref os_filedatetime astr_filetime);//转换PB时间为文件系统时间 
os_filedatetime  lstr_LocalTime 
os_systemtime    lstr_SystemTime 
 
lstr_SystemTime.ui_wyear = year(date(adt)) 
lstr_SystemTime.ui_WMonth = Month(date(adt)) 
lstr_SystemTime.ui_WDay = Day(date(adt)) 
 
lstr_SystemTime.ui_wHour = hour(time(adt)) 
lstr_SystemTime.ui_wMinute = Minute(time(adt)) 
lstr_SystemTime.ui_wSecond = Second(time(adt)) 
lstr_SystemTime.ui_wMilliseconds = Long(String(adt, "fff")) 
 
If Not SystemTimeToFileTime(lstr_SystemTime, lstr_LocalTime) Then Return -1 
 
If Not LocalFileTimeToFileTime(lstr_LocalTime, astr_FileTime) Then Return -1 
 
Return 1 

end function

public function string of_getvolumeserialnumber ();//取硬盘逻辑序列号
//of_GetVolumeSerialNumber()
String  ls_Rootpath ="C:"
String  ls_volumnename =Space(256)//卷名:新加卷
Ulong   lul_VolumeNameSize =256      
Ulong   lul_VolumeSerialNumber
Ulong   lul_MaximumComponentLength =256
Ulong   lul_FileSystemFlags      
String  ls_FileSystemNameBuffer =space(256)//分区格式NTFS      
Ulong   lul_FileSystemNameSize  =256      
boolean lb_rtn      
lb_rtn =GetVolumeInformationA(ls_Rootpath,ls_volumnename,lul_VolumeNameSize,lul_VolumeSerialNumber,&
  lul_MaximumComponentLength,lul_FileSystemFlags,ls_FileSystemNameBuffer,lul_FileSystemNameSize)      
if lb_rtn then
   Return String(lul_VolumeSerialNumber)     
else      
   Return ""     
end if      
         


end function

public function string of_getcomputername ();//  取计算机名 of_GetComputerName()
long   ll_buf=256
String ls_ComputerName
ls_ComputerName = Space(ll_buf)
GetComputerNameA(ls_ComputerName,ll_buf)

Return ls_ComputerName

end function

public function integer of__setfiletime (string as_filename, datetime adt);//  ====================================================================
//  Event/Fun:   of__setfiletime(string as_filename,datetime adt)  
//  Returns:     integer 1:OK ; <0:error 
//  Description: 测试修改文件时间
//  --------------------------------------------------------------------
//  Copyright (c) 2018-2025 GuangZhou Software Co.Ltd(TM), All rights reserved.
//  --------------------------------------------------------------------
//  Written in: 2018-9-20
//  Modified in:
//  ====================================================================

ulong ll_hFile 
os_filedatetime los_CreationTime,los_LastAccessTime,los_LastWriteTime, los_null
datetime ldt_CreationTime,ldt_LastAccessTime,ldt_LastWriteTime

//读方式打开文件 
ll_hFile = CreateFile(as_filename,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,0,0)
//取文件时间
if GetFileTime(ll_hFile,los_CreationTime,los_LastAccessTime,los_LastWriteTime)=0 then
	CloseHandle(ll_hFile)
	Return -1
end if
CloseHandle(ll_hFile)

of_convertfiledatetimetopb(los_CreationTime, ldt_CreationTime)
of_convertfiledatetimetopb(los_LastAccessTime, ldt_LastAccessTime)
of_convertfiledatetimetopb(los_LastWriteTime, ldt_LastWriteTime)
MessageBox(as_filename,string(ldt_CreationTime,"yyyy-mm-dd hh:mm:ss fff")+"~r~n"+string(ldt_LastAccessTime,"yyyy-mm-dd hh:mm:ss fff")+"~r~n"+string(ldt_LastWriteTime,"yyyy-mm-dd hh:mm:ss fff"))
 
of_ConvertPBDatetimeToFile(adt, los_LastWriteTime)
//写方式打开文件 
ll_hFile = CreateFile(as_filename,GENERIC_WRITE,FILE_SHARE_WRITE,0,OPEN_EXISTING,0,0)
//写文件时间
if SetFileTime(ll_hFile,los_null, los_null, los_LastWriteTime)=0 then
	CloseHandle(ll_hFile)
	Return -2
end if
CloseHandle(ll_hFile)
Return 1


end function

on n_cst_filetime.create
call super::create
TriggerEvent( this, "constructor" )
end on

on n_cst_filetime.destroy
TriggerEvent( this, "destructor" )
call super::destroy
end on

event constructor;//  ====================================================================
//  n_cst_filetime    
//  Description: Library "kernel32.dll"
//  取文件建立时间 of_GetCreateDatetime( string as_filename, ref datetime)
//  取文件修改时间 of_GetLastwriteDatetime( string as_filename, ref datetime)
//  设文件修改时间 of_setlastwritedatetime( string as_filename, ref datetime)
//  取硬盘序列号 of_getvolumeSerialNumber()
//  取计算机名	  of_GetComputerName()
//  --------------------------------------------------------------------
//	 Version 12.5
//  --------------------------------------------------------------------
//  Copyright (c) 2018-2025 GuangZhou Co.Ltd(TM), All rights reserved.
//  --------------------------------------------------------------------
//  Written in: 2018-9-20 By Q1852181773
//  Modified in:
//  ====================================================================

end event

 文件下载的示例代码(PB12.5)

//根据文件日期下载

Long     ll_id,ll_filebytes
String   ls_filename,ls_uptime,ls_lastwritetime
blob     lblb_filedata
Integer  li_FileNum
DateTime       ldt_lastwrite
n_cst_filetime lnv_filetime

DECLARE cur_file CURSOR FOR 
	Select Id, FileName, CONVERT(char(16),UpTime,120) ,FileBytes
		From T_appdata Where app=:is_app or app is null  USING SQLCA;
OPEN  cur_file;
do 

FETCH cur_file into :ll_id, :ls_filename, :ls_uptime, :ll_FileBytes ;
IF	SQLCA.SQLCode = 0 THEN	
	If FileExists( ls_filename ) Then
		lnv_filetime.of_getlastwritedatetime( ls_filename, ldt_lastwrite) //取文件修改日期
		ls_lastwritetime = string( ldt_lastwrite,"yyyy-mm-dd hh:mm")
	Else
		ls_lastwritetime = "1900-01-01 00:00"
	End If
		
	If ls_lastwritetime < ls_uptime THEN
		SELECTBLOB FileData INTO :lblb_filedata From T_appdata where Id=:ll_id USING SQLCA ;
		if SQLCA.SQLCode = 0 then
			if Len(lblb_filedata) = ll_FileBytes then
			w_showmsg.Visible = true
			w_showmsg.st_1.text="正在更新文件:"+ls_filename+"~r~n"+w_showmsg.st_1.text
			li_FileNum = FileOpen( ls_filename, StreamMode!, Write!, LockReadWrite!, Replace! )
			FileWriteEx ( li_FileNum, lblb_filedata )
			FileClose ( li_FileNum )
			SetProfileString(FILEINI,is_app,ls_filename,ls_uptime )
			ldt_lastwrite = DateTime(ls_uptime)
			lnv_filetime.of_setlastwritedatetime(ls_filename,ldt_lastwrite)//修改文件时间
		   end if
		end if
   End If
END IF

loop while SQLCA.SQLCode = 0
CLOSE cur_file;
	


 

 

你可能感兴趣的:(PowerBuilder)