用 API函数 :SHFileOperation 在 win7 下不能复制文件

czw8819 2015-12-21 05:15:19
VFP 代码中使用 API函数 :SHFileOperation 来复制文件, 在XP里 能正常复制文件,但在WIN7里却无效。没有任何提示,就是不能成功复制文件。
求解,谢谢!!
...全文
362 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
都市夜猫 2015-12-23
  • 打赏
  • 举报
回复
找到问题所在就好 8楼那段代码你的自己改改,没有做错误处理,例如: tcSource 传入的是否字符型,空串,Null 值 pForm 的值也要判断下是否为 0
czw8819 2015-12-23
  • 打赏
  • 举报
回复
问题找到并解决了。
原因是这条付值语句:targetPath = SYS(5)+CURDIR()+"\BITMAPS"
得出来的结果如图:



赋值值语句改为:targetPath = SYS(5)+CURDIR()+"BITMAPS" 即可。
感谢版主-----都市夜猫 的帮助,
因我这块砖头,引出了一块好玉,由此得到了一段精简代码(原张大师的代码确实太长了)。


czw8819 2015-12-23
  • 打赏
  • 举报
回复
回楼上,报错的代码是:0x000000B7



czw8819 2015-12-22
  • 打赏
  • 举报
回复
很奇怪,以下代码可正常复制:
PUBLIC copyEXEfile,delFile
delFile = .F.

sourceCopyFileName = "\\" + ALLTRIM(_pv_server0) + "\rsmisPhoto$\hrmis.EXE"
IF  .NOT. FILE(sourceCopyFileName )   
    =MESSAGEBOX('抱歉,连接服务器失败!!' + CHR(13) + CHR(13) +  ;
   '发生的原因:可能是网络线路故障或服务器不开启';
    + CHR(13) + '请咨询网络管理员......";
    +"【系统尝试升级失败,继续使用旧版本】',64,"系统信息")
ELSE  
    serverExeVer = FDATE(sourceCopyFileName ,1)
    localEXE= SYS(5)+CURDIR()+"hrmis.exe"
	oldEXE = SYS(5)+CURDIR()+"hrmisOLD.exe"
	
	IF FILE(localEXE)
	    localExeVer = FDATE(localEXE,1)

		IF serverExeVer > localExeVer
		    WAIT WINDOW "发现新版本。系统正在进行升级,请稍候……" NOWAIT NOCLEAR AT 20,35
		    IF FILE(oldEXE)
		        DO deleteFile
		    ENDIF  
		    delFile = .F.  
		    RENAME hrmis.exe TO hrmisOLD.EXE
		    *DO copyFile 
			   targetPath = SYS(5)+CURDIR()
			   DO copyFile.prg WITH sourceCopyFileName,targetPath
   
		    IF copyEXEfile = .T.
		       DO deleteFile
		       IF delFile = .T.
		          =MESSAGEBOX("升级成功!",64,"系统信息",1500) 
		       ENDIF    
		   ELSE 
		     =MESSAGEBOX("升级失败",64,"系统信息") 
		     RENAME hrmisOLD.exe TO hrmis.EXE &&恢复为原来的文件名
		   ENDIF 
		ENDIF 
	    RELEASE copyExeFile
	ELSE 
	    =MESSAGEBOX("抱歉,找不到可执行文件!",64,"系统信息")
	    CLOSE ALL
	    CLEAR EVENTS 
	    ON SHUTDOWN 
	    QUIT
	     
     ENDIF 	    
ENDIF
----------------------------------------------------------------------------------------- 但如下代码却不能复制:
 IF DIRECTORY("\\192.168.1.9\rsmisphoto$\BITMAPS")
		         sourceCopyFileName="\\192.168.1.9\rsmisphoto$\BITMAPS\*.*"
		        targetPath = SYS(5)+CURDIR()+"\BITMAPS"
		     
		         DO copyFile.prg WITH sourceCopyFileName,targetPath
         	 ENDIF
	       
czw8819 2015-12-22
  • 打赏
  • 举报
回复
很奇怪: 以下代码可正常复制
PUBLIC copyEXEfile,delFile
delFile = .F.

sourceCopyFileName = "\\" + ALLTRIM(_pv_server0) + "\rsmisPhoto$\hrmis.EXE"
IF  .NOT. FILE(sourceCopyFileName )   
    =MESSAGEBOX('抱歉,连接服务器失败!!' + CHR(13) + CHR(13) +  ;
   '发生的原因:可能是网络线路故障或服务器不开启';
    + CHR(13) + '请咨询网络管理员......";
    +"【系统尝试升级失败,继续使用旧版本】',64,"系统信息")
ELSE  
    serverExeVer = FDATE(sourceCopyFileName ,1)
    localEXE= SYS(5)+CURDIR()+"hrmis.exe"
	oldEXE = SYS(5)+CURDIR()+"hrmisOLD.exe"
	
	IF FILE(localEXE)
	    localExeVer = FDATE(localEXE,1)

		IF serverExeVer > localExeVer
		    WAIT WINDOW "发现新版本。系统正在进行升级,请稍候……" NOWAIT NOCLEAR AT 20,35
		    IF FILE(oldEXE)
		        DO deleteFile
		    ENDIF  
		    delFile = .F.  
		    RENAME hrmis.exe TO hrmisOLD.EXE
		     targetPath = SYS(5)+CURDIR()
		     DO copyFile.prg WITH sourceCopyFileName,targetPath
   
		    IF copyEXEfile = .T.
		       DO deleteFile
		       IF delFile = .T.
		          =MESSAGEBOX("升级成功!",64,"系统信息",1500) 
		       ENDIF    
		   ELSE 
		     =MESSAGEBOX("升级失败",64,"系统信息") 
		     RENAME hrmisOLD.exe TO hrmis.EXE &&恢复为原来的文件名
		   ENDIF 
		ENDIF 
	    RELEASE copyExeFile
	ELSE 
	    =MESSAGEBOX("抱歉,找不到可执行文件!",64,"系统信息")
	    CLOSE ALL
	    CLEAR EVENTS 
	    ON SHUTDOWN 
	    QUIT
	     
     ENDIF 	    
ENDIF     
DO hrMIS.EXE

------------------------------------------------------------------------------------------------- 但如下代码却不能复制:
       IF DIRECTORY("\\192.168.1.9\rsmisphoto$\BITMAPS")
		             sourceCopyFileName="\\192.168.1.9\rsmisphoto$\BITMAPS\*.*"
		            targetPath = SYS(5)+CURDIR()+"\BITMAPS"
		     
		               DO copyFile.prg WITH sourceCopyFileName,targetPath 
                   ENDIF               
czw8819 2015-12-22
  • 打赏
  • 举报
回复
回楼上: 不是很明白,我已贴出代码,老师可不可以明确的告诉我要修改哪 里,不好意思,我很笨。谢谢
czw8819 2015-12-22
  • 打赏
  • 举报
回复
先感谢楼上的回复。 代码是从 张洪举 的 《Visual FoxPro 360问》书中复制而来,只在首行增加了源文件及目标文件夹变量, 代码如下,
LPARAMETERS sourceCopyFileName,targetLocation

DECLARE Integer SHFileOperation IN SHELL32.dll String @ LPSHFILEOPSTRUCT 
DECLARE Integer GetActiveWindow IN WIN32API 
DECLARE INTEGER ShellExecute IN "Shell32.dll" ;
    INTEGER hwnd, ;
    STRING lpVerb, ;
    STRING lpFile, ;
    STRING lpParameters, ;
    STRING lpDirectory, ;
    LONG nShowCmd
    
oHeap =CREATEOBJECT("Heap") 
#define FO_COPY 2 
#define FOF_NOCONFIRMATION 0x10    &&  不提示用户. 
#define FOF_NOCONFIRMMKDIR 0x200   &&  不创建新目录 

*cSourceString = "\\panthers\mis_update$\HRMIS.exe" +CHR(0) +CHR(0) 
cSourceString = sourceCopyFileName +CHR(0) +CHR(0) 

IF EMPTY(targetLocation)
   cDestString = SYS(5)+CURDIR() + CHR(0) +CHR(0) 
ELSE 
    cDestString = targetLocation + CHR(0) +CHR(0) 
ENDIF 
   
nStringBase = oHeap.AllocBlob(cSourceString+cDestString) 
cFileOpStruct = NumToDWORD(GetActiveWindow()) + ; 
   NumToDWORD(FO_COPY) + ; 
   NumToDWORD(nStringBase) + ; 
   NumToDWORD(nStringBase + LEN(cSourceString)) + ; 
   NumToDWORD(FOF_NOCONFIRMATION+FOF_NOCONFIRMMKDIR)+ ; 
   CHR(0) + ; 
   NumToDWORD(0) + ; 
   NumToDWORD(0)

IF SHFileOperation(cFileOpStruct) = 0
   copyEXEfile = .T.
ELSE 
    MESSAGEBOX("抱歉,文件复制失败!",64,"系统信息")
    copyEXEfile = .F.
ENDIF     
oHeap = '' 

DEFINE CLASS heap AS custom 

	PROTECTED inHandle, inNumAllocsActive,iaAllocs[1,3] 
	inHandle = NULL 
	inNumAllocsActive = 0 
	iaAllocs = NULL 
	Name = "heap" 

	PROCEDURE Alloc 
		*  分配一个块, 返回一个指向它的指针 
		LPARAMETER nSize 
		DECLARE INTEGER HeapAlloc IN WIN32API AS HAlloc; 
			INTEGER hHeap, ; 
			INTEGER dwFlags, ; 
			INTEGER dwBytes 
		DECLARE INTEGER HeapSize IN WIN32API AS HSize ; 
			INTEGER hHeap, ; 
			INTEGER dwFlags, ; 
			INTEGER lpcMem 
		LOCAL nPtr 
		WITH this 
			nPtr = HAlloc(.inHandle, 0, @nSize) 
			IF nPtr # 0 
				*  块分配数组 
				.inNumAllocsActive = .inNumAllocsActive + 1 
				DIMENSION .iaAllocs[.inNumAllocsActive,3] 
				*  指针 
				.iaAllocs[.inNumAllocsActive,1] = nPtr 
				*  分配的实际大小 - 由HeapSize() 获得
				.iaAllocs[.inNumAllocsActive,2] = HSize(.inHandle, 0, nPtr) 
				.iaAllocs[.inNumAllocsActive,3] = .T. 
			ELSE
				*  HeapAlloc() 失败- 返回NULL指针 
				nPtr = NULL 
			ENDIF
		ENDWITH
		RETURN nPtr 
	ENDPROC

	FUNCTION AllocBLOB 
		*	分配一块能传递BString大小的内存,  The 
	    LPARAMETER cBStringToCopy 
		LOCAL nAllocPtr 
		WITH this 
			nAllocPtr = .Alloc(LEN(cBStringToCopy)) 
			IF ! ISNULL(nAllocPtr) 
				.CopyTo(nAllocPtr,cBStringToCopy)
			ENDIF
		ENDWITH
		RETURN nAllocPtr 
	ENDFUNC

	FUNCTION AllocString 
		LPARAMETER cString 
		RETURN this.AllocBLOB(cString + CHR(0)) 
	ENDFUNC

	FUNCTION AllocInitAs 
		*  分配一块内存初始化成CHR(nByteValue) 
		LPARAMETER nSizeOfBuffer, nByteValue 
		IF TYPE('nByteValue') # 'N' OR ! BETWEEN(nByteValue,0,255) 
			*	缺省初始化为nulls 
			nByteValue = 0 
		ENDIF
		RETURN this.AllocBLOB(REPLICATE(CHR(nByteValue),nSizeOfBuffer)) 
	ENDFUNC

	PROCEDURE DeAlloc 
		*  丢弃以前的分配块 
		LPARAMETER nPtr 
		DECLARE INTEGER HeapFree IN WIN32API AS HFree ; 
			INTEGER hHeap, ; 
			INTEGER dwFlags, ; 
			INTEGER lpMem 
		LOCAL nCtr 
	    nCtr = NULL 
		WITH this 
			nCtr = .FindAllocID(nPtr) 
			IF ! ISNULL(nCtr) 
				=HFree(.inHandle, 0, nPtr) 
				.iaAllocs[nCtr,3] = .F. 
			ENDIF
		ENDWITH
		RETURN ! ISNULL(nCtr) 
	ENDPROC


	PROCEDURE CopyTo 
		*  复制一个VFP字符串到块 
		LPARAMETER nPtr, cSource 
		DECLARE RtlMoveMemory IN WIN32API AS RtlCopy ; 
			INTEGER nDestBuffer, ; 
			STRING @pVoidSource, ; 
			INTEGER nLength 
		LOCAL nCtr 
		nCtr = NULL 
	   IF TYPE('nPtr') = 'N' AND TYPE('cSource') $ 'CM' ; 
		   AND ! (ISNULL(nPtr) OR ISNULL(cSource)) 
			WITH this 
				*  通过nPtr查找分配点 
				nCtr = .FindAllocID(nPtr) 
				IF ! ISNULL(nCtr) 
					*  复制较小的缓冲区或原字符串 
					=RtlCopy((.iaAllocs[nCtr,1]), ; 
							cSource, ; 
							MIN(LEN(cSource),.iaAllocs[nCtr,2]))
				ENDIF
			ENDWITH
		ENDIF
		RETURN ! ISNULL(nCtr) 
	ENDPROC


	PROCEDURE CopyFrom 
		*  复制缓冲区内容到VFP 
		LPARAMETER nPtr 
		DECLARE RtlMoveMemory IN WIN32API AS RtlCopy ; 
			STRING @DestBuffer, ; 
			INTEGER pVoidSource, ; 
			INTEGER nLength 
		LOCAL nCtr, uBuffer 
		uBuffer = NULL 
		nCtr = NULL 
		IF TYPE('nPtr') = 'N' AND ! ISNULL(nPtr) 
			WITH this 
				*  查找地址为nPtr的分配块 
				nCtr = .FindAllocID(nPtr) 
				IF ! ISNULL(nCtr) 
					* 在VFP中分配一个足够大的缓冲区来接收块 
					uBuffer = REPL(CHR(0),.iaAllocs[nCtr,2]) 
					=RtlCopy(@uBuffer, ; 
							(.iaAllocs[nCtr,1]), ; 
							(.iaAllocs[nCtr,2]))
				ENDIF
			ENDWITH
		ENDIF
		RETURN uBuffer 
	ENDPROC

	PROTECTED FUNCTION FindAllocID 
	 	LPARAMETER nPtr 
	 	LOCAL nCtr 
	 	WITH this 
			FOR nCtr = 1 TO .inNumAllocsActive 
				IF .iaAllocs[nCtr,1] = nPtr AND .iaAllocs[nCtr,3] 
					EXIT
				ENDIF
			ENDFOR
			RETURN IIF(nCtr <= .inNumAllocsActive,nCtr,NULL) 
		ENDWITH
	ENDPROC

	PROCEDURE SizeOfBlock 
		*  检索一个分配块的实际内存大小 
		LPARAMETERS nPtr 
		LOCAL nCtr, nSizeOfBlock 
		nSizeOfBlock = NULL 
		WITH this 
			*  查找地址为nPtr的分配块 
			nCtr = .FindAllocID(nPtr) 
			RETURN IIF(ISNULL(nCtr),NULL,.iaAllocs[nCtr,2]) 
		ENDWITH
	ENDPROC

	PROCEDURE Destroy 
		DECLARE HeapDestroy IN WIN32API AS HDestroy ; 
		  INTEGER hHeap 

		LOCAL nCtr 
		WITH this 
			FOR nCtr = 1 TO .inNumAllocsActive 
				IF .iaAllocs[nCtr,3] 
					.Dealloc(.iaAllocs[nCtr,1])
				ENDIF
			ENDFOR
			HDestroy[.inHandle]
		ENDWITH
		DODEFAULT()
	ENDPROC


	PROCEDURE Init 
		DECLARE INTEGER HeapCreate IN WIN32API AS HCreate ; 
			INTEGER dwOptions, ; 
			INTEGER dwInitialSize, ; 
			INTEGER dwMaxSize 
		#DEFINE SwapFilePageSize  4096 
		#DEFINE BlockAllocSize    2 * SwapFilePageSize 
		WITH this 
			.inHandle = HCreate(0, BlockAllocSize, 0) 
			DIMENSION .iaAllocs[1,3] 
			.iaAllocs[1,1] = 0 
			.iaAllocs[1,2] = 0 
			.iaAllocs[1,3] = .F. 
			.inNumAllocsActive = 0 
		ENDWITH
		RETURN (this.inHandle # 0) 
	ENDPROC

ENDDEFINE


FUNCTION SetMem 
LPARAMETERS nPtr, cSource 
DECLARE RtlMoveMemory IN WIN32API AS RtlCopy ; 
	INTEGER nDestBuffer, ; 
	STRING @pVoidSource, ; 
	INTEGER nLength 

RtlCopy(nPtr, ; 
		cSource, ; 
		LEN(cSource))
RETURN .T. 

FUNCTION GetMem 
LPARAMETERS nPtr, nLen 
DECLARE RtlMoveMemory IN WIN32API AS RtlCopy ; 
	STRING @DestBuffer, ; 
	INTEGER pVoidSource, ; 
	INTEGER nLength 
LOCAL uBuffer 
* 分配一个足够大的缓冲区来接收块 
uBuffer = REPL(CHR(0),nLen) 
=RtlCopy(@uBuffer, ; 
		 nPtr, ; 
		 nLen)
RETURN uBuffer 

FUNCTION GetMemString 
LPARAMETERS nPtr, nSize 
DECLARE INTEGER lstrcpyn IN WIN32API AS StrCpyN ; 
	STRING @ lpDestString, ; 
	INTEGER lpSource, ; 
	INTEGER nMaxLength 
LOCAL uBuffer 
IF TYPE('nSize') # 'N' OR ISNULL(nSize) 
	nSize = 512 
ENDIF
*  分配一个足够大的缓冲区来接收数据 
uBuffer = REPL(CHR(0), nSize) 
IF StrCpyN(@uBuffer, nPtr, nSize-1) # 0 
	uBuffer = LEFT(uBuffer, MAX(0,AT(CHR(0),uBuffer) - 1)) 
ELSE
	uBuffer = NULL 
ENDIF
RETURN uBuffer 

FUNCTION SHORTToNum 
	* 转变结构中的16位带符号整数到VFP数值型 
 	LPARAMETER tcInt 
	LOCAL b0,b1,nRetVal 
	b0=asc(tcInt)
	b1=asc(subs(tcInt,2,1))
	if b1<128 
		nRetVal=b1 * 256 + b0 
	else
		b1=255-b1
		b0=256-b0
		nRetVal= -( (b1 * 256) + b0) 
	endif
	return nRetVal 

FUNCTION NumToSHORT 
	LPARAMETER tnNum 
	LOCAL b0,b1,x 
	IF tnNum>=0 
		x=INT(tnNum)
		b1=INT(x/256)
		b0=MOD(x,256)
	ELSE
		x=INT(-tnNum)
		b1=255-INT(x/256)
		b0=256-MOD(x,256)
		IF b0=256 
			b0=0
			b1=b1+1
		ENDIF
	ENDIF
	RETURN CHR(b0)+CHR(b1) 

FUNCTION DWORDToNum 
	LPARAMETER tcDWORD 
	LOCAL b0,b1,b2,b3 
	b0=asc(tcDWORD)
	b1=asc(subs(tcDWORD,2,1))
	b2=asc(subs(tcDWORD,3,1))
	b3=asc(subs(tcDWORD,4,1))
	RETURN ( ( (b3 * 256 + b2) * 256 + b1) * 256 + b0) 

FUNCTION NumToDWORD 
	LPARAMETER tnNum 
	RETURN NumToLong(tnNum) 

FUNCTION WORDToNum 
	LPARAMETER tcWORD 
	RETURN (256 *  ASC(SUBST(tcWORD,2,1)) ) + ASC(tcWORD) 

FUNCTION NumToWORD 
	LPARAMETER tnNum 
	LOCAL x 
	x=INT(tnNum)
	RETURN CHR(MOD(x,256))+CHR(INT(x/256)) 

FUNCTION NumToLong 
	LPARAMETER tnNum 
	DECLARE RtlMoveMemory IN WIN32API AS RtlCopyLong ; 
		STRING @pDestString, ; 
		INTEGER @pVoidSource, ; 
		INTEGER nLength 
	LOCAL cString 
	cString = SPACE(4) 
   =RtlCopyLong(@cString, BITOR(tnNum,0), 4) 
	RETURN cString 

FUNCTION LongToNum 
	LPARAMETER tcLong 
	DECLARE RtlMoveMemory IN WIN32API AS RtlCopyLong ; 
		INTEGER @ DestNum, ; 
		STRING @ pVoidSource, ; 
		INTEGER nLength 
	LOCAL nNum 
	nNum = 0 
	=RtlCopyLong(@nNum, tcLong, 4) 
	RETURN nNum 

FUNCTION AllocNetAPIBuffer 
LPARAMETER nSize 
IF TYPE('nSize') # 'N' OR nSize <= 0 
	*	传递地非法参数,所以返回NULL
	MESSAGEBOX(" 传递非法参数,复制失败!")
	RETURN NULL 
ENDIF

IF ! 'NT' $ OS() 
	*	仅支持在NT下API调用, 所以返回失败 
	MESSAGEBOX("抱歉,仅支持在NT下API调用")
	RETURN NULL 
ENDIF
DECLARE INTEGER NetApiBufferAllocate IN NETAPI32.DLL ; 
	INTEGER dwByteCount, ; 
	INTEGER lpBuffer 
LOCAL  nBufferPointer 
nBufferPointer = 0 
IF NetApiBufferAllocate(INT(nSize), @nBufferPointer) # 0 
	*  调用错误,所以返回一个NULL值 
		MESSAGEBOX(" 调用错误,所以返回一个NULL值,复制失败!")
	nBufferPointer = NULL 
ENDIF
RETURN nBufferPointer 

FUNCTION DeAllocNetAPIBuffer 
LPARAMETER nPtr 
IF TYPE('nPtr') # 'N' 
	*	传递了非法参数,所以返回失败
	MESSAGEBOX(" 传递了非法参数,所以返回失败")
	RETURN .F. 
ENDIF

IF ! 'NT' $ OS() 
	*	仅支持在NT下API调用, 所以返回失败 
	RETURN .F. 
ENDIF
DECLARE INTEGER NetApiBufferFree IN NETAPI32.DLL ; 
	INTEGER lpBuffer 
RETURN (NetApiBufferFree(INT(nPtr)) = 0) 

Function CopyDoubleToString 
LPARAMETER nDoubleToCopy 
DECLARE RtlMoveMemory IN WIN32API AS RtlCopyDbl ; 
	STRING @DestString, ; 
	DOUBLE @pVoidSource, ; 
	INTEGER nLength 
LOCAL cString 
cString = SPACE(8) 
=RtlCopyDbl(@cString, nDoubleToCopy, 8) 
RETURN cString 

FUNCTION DoubleToNum 
LPARAMETER cDoubleInString 
DECLARE RtlMoveMemory IN WIN32API AS RtlCopyDbl ; 
	DOUBLE @DestNumeric, ; 
	STRING @pVoidSource, ; 
	INTEGER nLength 
LOCAL nNum 
nNum = 0.000000000000000000 
=RtlCopyDbl(@nNum, cDoubleInString, 8) 
RETURN nNum
-------------------------------------------------------------------------------------------------------------------------------------------------------------------- 附注: 我将以上代码生成一个 CopyFile.PRG 文件,在自己的系统中调用,不会单独运行此文件。 分别试过以管理员身份及兼容XP方式运行,问题依旧。
文修 2015-12-22
  • 打赏
  • 举报
回复
function File_Action(fFROM, fTO: string; Action: integer): Boolean;
// 对文件进行操作
var
FData: TShFileOpStruct;
begin
FillChar(FData, SizeOf(TShFileOpStruct), 0);
FData.pFrom := pchar(fFROM + #0);
// 设立数据源路径和文件、目录名,支(?,*通配符)
if fTO <> '' then
if fTO[length(fTO)] <> '\' then
fTO := fTO + '\';
FData.pTo := pchar(fTO + #0); // 设立目标路径
case Action of
0:
FData.wFunc := FO_COPY; // copy
1:
FData.wFunc := FO_MOVE; // move
2:
FData.wFunc := FO_DELETE; // delete
3:
FData.wFunc := FO_RENAME; // rename,未使用
else
FData.wFunc := FO_COPY;
end;
FData.fFlags := FOF_ALLOWUNDO or FOF_CONFIRMMOUSE;
if ExtractFilePath(fFROM) = fTO then
FData.fFlags := FOF_RENAMEONCOLLISION;
FData.fAnyOperationsAborted := false;
FData.hNameMappings := nil;
case Action of
0:
FData.lpszProgressTitle := '复制文件'; // copy
1:
FData.lpszProgressTitle := '移动文件'; // move
2:
FData.lpszProgressTitle := '删除文件'; // delete
3:
FData.lpszProgressTitle := '重命名'; // rename
end;
Result := ShFileOperation(FData) = 0;
end;.


把AnsiChar都改成string;

这个是 dephi 代码,与本版块无关
都市夜猫 2015-12-22
  • 打赏
  • 举报
回复
张大师的代码太长了, 用我这个简单点的试试,看报错的代码是什么
nErrCode = CopyFiles('d:\test1\*.*', 'c:\test2')
If 0 != nErrCode
MessageBox('复制文件失败,错误码:' + Transform(nErrCode, '@0'))
EndIf

Function CopyFiles(tcSource, tcTarget)
Local cFOS, pFrom, pTo, nErrorCode

Declare Long SHFileOperation in shell32 String @
Declare Long GlobalAlloc in win32api Long, Long
Declare Long GlobalFree in win32api Long

tcTarget = Addbs(Evl(tcTarget, Sys(5)+Curdir()))

pFrom = GlobalAlloc(0x40, 4 + Len(tcSource + tcTarget))
pTo = pFrom + Len(tcSource) + 2
Sys(2600, pFrom, Len(tcSource), tcSource)
Sys(2600, pTo, Len(tcTarget), tcTarget)

cFOS = BinToC(0, 'rs') + BinToC(2, 'rs') ;
+ BinToC(pFrom, 'rs') + BinToC(pTo, 'rs') ;
+ BinToC(0x0008 + 0x0010 + 0x0200, 'rs') ;
+ Replicate(0h00, 4*3)
nErrorCode = SHFileOperation(@ cFOS)
GlobalFree(pFrom)
Return nErrorCode
EndFunc
都市夜猫 2015-12-22
  • 打赏
  • 举报
回复
你把 CopyFile.prg 中的
IF SHFileOperation(cFileOpStruct) = 0
   copyEXEfile = .T.
ELSE 
    MESSAGEBOX("抱歉,文件复制失败!",64,"系统信息")
    copyEXEfile = .F.
ENDIF
改成
nErrorCode = SHFileOperation(cFileOpStruct)
IF nErrorCode == 0
   copyEXEfile = .T.
ELSE 
    MESSAGEBOX("抱歉,文件复制失败!" ;
    	+ 0h0d0a0d0a + "错误代码:" + Transform(nErrorCode, '@0') ;
    	, 64, "系统信息")
    copyEXEfile = .F.
ENDIF
看看不成功时返回的错误代码是什么,然后到 这里 查找对应的错误原因。
都市夜猫 2015-12-21
  • 打赏
  • 举报
回复
把你的代码贴出来,还有,调用 SHFileOperation 函数的返回的值是什么? xp 下可以, win7 下不好用,通常都是权限问题,先试试用管理员身份运行

2,723

社区成员

发帖
与我相关
我的任务
社区描述
VFP,是Microsoft公司推出的数据库开发软件,用它来开发数据库,既简单又方便。
社区管理员
  • VFP社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧