Solved

Get the full path of an Application when it is started through a LAN

Posted on 2006-06-27
9
580 Views
Last Modified: 2010-04-05
var
  PathExe: string;
begin
  PathExe := ExtractFilePath(Application.ExeName);
//.....................................................................

I have no problem when the Application is ran on a Local Computer to get its full path ....
But I need to get the full pat when I start the Application through a LAN.

I was advised to use:
function ExpandUNCFileName(const FileName: string): string;

but it was not successfull:

var
  PathExe: string;
begin
  PathExe := ExtractFilePath(ExpandUNCFileName(Application.ExeName));
//.....................................................................

So I am waiting for a solution.
Thanks.

Emil.
0
Comment
Question by:esoftbg
9 Comments
 
LVL 26

Expert Comment

by:Russell Libby
ID: 16998228
Emil,

What are you looking for exactly? If you are running your application from a network share that is not mapped to a drive letter, eg:

\\server\sharename\application.exe

then the file path would return:

\\server\sharename\

this IS the path that the application is running from. It may be a UNC, but its still a valid path. It is *possible* to check to see if a drive letter is mapped to this network share (then return the drive letter substituted for the unc), but if the share is not mapped, then the UNC is all you are going to get. Perhaps you could explain why you find this an issue/problem?

Regards,
Russell
0
 
LVL 9

Expert Comment

by:sun4sunday
ID: 16998279
Hi..you alrady asked the same question once

http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_21898512.html

Russell explaine it very well.

What error are you getting?

sun4sunday
0
 
LVL 12

Author Comment

by:esoftbg
ID: 17002876
I would like to copy my application on a LAN Computer to say into a path C:\....\Emil.
My application works with a FireBird database. This database is located in a subpath named C:\....\Emil\DB\Data.FDB
Then I do install of FireBird on this machine and it becomes a FireBird Server.
When I run my application it does:
//.......................................................................
IBDB is a TIBDataBase component
//.......................................................................
procedure TIBModule.DataModuleCreate(Sender: TObject);
var
  SP_FDB: string;
  SF_FDB: string;
  PathExe:string;
begin
//  PathExe := ExtractFilePath(Application.ExeName);
  PathExe := ExtractFilePath(ExpandUNCFileName(Application.ExeName));
  SP_FDB  := PathExe + 'DB\';
  SF_FDB  := 'DATA.FDB';
  try
    if FileExists(SP_FDB+SF_FDB) then
    begin
      begin
        IBDB.DatabaseName := SD_GDB + SF_GDB;
        IBDB.Params.Values['lc_ctype']  := 'WIN1251';
        IBDB.Params.Values['user_name'] := 'SYSDBA';
        IBDB.Params.Values['password']  := 'masterkey';
        IBDB.Connected := True;
        IBDS_STATUS.Active := True;
        IBDS_MANIPULS.Active := True;
        IBQ_PATIENTS.Active := True;
        IBQ_PATIENTS_MANIPULS.Active := True;
        IBDS_PATIENTS_MANIPULS.Active := True;
      end;
    end;
  except
    on E : Exception do
    begin
//      ShowMessage(e.message);
      if IBDB.Connected then
        IBDB.Connected := False;
      Application.Terminate;
    end;
  end;
end;
//.......................................................................
On the server machine there is no problem - it works fine.

But I go on the client machine, browse through the LAN, find my application and start it. There occurs an error I forgot the message, but it is about "can't find the path \Emil\DB".
At home I have not LAN, so I can't test this case under Delphi.
I have this error when I test my application on real environment.
I hope I described my problem good enough.

Emil.
0
 
LVL 26

Expert Comment

by:Russell Libby
ID: 17004360
Emil,

Please enlighten me on the following code then....

---

 SP_FDB  := PathExe + 'DB\';
  SF_FDB  := 'DATA.FDB';
  try
    if FileExists(SP_FDB+SF_FDB) then
    begin
      begin
        IBDB.DatabaseName := SD_GDB + SF_GDB;
---

It seems to me that SP_FDB + SF_FDB do exist, otherwise the check to FileExists would fail (would not throw exception), and you would never get to setting the properties for IBDB. But if the file does exist, you then turn around and assign the following:

  IBDB.DatabaseName := SD_GDB + SF_GDB; // Where do these 2 vars come from???

Shouldn't that be SP_FDB + SF_FDB ? Otherwise, why bother going to the trouble of getting the app path and checking that the file exists?

---

Russell

0
Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

 
LVL 17

Expert Comment

by:TheRealLoki
ID: 17005982
I suspect the error you are getting is a firebird connect error.
when connecting via firebird to a firebird server on another machine, you need a different notation than just

f:\database\data\somefile.fdb (f: being a mapped drive)  <--- this is wrong!
because the server is NOT local, so F:\ thinks it is local.

you need it to be :-
(TCP)
Machinename:C:\database\data\somefile.fdb
or
(NetBIOS)
\\Machinename\ShareName\database\data\somefile.fdb  

you could check if PathExe has '\\' at the start and put the correct notation in for the firebird databasename
0
 
LVL 12

Author Comment

by:esoftbg
ID: 17010059
Russell,

When I copy my application on the server, the path of the Application and it subpath 'DB\' do exist.
It may be C:\Emil\DB or D:\Program Files\Emil\DB, or F:\Applications\Emil\DB, or .......
I don't know what happens after I go home. My customer, may to make desicion to move whole directory from C:\Emil\DB to E:\Some Applications\Emil\DB ....
I would like that my application to work without problems ONLY IF THE FOLDER WHERE IT RESIDES CONTAINS THE SUBPATH \DB AND THERE IS THE REAL FIREBIRD DATABASE 'DATA.FDB'.

TheRealLoki,
May be you are right and I need to replace '\\' into the PathExe whith ':\'.
I will try it, but I will go to the office with the LAN at saturday.
At saturday I will know will run successfully my application with LAN or not ....


Thank you both.
Emil.
0
 
LVL 26

Accepted Solution

by:
Russell Libby earned 250 total points
ID: 17011798

Emil, I **GET** what you are trying to do, but you still failed to answer my simple question;

>> WHERE ARE SD_GDB and SF_GDB SET FROM?

Because (according to your code), this is what you use to set the database name:

>> IBDB.DatabaseName := SD_GDB + SF_GDB;

Even though you LOADED THE APPLICATION PATH INTO:

 SP_FDB  := PathExe + 'DB\'; // SP_FDB and SD_GDB are 2 DIFFERENT VARIABLES
  SF_FDB  := 'DATA.FDB';      // SF_FDB and SF_GDB are 2 DIFFERENT VARIABLES

This means that:
- You failed to show us pertinent code, eg what and where do SD_GDB and SF_GDB get set from
or
- You have a coding error, and really meant to use SP_FDB and SF_FDB

And you misinterpreted what TheRealLoki stated. If the path is coming back as X:\ where X:\ is a mapped network drive, the path needs to converted to a UNC format of \\server\share.  

In fact, I'll make is even simpler for you. Just change the code to this and let us know the results:

procedure TIBModule.DataModuleCreate(Sender: TObject);
var  szAppPath:     String;
     szDBFile:      String;
     dwSize:        DWORD;
begin

  // This will return the application path as either x:\path or \\server\share
  szAppPath:=ExcludeTrailingBackslash(ExtractFilePath(Application.ExeName));

  // Now append the database filename of \DB\DATA.FDB
  szDBFile:=Format('%s\DB\DATA.FDB', [szAppPath]);

  // Exception trap
  try
     // Check for file existence
     if FileExists(szDBFile) then
     begin
        // File exists, now determine if the a drive letter was used and if the drive
        // is mapped to a network share.
        if ((szDBFile[1] in ['D'..'Z', 'd'..'z']) and (szDBFile[2] = ':')) then
        begin
           // Set buffer size
           dwSize:=MAX_PATH;
           // Allocate a buffer for results
           SetLength(szAppPath, dwSize);
           // Check for a network connection
           if (WNetGetConnection(PChar(Copy(szDBFile, 1, 2)), Pointer(szAppPath), dwSize) = ERROR_SUCCESS) then
           begin
              // Truncate the buffer
              SetLength(szAppPath, StrLen(Pointer(szAppPath)));
              // Remove the drive letter
              Delete(szDBFile, 1, 2);
              // Update the path using the UNC
              szDBFile:=szAppPath+szDBFile;
              // Verify the file through netbios check
              if not(FileExists(szDBFile)) then raise EWin32Error.Create(SysErrorMessage(ERROR_FILE_NOT_FOUND));
           end;
        end;
        // Set the correct database file name
        IBDB.DatabaseName := szDBFile;
        IBDB.Params.Values['lc_ctype']  := 'WIN1251';
        IBDB.Params.Values['user_name'] := 'SYSDBA';
        IBDB.Params.Values['password']  := 'masterkey';
        IBDB.Connected := True;
        IBDS_STATUS.Active := True;
        IBDS_MANIPULS.Active := True;
        IBQ_PATIENTS.Active := True;
        IBQ_PATIENTS_MANIPULS.Active := True;
        IBDS_PATIENTS_MANIPULS.Active := True;
     end
     else
        // Raise exception indicating that the file can't be found
        raise EWin32Error.Create(SysErrorMessage(ERROR_FILE_NOT_FOUND));
  except
     on E: Exception do
     begin
        if IBDB.Connected then IBDB.Connected:=False;
        Application.Terminate;
     end;
  end;

end;


0
 
LVL 12

Author Comment

by:esoftbg
ID: 17011991
Russell,
It is my stupid and very big mistake

>  SP_FDB  := PathExe + 'DB\'; // SP_FDB and SD_GDB are 2 DIFFERENT VARIABLES
>  SF_FDB  := 'DATA.FDB';      // SF_FDB and SF_GDB are 2 DIFFERENT VARIABLES

Please ignore the variables SD_GDB and SF_GDB
it must to be:
        IBDB.DatabaseName := SP_FDB + SF_FDB;

Excuse me again for this confusing mistake.

Thank you very much for your code, I will test it as soon as is possible for me.

Emil.
0
 
LVL 12

Author Comment

by:esoftbg
ID: 17012120
Russell,

Your code works perfect on my single machine, I will test it with LAN machines at saturday ....

Thank you again,
Emil.
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now