deltree时内存出错问题 (50分)

  • 主题发起人 主题发起人 fuku
  • 开始时间 开始时间
F

fuku

Unregistered / Unconfirmed
GUEST, unregistred user!
小弟想实现deltree的功能,代码如下:<br>var OpStruc: TSHFileOpStruct;<br>&nbsp; &nbsp; frombuf: Array [0..128] of Char;<br>&nbsp; &nbsp; Source:String;<br>begin<br>&nbsp; Source:='C:/aaa';<br>&nbsp; FillChar( frombuf, Sizeof(frombuf), 0 );<br>&nbsp; StrPCopy( frombuf, Source );<br>&nbsp; With OpStruc DO Begin<br>&nbsp; &nbsp; Wnd:= Handle;<br>&nbsp; &nbsp; wFunc:= FO_DELETE;<br>&nbsp; &nbsp; pFrom:= @frombuf;<br>&nbsp; &nbsp; fFlags:=FOF_SIMPLEPROGRESS;<br>&nbsp; &nbsp; fAnyOperationsAborted:= False;<br>&nbsp; &nbsp; hNameMappings:= Nil;<br>&nbsp; &nbsp; lpszProgressTitle:= Nil;<br>&nbsp; end;<br>&nbsp; ShFileOperation( OpStruc );<br>end;<br>问题是一执行就出现shell32.dll访问内存出错,此时deltree功能仍然完成,<br>如何解决?<br>
 
其实实现DelTree可以这么做 :<br>&nbsp;<br>  delphi提供了关于文件操作的许多函数,其中关于目录操作的有目录的创建与删除、<br>设置当前目录、获取当前目录等。目录的删除有函数(function)removedir和过程<br>(procedure)rmdir,但它们都只能删除空目录,对于非空目录则不能删除。要实现删除<br>整个目录树(deltree)必须编写程序来删除其中的子目录和文件。 <br><br>  目录中的文件可以通过调用函数deletefile来删除,但对于特殊文件(只读、系统、<br>隐藏等)则不能有效删除,必须更改文件属性为普通文件才能删除。更改文件属性可以用<br>函数filesetattr,这里将特殊文件的属性设置为普通文件属性(属性值为0)。 <br><br>  考虑到树型目录结构最适合于递归方法,所有这里用递归算法来实现deltree函数。<br>下面是具体实现程序。 <br><br>  //path是需删除的目录路径 <br><br>  //目录成功删除返回true,否则返回false <br><br>  function tform1.deltree (path : string): boolean ; <br><br>  var <br><br>   searchrec: tsearchrec; <br><br>  begin <br><br>  //判断目录是否存在 <br><br>if directoryexists(path) then <br><br>begin <br><br>  //进入该目录,删除其中的子目录和文件 <br><br>   olddir := getcurrentdir; <br><br>   chdir(path); <br><br>  //查找目录中所有任何文件 <br><br>  findfirst(′?.?′, faanyfile, searchrec); <br><br>  repeat <br><br>  //修改文件属性为普通属性值 <br><br>   filesetattr(searchrec.name,0); <br><br>  //如果是目录并且不是.和..则递归调用deltree <br><br>  if(searchrec.attr and fadirectory &gt; 0) then <br><br>  begin <br><br>  if(searchrec.name[1]&lt;&gt;′.′) then <br><br>  if(not deltree(searchrec.name)) then <br><br>  break; <br><br>  end <br><br>  //如果是文件直接删除 <br><br>  else <br><br>  if(not deletefile(searchrec.name))then <br><br>  break ; <br><br>  //继续查找,直到最后 <br><br>  until (findnext(searchrec)&lt;&gt;0) ; <br><br>  //回到父目录,删除该目录 <br><br>  chdir(′..′); <br><br>  result := removedir(path); <br><br>&nbsp; &nbsp; setcurrentdir(olddir); <br><br>  end <br><br>  else <br><br>&nbsp; &nbsp; &nbsp; result := false ; <br><br>  end ; <br>&nbsp;<br>
 
To:卷起千堆雪tyn<br>首先谢谢兄长耐心详尽的指导,但小弟只是想知道自己的方法为何会出现内存错误,<br>以及如何解决,或者如何掩盖内存出错信息。<br>
 
To:卷起千堆雪tyn<br>首先谢谢兄长耐心详尽的指导,但小弟只是想知道自己的方法为何会出现内存错误,<br>以及如何解决,或者如何掩盖内存出错信息。<br>
 
你的操作系统是???现在ShFileOperation只支持WinNt呀!!!<br>看看帮助,它是这样写的 :<br>SHFileOperation <br>[Now Supported on Windows NT]<br><br>Performs a copy, move, rename, or delete operation on a file system object. <br><br>WINSHELLAPI int WINAPI SHFileOperation(<br><br>&nbsp; &nbsp; LPSHFILEOPSTRUCT lpFileOp <br>&nbsp; &nbsp;); <br>&nbsp;<br><br>Parameters<br><br>lpFileOp<br><br>Pointer to an SHFILEOPSTRUCT structure that contains information the function needs to carry out the operation.<br><br>&nbsp;<br><br>Return Values<br><br>Returns zero if successful or nonzero if an error occurs.
 
To 卷起千堆雪tyn<br>小弟对[Now Supported on Windows NT]的理解是NT现在已经支持SHFileOperation,<br>而原先SHFileOperation只能在WIN9X上使用,因为并不是[Now Only Supported on <br>Windows NT],况且文件的复制用SHFileOperation都没问题,相信N(N趋向于无穷)<br>人在WIN9X下写的文件复制都是用SHFileOperation写的,小弟也写过。不好意思,<br>小弟钻牛角尖了。 <br>
 
To 卷起千堆雪tyn:<br>小弟又看了一下help,发现SHFileOperation的quick view中写着使用平台为WIN9X和NT,<br>小弟在NT上运行此程序则提示kernel32.dll访问内存出错,而且deltree功能无法实现,<br>就是程序的SHFileOperation一执行就出错,而WIN9X上是在执行结束时出现内存错误,<br>所以我认为可能是代码存在问题。
 
请在设置OpStruc之前将里面的内容清0:<br><br>FillChar(OpStruc,sizeof(OpStruc),0);
 
to fuku :<br>总算为你改好了!!!<br>pFrom:= @frombuf;<br>pTo :=nil; &nbsp;//一定要加上的<br>fFlags:=FOF_SIMPLEPROGRESS;<br>其实你看看帮助,就会知道的.<br>pTo :<br>&nbsp; Address of a buffer to contain the name of the destination file or directory.<br>The buffer can contain multiple destination file names if the fFlags member <br>specifies FOF_MULTIDESTFILES. Multiple names must be null-separated. The list <br>of names must be double null-terminated. <br>
 
小弟试过两位兄长的方法都是可行的,谢谢解答!<br>特别感谢:卷起千堆雪tyn大哥的耐心指导!
 
多人接受答案了。
 
后退
顶部