PB自動更新クライアントファイルの実現

15012 ワード

C/SがB/S構造と比較する欠点は、クライアントファイルの更新が煩雑であり、PB 12を使用することである.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);

win 32 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

ファイルダウンロードのサンプルコード(PB 12.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;