Recent

Author Topic: [Solved] - Search for a file  (Read 7421 times)

Rayvenhaus

  • Jr. Member
  • **
  • Posts: 70
[Solved] - Search for a file
« on: March 21, 2017, 02:37:34 pm »
Good morning everyone. I've run into a bit of a issue with the following code:

Code: Pascal  [Select][+][-]
  1.   if FileExists('./sqlite3.dll') then
  2.     begin
  3.       frm_wyckersetup.uELED1.Color:=clLime;
  4.     end
  5.   else
  6.     begin
  7.       frm_wyckersetup.uEled1.Color:=clLime;
  8.       SearchCount:=0;
  9.       if FindFirst('sqlite3.dll', faAnyFile and faDirectory, SearchInfo)=0 then
  10.         begin
  11.           Repeat
  12.             Inc(SearchCount);
  13.             With SearchInfo do
  14.               begin
  15.                 If (Attr and faDirectory) = faDirectory then
  16.                   //Test
  17.               end;
  18.           until FindNext(SearchInfo)<>0;
  19.         end;
  20.         FindCLose(SearchInfo);
  21.         if SearchCount = 0 then
  22.           begin
  23.             Logger.Error('Missing sqlite3.dll.');
  24.             frm_wyckersetup.uEled1.Color:=clRed;
  25.             if MessageDlg('Missing Required File', 'Wycker can not start. SQL Library file (sqlite3.dll) is missing. Please locate this file and place it in the same directory that you installed Wycker in.', mtConfirmation, [mbYes],0) = mrYes then
  26.               begin
  27.                 Application.Terminate;
  28.               end;
  29.           end;
  30.     end;

What I'm trying to do is search the hard drive to see if the sqlite3.dll is available.  It should be available in the directory that ,y p[ropgram resides in and this snippet of code appears to work correctly if it's there or not, but this snippet does not appear to find the DLL if it resides anywhere else on the HD.

Am I doing something wrong?
« Last Edit: March 21, 2017, 11:28:54 pm by Rayvenhaus »

jacmoe

  • Full Member
  • ***
  • Posts: 249
    • Jacmoe's Cyber SoapBox
Re: Search for a file
« Reply #1 on: March 21, 2017, 02:56:49 pm »
Why not skip all of that and try to use a SQLite function?
If it fails, then the SQLite DLL can't be found/loaded.
more signal - less noise

sky_khan

  • Guest
Re: Search for a file
« Reply #2 on: March 21, 2017, 03:06:53 pm »
Which components do you use for sqlite ? AFAIK, standart SqlDB components requires sqlite3.dll present before your application loaded anyway. You have to load dll manually after your program loaded and use getProcAddress for each exported function of it for this to work otherwise OS wont load your program and gives missing library error before your search code get executed.
« Last Edit: March 21, 2017, 03:08:50 pm by SkyKhan »

jacmoe

  • Full Member
  • ***
  • Posts: 249
    • Jacmoe's Cyber SoapBox
Re: Search for a file
« Reply #3 on: March 21, 2017, 03:28:47 pm »
By the looks of it, he is writing a setup program, SkyKhan.
more signal - less noise

sky_khan

  • Guest
Re: Search for a file
« Reply #4 on: March 21, 2017, 03:52:46 pm »
Well, Ok. In that case,

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var
  3.   FileList: TStrings;
  4. begin
  5.   FileList:=FindAllFiles('C:\','sqlite3.dll');
  6.   Memo1.Lines.Assign(FileList);
  7.   FileList.Free;
  8. end;
  9.  

It will take some time if you search all disk, you must be patient.

Rayvenhaus

  • Jr. Member
  • **
  • Posts: 70
Re: Search for a file
« Reply #5 on: March 21, 2017, 03:53:36 pm »
Well, basically, I am adding database functions into my program, Wycker.  This is the first time I've ever worked with databases in Pascal and it's a learning curve. What I am trying to do it, on startup of the program, look to see if required files are present. If sqlite3.dll is missing, I want the program to exit.  If the database is missing, I'm going add code to create it. If the DLL is missing, I want to notify the user to install it, although my installation program will place it in the program directory when the program is installed.

The problem I'm seeing with the snippet above is that, if the required DLL is not in the program directory, it correctly identifies that and exists. But, what is they already have the DLL in the, for example, c:\windows\system32 directory?  If it's there, the program should be able to run.

sky_khan

  • Guest
Re: Search for a file
« Reply #6 on: March 21, 2017, 04:08:20 pm »
@Rayvenhaus, This is even more easy

FindDefaultExecutablePath('sqlite3.dll');

finds which dll would be loaded by searching system path
or returns empty string if there is none.
 

Rayvenhaus

  • Jr. Member
  • **
  • Posts: 70
Re: Search for a file
« Reply #7 on: March 21, 2017, 04:24:15 pm »
I can not find a reference to 'FindDefaultExecutablePath' anywhere.  Can you point me to where this is documented?

sky_khan

  • Guest
Re: Search for a file
« Reply #8 on: March 21, 2017, 04:47:35 pm »
Well, IDK about documentation. I prefer reading code if I have a chance.

Try this on new project,
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. begin
  3.   ShowMessage(FindDefaultExecutablePath('sqlite3.dll'));
  4. end;
  5.  

it will show you first match of sqlite3.dll in your system path. Now return to Lazarus, hold your CTRL key and click on "FindDefaultExecutablePath" in source editor. It will go to where it is defined. Then hold CTRL+Shift and press down arrow. It will go to where it is implemented. It is in FileUtil unit which is included in uses clause of your main form for default project. You can see what exactly this function is doing there.
« Last Edit: March 21, 2017, 04:49:28 pm by SkyKhan »

Rayvenhaus

  • Jr. Member
  • **
  • Posts: 70
Re: Search for a file
« Reply #9 on: March 21, 2017, 06:22:55 pm »
So, if I read that right, it will return a NULL if it does not find the file in the programs directory OR in the system paths.  Correct?

sky_khan

  • Guest
Re: Search for a file
« Reply #10 on: March 21, 2017, 06:45:34 pm »
On windows, yes. I thought that was what you wanted ?

Rayvenhaus

  • Jr. Member
  • **
  • Posts: 70
Re: Search for a file
« Reply #11 on: March 21, 2017, 07:23:07 pm »
Yep, windows, however, does this snippet you provided only search the system paths?

sky_khan

  • Guest
Re: Search for a file
« Reply #12 on: March 21, 2017, 07:45:13 pm »
Loading dynamic libraries from application's path is a windows thing. Normally on unix or linux,  executables or libraries is searched only on system path. It does not execute a program or load a library just because it is in your current path. They must be on system path. Thats why i said "on windows".

Whatever,
FindDefaultExecutablePath is exactly what you asked in your first post. 

It looks for your application path first and keeps looking every directory in your system path until it finds one or it returns an empty string. If you give Windows an absolute path to execute a program or load a dll it wont search  it just looks where you said otherwise if you give it only a filename, that is how Windows decides which exe or dll will be loaded. FindDefaultExecutablePath is imitation of how Windows search for exe or dlls. If I still could not explain it with my limited English sorry, I dont know how :(

Again,
FindDefaultExecutablePath is your answer.

Rayvenhaus

  • Jr. Member
  • **
  • Posts: 70
Re: Search for a file
« Reply #13 on: March 21, 2017, 09:49:25 pm »
That makes perfect sense.  And, yes it will help very much as it cuts way back on the lines of code needed. Here's what I have come up with to search the programs directory and the system paths:

Code: Pascal  [Select][+][-]
  1.   if FileExists('./sqlite3.dll') then
  2.     begin
  3.       frm_wyckersetup.uELED1.Color:=clLime;
  4.       Logger.Info('SQLite DLL found in program directory.');
  5.       //Activate Datebase Connection
  6.       SQLDBLibraryLoader1.ConnectionType:='SQLite3';
  7.       SQLDBLibraryLoader1.LibraryName := '.\sqlite3.dll';
  8.       SQLDBLibraryLoader1.Enabled := true;
  9.       SQLDBLibraryLoader1.LoadLibrary;
  10.     end
  11.   else
  12.     begin
  13.       searchResult := FindDefaultExecutablePath('sqlite3.dll');
  14.       if searchResult = '' then
  15.         begin
  16.           Logger.Error('Missing sqlite3.dll.');
  17.           frm_wyckersetup.uEled1.Color:=clRed;
  18.           if MessageDlg('Missing Required File', 'Wycker can not start. SQL Library file (sqlite3.dll) is missing. Please locate this file and place it in the same directory that you installed Wycker in.', mtConfirmation, [mbYes],0) = mrYes then
  19.             begin
  20.               Application.Terminate;
  21.             end
  22.         end
  23.       else
  24.         begin
  25.           Logger.Info('SQLite DLL library found in system path.');
  26.           frm_wyckersetup.uEled1.Color:=clLime;
  27.           //Activate Datebase Connection
  28.           SQLDBLibraryLoader1.ConnectionType:='SQLite3';
  29.           SQLDBLibraryLoader1.LibraryName := '.\sqlite3.dll';
  30.           SQLDBLibraryLoader1.Enabled := true;
  31.           SQLDBLibraryLoader1.LoadLibrary;
  32.         end
  33.     end;
  34.  

Kays

  • Hero Member
  • *****
  • Posts: 569
  • Whasup!?
    • KaiBurghardt.de
Re: Search for a file
« Reply #14 on: March 21, 2017, 10:28:23 pm »
Why not skip all of that and try to use a SQLite function?
If it fails, then the SQLite DLL can't be found/loaded.
Bad. I hate programs not providing some meaningful error messages.
[…]If sqlite3.dll is missing, I want the program to exit.[…]
Good, that way you can either print “could not start, because DB not found” or say that the DB library you're using failed.

PS: Worst error message ever: “ERROR: unknown error”  >:(
« Last Edit: March 21, 2017, 10:30:41 pm by Kays »
Yours Sincerely
Kai Burghardt

 

TinyPortal © 2005-2018