DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: jeff1314
今日帖子: 0
在线用户: 5
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil  
作者:
男 moom (小新啊) ▲▲▲△△ -
普通会员
2018/2/21 23:28:53
标题:
问题:判断文件是否被占用函数,D10.22-32位正常,64位无效? 浏览:1580
加入我的收藏
楼主: 如打开一个 doc/exe/pdf。。。 

D10.22 - 32位编译的 exe 正常,64位却总是返回 False

请问什么原因?  谢谢...
 
//判断文件是否被占用函数
function IsFileInUse(FileName: TFileName): Boolean;
var
  HFileRes: HFILE;
begin
  Result := False;
  if not FileExists(FileName) then Exit;
  HFileRes := CreateFile(PChar(FileName),
          GENERIC_READ or GENERIC_WRITE,
          0,
          nil,
          OPEN_EXISTING,
          FILE_ATTRIBUTE_NORMAL,
          0);
  Result := (HFileRes = INVALID_HANDLE_VALUE);
  if not Result then
    CloseHandle(HFileRes);
end;


procedure TForm1.Button1Click(Sender: TObject);
begin
  if IsFileInUse('c:\Programs\delphi6\bin\delphi32.exe') then
    ShowMessage('File is in use.');
  else
    ShowMessage('File not in use.');
end;
----------------------------------------------
谢谢各位大大
作者:
男 moom (小新啊) ▲▲▲△△ -
普通会员
2018/2/21 23:59:45
1楼: 我是在 win10   64位系统测试
----------------------------------------------
谢谢各位大大
作者:
男 bahamut8348 (leonna) ★☆☆☆☆ -
普通会员
2018/2/22 8:58:49
2楼: 32位64位都一样。
不过兰州的代码写的有问题。
句柄为-1还要判断getlasterror的返回值。
----------------------------------------------
--
作者:
男 hsj (hsj) ★☆☆☆☆ -
盒子活跃会员
2018/2/22 9:03:53
3楼: function isFileInUse(AName: string): Boolean;

var
  hfileres: hfile;
begin
  Application.ProcessMessages;
  Result := false;
  if not FileExists(AName) then
    Exit;
  SetFileReadOnly(AName, false); //只读的话,下面的检测就会失败//hsj 2017-09-07
  Application.ProcessMessages;
  hfileres := createfile(PChar(AName), generic_read or generic_write, 0, nil,
    open_existing, file_attribute_normal, 0);
  try
    Result := hfileres = invalid_handle_value;
  finally
    if not Result then
      CloseHandle(hfileres);
  end;
end;
----------------------------------------------
qq:171833017,靖源软件http://www.dxmylove.com
作者:
男 moom (小新啊) ▲▲▲△△ -
普通会员
2018/2/22 11:14:49
4楼: 谢谢楼上各位。

还是不能使用。。在 D10.22-64位编译的exe,仍是返回 False,32位可以返回 true。。。
----------------------------------------------
谢谢各位大大
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2018/2/22 11:29:24
5楼: // 检查文件是否被独占打开。
Function IsFileInUseForExclusiveOpen(FileName: WideString): Boolean;
var
  hFile: THandle;
begin
  Result := False;
  if not FileExists(FileName) then
    Exit;
  hFile := FileOpen(FileName, fmOpenReadWrite or fmShareDenyWrite or fmShareDenyRead);
  if hFile = NULL_Handle then
    Exit;
  if (hFile = INVALID_HANDLE_VALUE) then
  begin
    Result := True;
    Exit;
  end;
  try
    Result := False;
  finally
    CloseHandle(hFile);
  end;
end;

// 试图独占打开前,可以使用本函数判断
Function IsFileCanExclusiveOpen(FileName: WideString): Boolean;
var
  hFile: THandle;
begin
  Result := False;
  if not FileExists(FileName) then
    Exit;
  hFile := FileOpen(FileName, fmOpenReadWrite or fmShareExclusive);
  if hFile = NULL_Handle then
    Exit;
  if (hFile = INVALID_HANDLE_VALUE) then
  begin
    Result := False; //注意 和别的函数是反的。
    Exit;
  end;
  try
    Result := True;  //注意 和别的函数是反的。
  finally
    CloseHandle(hFile);
  end;
end;

// 试图复制到或写入文件时,可以使用本函数判断。
Function IsFileInUseForCopyToOrWrite(FileName: WideString): Boolean;
var
  hFile: THandle;
begin
  Result := False;
  if not FileExists(FileName) then
    Exit;
  hFile := FileOpen(FileName, fmOpenReadWrite or fmShareDenyNone);
  if hFile = NULL_Handle then
    Exit;
  if (hFile = INVALID_HANDLE_VALUE) then
  begin
    Result := True;
    Exit;
  end;
  try
    Result := False;
  finally
    CloseHandle(hFile);
  end;
end;

// 试图删除或重命名文件时,可以使用本函数判断。
Function IsFileInUseForDeleteOrRename(FileName: WideString): Boolean;
var
  hFile: THandle;
begin
  Result := False;
  if not FileExists(FileName) then
    Exit;
  hFile := FileOpen(FileName, fmOpenReadWrite or fmShareDenyWrite);
  if hFile = NULL_Handle then
    Exit;
  if (hFile = INVALID_HANDLE_VALUE) then
  begin
    Result := True;
    Exit;
  end;
  try
    Result := False;
  finally
    CloseHandle(hFile);
  end;
end;

Function IsFileCanDeleteOrRename(FileName: WideString): Boolean;
begin
  Result := not IsFileInUseForDeleteOrRename(FileName);
end;

Function IsFileCanCopyToOrWrite(FileName: WideString): Boolean;
begin
  Result := not IsFileInUseForCopyToOrWrite(FileName);
end;
----------------------------------------------
(C)(P)Flying Wang
作者:
男 moom (小新啊) ▲▲▲△△ -
普通会员
2018/2/22 13:41:14
6楼: 请问楼上, 提示  NULL_Handle     Undeclared。。。如何解决?
----------------------------------------------
谢谢各位大大
作者:
男 moom (小新啊) ▲▲▲△△ -
普通会员
2018/2/22 13:56:19
7楼: 0楼 代码编译为32位 exe,是可以正确 返回结果的...

但什么也没改,编译为 64位 exe,就总是返回 false 了....


继续求解........
----------------------------------------------
谢谢各位大大
作者:
男 bahamut8348 (leonna) ★☆☆☆☆ -
普通会员
2018/2/22 14:07:25
7楼: bool FileIsUsed(const TCHAR * pszFileName)
{
  HANDLE hFile = CreateFile(pszFileName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  DWORD dwErrorCode = GetLastError();

  if (INVALID_HANDLE_VALUE != hFile)
    CloseHandle(hFile);

  return ERROR_SHARING_VIOLATION == dwErrorCode || ERROR_LOCK_VIOLATION == dwErrorCode;
}


int _tmain(int, TCHAR** argv)
{
  if (FileIsUsed(argv[0]))
    printf("used!\n");
  else
    printf("no used!");
  system("pause");
    return 0;
}


另外一个就是,兰州自己注意一下特殊目录。
32位和64位系统,对几个特殊目录的最终访问目录是不同的。比如program files, system32这些。
----------------------------------------------
--
作者:
男 moom (小新啊) ▲▲▲△△ -
普通会员
2018/2/22 14:57:12
8楼: 谢谢楼上,你的代码和我的一样...

但现在问题是 :  随便一个盘(DEF...)打开一个文件,如 exe/doc/pdf ,

我的代码编译为32位 exe,检测打开的文件,是可以正确 返回结果的...打开文件就返回 True...

但什么也没改,编译为 64位 exe,就总是返回 false 了....


继续求解........
----------------------------------------------
谢谢各位大大
作者:
男 bahamut8348 (leonna) ★☆☆☆☆ -
普通会员
2018/2/22 15:05:01
9楼: 怎么可能不一样。
此帖子包含附件:
PNG 图像
大小:35.1K
----------------------------------------------
--
作者:
男 crystalmoon (crystalmoon) ★☆☆☆☆ -
盒子活跃会员
2018/2/22 15:10:32
10楼: Const
NULL_Handle = 0;
INVALID_HANDLE_VALUE = -1;
----------------------------------------------
-
作者:
男 moom (小新啊) ▲▲▲△△ -
普通会员
2018/2/22 16:05:34
11楼: 谢谢各位...

bahamut8348 (leonna)..你的是 Cb吧

我用的是 Delphi , 不知道为什么 就是 64位不行....
----------------------------------------------
谢谢各位大大
作者:
男 nevergrief (孤独骑士) ★☆☆☆☆ -
盒子活跃会员
2018/2/22 18:31:06
12楼: 你做实验的文件是哪个?
是这个吗?
c:\Programs\delphi6\bin\delphi32.exe

建议改成c:\目录测试,Programs这个名字还是有可能被系统占用了(十多年前我就碰到过这个问题),或者被重定向了。

我不信这个问题不信,你最好留个QQ号交流吧。
----------------------------------------------
只有偏执狂才能生存!
作者:
男 merced (merced) ★☆☆☆☆ -
普通会员
2018/2/22 21:43:24
13楼: CreateFile这个API返回值是THandle类型,而不是HFILE类型
THandle在32/64位系统中分别为4/8字节,无符号
HFILE在在32/64位系统均为4字节,无符号
这样HFileRes就把CreateFile返回值的高32bit截断了,就不可能等于INVALID_HANDLE_VALUE了
----------------------------------------------
-
作者:
男 moom (小新啊) ▲▲▲△△ -
普通会员
2018/2/22 22:29:10
14楼: To: nevergrief (孤独骑士)
不是指定文件。。。是任意盘,任意一个 打开的 文件。。。

各位如果有  XE 以上版本,可以 编译 64位 exe 的  大大 们...

你们可以直接把 我的 代码 复制 后 试试...


to:  merced (merced)
你的应该是原因了....thx


不过如何改上面代码呢? 继续等待中....
----------------------------------------------
谢谢各位大大
作者:
男 abcjingtong (jingtong) ★☆☆☆☆ -
普通会员
2018/2/23 12:28:51
15楼: 把HFileRes的类型换为THandle就可以了(本来CreateFile返回的就是THandle类型(最终是NativeUInt类型即支持跨平台),不知你为什么赋值给一个HFILE类型),因为INVALID_HANDLE_VALUE = THandle(-1),所以Result := (HFileRes = INVALID_HANDLE_VALUE);比较是否相等时类型一致即可,此外你的代码中Button1Click中if...then后面的那行代码后面多了个;号。
----------------------------------------------
18114532@qq.com
作者:
男 earthsbest (全能中间件) ▲▲▲▲△ -
普通会员
2018/2/23 14:47:14
16楼: 13 楼正解!
----------------------------------------------
Delphi4Linux Delphi三层/FireDAC 技术群:734515869 http://www.cnblogs.com/rtcmw
作者:
男 moom (小新啊) ▲▲▲△△ -
普通会员
2018/3/2 14:14:00
17楼: 谢谢 13楼: 
**********
CreateFile这个API返回值是THandle类型,而不是HFILE类型
THandle在32/64位系统中分别为4/8字节,无符号
HFILE在在32/64位系统均为4字节,无符号
这样HFileRes就把CreateFile返回值的高32bit截断了,就不可能等于INVALID_HANDLE_VALUE了
**********

各位大大:
小生不才,请问如何把我的代码 改为 64位 可以使用呢?
----------------------------------------------
谢谢各位大大
作者:
男 earthsbest (全能中间件) ▲▲▲▲△ -
普通会员
2018/3/3 9:32:58
18楼: var
  HFileRes: THandle;

变量定义为这样就可以了。
----------------------------------------------
Delphi4Linux Delphi三层/FireDAC 技术群:734515869 http://www.cnblogs.com/rtcmw
作者:
男 moom (小新啊) ▲▲▲△△ -
普通会员
2018/3/3 14:45:32
19楼: 楼上 滔滔江水 啊.....
----------------------------------------------
谢谢各位大大
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行80.07813毫秒 RSS