Recent

Author Topic: [SOLVED] Identifier not found "CloseHandle"  (Read 170 times)

fatmonk

  • Full Member
  • ***
  • Posts: 192
[SOLVED] Identifier not found "CloseHandle"
« on: August 14, 2019, 11:57:51 am »
I'm using the following (from an old project and before that probably from these forums) to detect if my application is already running, but I get a compile time Identifier not found for Closehandle.

Code: [Select]
function TMainForm.WindowsProcIsRunning(const ExeName: string): integer;
var
  ContinueLoop: BOOL;
  FSnapshotHandle: THandle;
  FProcessEntry32: TProcessEntry32;
begin
  FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  FProcessEntry32.dwSize := SizeOf(FProcessEntry32);
  ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);
  Result := 0;
  while integer(ContinueLoop) <> 0 do
    begin
    if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) =
      UpperCase(ExeName)) or (UpperCase(FProcessEntry32.szExeFile) =
      UpperCase(ExeName))) then
      begin
      Inc(Result);
      end;
    ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
    end;
  CloseHandle(FSnapshotHandle);
end;

in my uses I have the following to support this: LCLType, Process, JwaTlHelp32.

Thanks,

FM

« Last Edit: August 14, 2019, 01:10:35 pm by fatmonk »

GetMem

  • Hero Member
  • *****
  • Posts: 3476
Re: Identifier not found "CloseHandle"
« Reply #1 on: August 14, 2019, 12:10:21 pm »
Add the windows unit to the uses.

fatmonk

  • Full Member
  • ***
  • Posts: 192
Re: Identifier not found "CloseHandle"
« Reply #2 on: August 14, 2019, 12:18:35 pm »
When I do that my use of GetEnvironmentVariable() breaks :-(

(I forgot I'd already tried that yesterday!).

-FM
« Last Edit: August 14, 2019, 01:10:51 pm by fatmonk »

fatmonk

  • Full Member
  • ***
  • Posts: 192
Re: Identifier not found "CloseHandle"
« Reply #3 on: August 14, 2019, 12:20:33 pm »
Adding windows to uses also seems to break DeleteFile.

-FM
« Last Edit: August 14, 2019, 12:36:00 pm by fatmonk »

Thaddy

  • Hero Member
  • *****
  • Posts: 8457
Re: Identifier not found "CloseHandle"
« Reply #4 on: August 14, 2019, 12:25:40 pm »
Fully qualify those should work:
Code: Pascal  [Select]
  1. windows.CloseHandle;
  2. windows.GetENvironmentVariable  //or the one in one of your units.
  3. // maybe also windows.ttDeleteFile
  4.  
But if that works there is something seriously wrong with your code: duplicate implementation names in different units that do not fully match.
GetENvironmentVariable is a windows API function and the version from windows is correct.
« Last Edit: August 14, 2019, 12:29:05 pm by Thaddy »
Read the manuals and if you are a professional get a proper education in computer science. Makes the forum a lot cleaner.

fatmonk

  • Full Member
  • ***
  • Posts: 192
Re: Identifier not found "CloseHandle"
« Reply #5 on: August 14, 2019, 12:42:24 pm »
It looks like GetEnvironmentVariable and DeleteFile are both coming from sysutils.

Fully qualifying those to sysutils.GetEnvironmentVariable and sysutils.DeleteFile and including windows for the CloseHandle seems to have fixed it.

Is that odd that I'm using versions from sysutils?

-FM

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 7297
Re: Identifier not found "CloseHandle"
« Reply #6 on: August 14, 2019, 12:46:48 pm »
(or put the windows unit first in the unit clauses list)

fatmonk

  • Full Member
  • ***
  • Posts: 192
Re: Identifier not found "CloseHandle"
« Reply #7 on: August 14, 2019, 12:54:46 pm »
I keep forgetting about the order determining precedence!

I quite like fully qualifying for clarity, but thanks for reminding me of that.

-FM

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 7297
Re: [SOLVED] Identifier not found "CloseHandle"
« Reply #8 on: August 14, 2019, 01:47:41 pm »
I use both. I mentally order units in layers, and maintain a rough order of units in the uses clause that way, in larger uses clauses sometimes adding a linefeed to distinguish.

API units are typically on the deepest shell, general purpose RTL units like sysutils are a bit higher, and my own general purpose units a level more, and then framework, and then application specific etc.

This is not entirely fixed, in something that is mostly API the order could be different, but usually that is not even  a problem, since such units usually have few units in clauses anyway.

I rarely use qualification in normal code, I've had enough of micromanaging that during my years of Modula2. Great idea, not too convinced of the practicalities. The most I use qualification is in type aliases.