Delphi判断某个Word文件是否已打开,如已打开则关闭

时间:2021-05-22 23:49:10
如果某个名为:‘我的文档.doc’的Word文档已被打开,该如何使用Delphi判断它已打开,如果已打开就使用Delphi关闭该文档。

8 个解决方案

#1


delphi中一般使用CreateOleObject操作word
可以参考http://www.codes51.com/article/detail_23118.html

#2


function KillProcess(AFile: string; AEffectFirst: Boolean = True): WORD; overload;
implementation

{$R *.dfm}
{AFile: 要结束的进程
AEffectFirst: 是否只结束第一个找到的进程

可以只输入EXE名称, 或者全路径+文件名, 或者只是某个文件路径
如果输入的只是某个路径, 则关闭属于这个路径下的所有进程}
function KillProcess(AFile: string; AEffectFirst: Boolean = True): WORD; overload;
const
  PROCESS_TERMINATE = $0001;
var
  nContinueLoop: BOOL;
  nSnapShotHandle: THandle;
  nProcessEntry32: TProcessEntry32;
  nSelfID, nPrHandle: Cardinal;
  nMBF: array [0..MAX_PATH] of Char;
  nCMode: Byte; {0:检测全路径文件, 1:仅检测文件 2:仅检测路径}
  nCPath, nCFile, nStr, nFile, nPath: string;
begin
  Result := 0;
  AFile := UpperCase(AFile);
  nCPath := ExtractFilePath(AFile);
  nCFile := ExtractFileName(AFile);

  if (nPath <> '') and (nCFile <> '') then
    nCMode := 0
  else if nCFile <> '' then
    nCMode := 1
  else if nCPath <> '' then
    nCMode := 2
  else
    Exit;

  nSelfID := GetCurrentProcessID;
  nSnapShotHandle := CreateToolhelp32SnapShot(TH32CS_SNAPPROCESS, 0);
  try
    nProcessEntry32.dwSize := SizeOf(nProcessEntry32);
    nContinueLoop := Process32First(nSnapShotHandle, nProcessEntry32);
    while nContinueLoop do
    begin
      if nProcessEntry32.th32ProcessID <> nSelfID then
      begin
        nStr := UpperCase(nProcessEntry32.szExeFile);
        nFile := ExtractFileName(nStr);
        nPrHandle := OpenProcess(PROCESS_ALL_ACCESS, False, nProcessEntry32.th32ProcessID);
        try
          if nCMode <> 1 then
          begin
            nPath := ExtractFilePath(nStr);
            if nPath = '' then
            begin
              if GetModuleFileNameEx(nPrHandle, 0, @nMBF[0], SizeOf(nMBF)) > 0 then
                nPath := UpperCase(ExtractFilePath(nMBF));
            end;
          end;

          if ((nCMode = 0) and (nPath = nCPath) and (nFile = nCFile)) {全路径文件名相同}
            or ((nCMode = 1) and (nFile = nCFile)) {文件名相同}
            or ((nCMode = 2) and (Copy(nPath, 1, Length(nCPath)) = nCPath)) {路径包含} then
          begin
            TerminateProcess(nPrHandle, 0); {强制关闭进程}
            if AEffectFirst then
              Break;
          end;
        finally
          CloseHandle(nPrHandle);
        end;
      end;
      nContinueLoop := Process32Next(nSnapShotHandle, nProcessEntry32);
    end;
  finally
    CloseHandle(nSnapShotHandle);
  end;
end;

procedure TFormMain.btnkill2Click(Sender: TObject);
begin
  KillProcess(PChar(edtname2.Text) ,False);
end;

用函数去找句柄,然后去关闭他。无论word还是别的exe

#3


Delphi判断某个Word文件是否已打开,如已打开则关闭
这个要求比较蛋疼啊,比较好的办法应该是从文件驱动入手
比较蛋疼的办法,就是FileOpen一下,然后写入一个字节内容,保存,如果可以保存成功,说明没打开(然后再删除最后的一个写入的字节内容),否则说明打开了

#4


引用 1 楼 chenyq2008 的回复:
delphi中一般使用CreateOleObject操作word
可以参考http://www.codes51.com/article/detail_23118.html


这个方法达不到要求啊 Delphi判断某个Word文件是否已打开,如已打开则关闭

#5


引用 2 楼 sxper 的回复:
function KillProcess(AFile: string; AEffectFirst: Boolean = True): WORD; overload;
implementation

{$R *.dfm}
{AFile: 要结束的进程
AEffectFirst: 是否只结束第一个找到的进程

可以只输入EXE名称, 或者全路径+文件名, 或者只是某个文件路径
如果输入的只是某个路径, 则关闭属于这个路径下的所有进程}
function KillProcess(AFile: string; AEffectFirst: Boolean = True): WORD; overload;
const
  PROCESS_TERMINATE = $0001;
var
  nContinueLoop: BOOL;
  nSnapShotHandle: THandle;
  nProcessEntry32: TProcessEntry32;
  nSelfID, nPrHandle: Cardinal;
  nMBF: array [0..MAX_PATH] of Char;
  nCMode: Byte; {0:检测全路径文件, 1:仅检测文件 2:仅检测路径}
  nCPath, nCFile, nStr, nFile, nPath: string;
begin
  Result := 0;
  AFile := UpperCase(AFile);
  nCPath := ExtractFilePath(AFile);
  nCFile := ExtractFileName(AFile);

  if (nPath <> '') and (nCFile <> '') then
    nCMode := 0
  else if nCFile <> '' then
    nCMode := 1
  else if nCPath <> '' then
    nCMode := 2
  else
    Exit;

  nSelfID := GetCurrentProcessID;
  nSnapShotHandle := CreateToolhelp32SnapShot(TH32CS_SNAPPROCESS, 0);
  try
    nProcessEntry32.dwSize := SizeOf(nProcessEntry32);
    nContinueLoop := Process32First(nSnapShotHandle, nProcessEntry32);
    while nContinueLoop do
    begin
      if nProcessEntry32.th32ProcessID <> nSelfID then
      begin
        nStr := UpperCase(nProcessEntry32.szExeFile);
        nFile := ExtractFileName(nStr);
        nPrHandle := OpenProcess(PROCESS_ALL_ACCESS, False, nProcessEntry32.th32ProcessID);
        try
          if nCMode <> 1 then
          begin
            nPath := ExtractFilePath(nStr);
            if nPath = '' then
            begin
              if GetModuleFileNameEx(nPrHandle, 0, @nMBF[0], SizeOf(nMBF)) > 0 then
                nPath := UpperCase(ExtractFilePath(nMBF));
            end;
          end;

          if ((nCMode = 0) and (nPath = nCPath) and (nFile = nCFile)) {全路径文件名相同}
            or ((nCMode = 1) and (nFile = nCFile)) {文件名相同}
            or ((nCMode = 2) and (Copy(nPath, 1, Length(nCPath)) = nCPath)) {路径包含} then
          begin
            TerminateProcess(nPrHandle, 0); {强制关闭进程}
            if AEffectFirst then
              Break;
          end;
        finally
          CloseHandle(nPrHandle);
        end;
      end;
      nContinueLoop := Process32Next(nSnapShotHandle, nProcessEntry32);
    end;
  finally
    CloseHandle(nSnapShotHandle);
  end;
end;

procedure TFormMain.btnkill2Click(Sender: TObject);
begin
  KillProcess(PChar(edtname2.Text) ,False);
end;

用函数去找句柄,然后去关闭他。无论word还是别的exe


谢谢你,我会试一下你提议的方法的

#6


引用 3 楼 suiyunonghen 的回复:
Delphi判断某个Word文件是否已打开,如已打开则关闭
这个要求比较蛋疼啊,比较好的办法应该是从文件驱动入手
比较蛋疼的办法,就是FileOpen一下,然后写入一个字节内容,保存,如果可以保存成功,说明没打开(然后再删除最后的一个写入的字节内容),否则说明打开了


貌似往这个方向想确实有点希望,但是,我主要想解决的是关闭掉某个已打开的指定文档,其他的不关闭。

#7


遍历Documents 对象的    使用Close 方法 关闭单个文件不行?

#8


用独占方式打开文件OpenFile,如果返回错误则表明文档已经打开,然后遍历进程,找到进程,然后kill他

#1


delphi中一般使用CreateOleObject操作word
可以参考http://www.codes51.com/article/detail_23118.html

#2


function KillProcess(AFile: string; AEffectFirst: Boolean = True): WORD; overload;
implementation

{$R *.dfm}
{AFile: 要结束的进程
AEffectFirst: 是否只结束第一个找到的进程

可以只输入EXE名称, 或者全路径+文件名, 或者只是某个文件路径
如果输入的只是某个路径, 则关闭属于这个路径下的所有进程}
function KillProcess(AFile: string; AEffectFirst: Boolean = True): WORD; overload;
const
  PROCESS_TERMINATE = $0001;
var
  nContinueLoop: BOOL;
  nSnapShotHandle: THandle;
  nProcessEntry32: TProcessEntry32;
  nSelfID, nPrHandle: Cardinal;
  nMBF: array [0..MAX_PATH] of Char;
  nCMode: Byte; {0:检测全路径文件, 1:仅检测文件 2:仅检测路径}
  nCPath, nCFile, nStr, nFile, nPath: string;
begin
  Result := 0;
  AFile := UpperCase(AFile);
  nCPath := ExtractFilePath(AFile);
  nCFile := ExtractFileName(AFile);

  if (nPath <> '') and (nCFile <> '') then
    nCMode := 0
  else if nCFile <> '' then
    nCMode := 1
  else if nCPath <> '' then
    nCMode := 2
  else
    Exit;

  nSelfID := GetCurrentProcessID;
  nSnapShotHandle := CreateToolhelp32SnapShot(TH32CS_SNAPPROCESS, 0);
  try
    nProcessEntry32.dwSize := SizeOf(nProcessEntry32);
    nContinueLoop := Process32First(nSnapShotHandle, nProcessEntry32);
    while nContinueLoop do
    begin
      if nProcessEntry32.th32ProcessID <> nSelfID then
      begin
        nStr := UpperCase(nProcessEntry32.szExeFile);
        nFile := ExtractFileName(nStr);
        nPrHandle := OpenProcess(PROCESS_ALL_ACCESS, False, nProcessEntry32.th32ProcessID);
        try
          if nCMode <> 1 then
          begin
            nPath := ExtractFilePath(nStr);
            if nPath = '' then
            begin
              if GetModuleFileNameEx(nPrHandle, 0, @nMBF[0], SizeOf(nMBF)) > 0 then
                nPath := UpperCase(ExtractFilePath(nMBF));
            end;
          end;

          if ((nCMode = 0) and (nPath = nCPath) and (nFile = nCFile)) {全路径文件名相同}
            or ((nCMode = 1) and (nFile = nCFile)) {文件名相同}
            or ((nCMode = 2) and (Copy(nPath, 1, Length(nCPath)) = nCPath)) {路径包含} then
          begin
            TerminateProcess(nPrHandle, 0); {强制关闭进程}
            if AEffectFirst then
              Break;
          end;
        finally
          CloseHandle(nPrHandle);
        end;
      end;
      nContinueLoop := Process32Next(nSnapShotHandle, nProcessEntry32);
    end;
  finally
    CloseHandle(nSnapShotHandle);
  end;
end;

procedure TFormMain.btnkill2Click(Sender: TObject);
begin
  KillProcess(PChar(edtname2.Text) ,False);
end;

用函数去找句柄,然后去关闭他。无论word还是别的exe

#3


Delphi判断某个Word文件是否已打开,如已打开则关闭
这个要求比较蛋疼啊,比较好的办法应该是从文件驱动入手
比较蛋疼的办法,就是FileOpen一下,然后写入一个字节内容,保存,如果可以保存成功,说明没打开(然后再删除最后的一个写入的字节内容),否则说明打开了

#4


引用 1 楼 chenyq2008 的回复:
delphi中一般使用CreateOleObject操作word
可以参考http://www.codes51.com/article/detail_23118.html


这个方法达不到要求啊 Delphi判断某个Word文件是否已打开,如已打开则关闭

#5


引用 2 楼 sxper 的回复:
function KillProcess(AFile: string; AEffectFirst: Boolean = True): WORD; overload;
implementation

{$R *.dfm}
{AFile: 要结束的进程
AEffectFirst: 是否只结束第一个找到的进程

可以只输入EXE名称, 或者全路径+文件名, 或者只是某个文件路径
如果输入的只是某个路径, 则关闭属于这个路径下的所有进程}
function KillProcess(AFile: string; AEffectFirst: Boolean = True): WORD; overload;
const
  PROCESS_TERMINATE = $0001;
var
  nContinueLoop: BOOL;
  nSnapShotHandle: THandle;
  nProcessEntry32: TProcessEntry32;
  nSelfID, nPrHandle: Cardinal;
  nMBF: array [0..MAX_PATH] of Char;
  nCMode: Byte; {0:检测全路径文件, 1:仅检测文件 2:仅检测路径}
  nCPath, nCFile, nStr, nFile, nPath: string;
begin
  Result := 0;
  AFile := UpperCase(AFile);
  nCPath := ExtractFilePath(AFile);
  nCFile := ExtractFileName(AFile);

  if (nPath <> '') and (nCFile <> '') then
    nCMode := 0
  else if nCFile <> '' then
    nCMode := 1
  else if nCPath <> '' then
    nCMode := 2
  else
    Exit;

  nSelfID := GetCurrentProcessID;
  nSnapShotHandle := CreateToolhelp32SnapShot(TH32CS_SNAPPROCESS, 0);
  try
    nProcessEntry32.dwSize := SizeOf(nProcessEntry32);
    nContinueLoop := Process32First(nSnapShotHandle, nProcessEntry32);
    while nContinueLoop do
    begin
      if nProcessEntry32.th32ProcessID <> nSelfID then
      begin
        nStr := UpperCase(nProcessEntry32.szExeFile);
        nFile := ExtractFileName(nStr);
        nPrHandle := OpenProcess(PROCESS_ALL_ACCESS, False, nProcessEntry32.th32ProcessID);
        try
          if nCMode <> 1 then
          begin
            nPath := ExtractFilePath(nStr);
            if nPath = '' then
            begin
              if GetModuleFileNameEx(nPrHandle, 0, @nMBF[0], SizeOf(nMBF)) > 0 then
                nPath := UpperCase(ExtractFilePath(nMBF));
            end;
          end;

          if ((nCMode = 0) and (nPath = nCPath) and (nFile = nCFile)) {全路径文件名相同}
            or ((nCMode = 1) and (nFile = nCFile)) {文件名相同}
            or ((nCMode = 2) and (Copy(nPath, 1, Length(nCPath)) = nCPath)) {路径包含} then
          begin
            TerminateProcess(nPrHandle, 0); {强制关闭进程}
            if AEffectFirst then
              Break;
          end;
        finally
          CloseHandle(nPrHandle);
        end;
      end;
      nContinueLoop := Process32Next(nSnapShotHandle, nProcessEntry32);
    end;
  finally
    CloseHandle(nSnapShotHandle);
  end;
end;

procedure TFormMain.btnkill2Click(Sender: TObject);
begin
  KillProcess(PChar(edtname2.Text) ,False);
end;

用函数去找句柄,然后去关闭他。无论word还是别的exe


谢谢你,我会试一下你提议的方法的

#6


引用 3 楼 suiyunonghen 的回复:
Delphi判断某个Word文件是否已打开,如已打开则关闭
这个要求比较蛋疼啊,比较好的办法应该是从文件驱动入手
比较蛋疼的办法,就是FileOpen一下,然后写入一个字节内容,保存,如果可以保存成功,说明没打开(然后再删除最后的一个写入的字节内容),否则说明打开了


貌似往这个方向想确实有点希望,但是,我主要想解决的是关闭掉某个已打开的指定文档,其他的不关闭。

#7


遍历Documents 对象的    使用Close 方法 关闭单个文件不行?

#8


用独占方式打开文件OpenFile,如果返回错误则表明文档已经打开,然后遍历进程,找到进程,然后kill他