windowsdelphiwinapi

How to check if a network drive is available, instantly?


In my Windows computer, I have some network drives mapped. At a given time, I want to check which drive is available and which is not. Every method I used (WNetGetConnection, GetDiskFreeSpaceEx, GetVolumeInformation, ...) blocks my program for about a minute if that drive is not available (server not online). I guess it has a timeout waiting for the drive to connect.

Is there a way to check this without blocking my program? I don't want to use another thread just for that.


Solution

  • Because the Windows API that is called to retrieve the folder has its own delay (which cannot be changed), you have no other option but to use a thread and handle the event yourself.

    I achieve this by attempting to access the directory in a separate thread. If the timeout is reached, I exit the function. This does not completely free the main thread from waiting, but it makes the waiting time more manageable until you receive a response.

    A function could look like this:

    function NetworkPathAvailableWithTimeOut(const _NetworkPath: string; _TimeOut: Cardinal): Boolean;
    var
      l_PathAvailable: Boolean;
      l_EndTime: UInt64;
      l_TaskDone: Boolean;
    begin
      l_PathAvailable := False;
      l_TaskDone := False;
      l_EndTime := GetTickCount64 + _TimeOut;
    
      // Run the check in a separate thread to avoid blocking
      TTask.Run(
        procedure
        begin
          l_PathAvailable := System.SysUtils.DirectoryExists(_NetworkPath);
          l_TaskDone := True;
        end
      );
    
      // Wait for the task to complete or timeout
      while not l_TaskDone do
      begin
        if GetTickCount64 >= l_EndTime then
          Exit(False); // Timeout reached, assume unavailable
        Sleep(50); // Prevent CPU overuse
      end;
    
      Result := l_PathAvailable;
    end;