Icon View Thread

The following is the text of the current message along with any replies.
Messages 1 to 8 of 8 total
Thread Help with app setup over a lan (say 2 users)
Wed, Nov 16 2011 6:11 AMPermanent Link

kamran

Hi

Just needed some guidance as to what is the best way to set up my application to work over
a local area network using a shared folder / simple share

c:/computer1/app       (data + software)
c:/computer2/app       (software)

The problem I have is the computer name and folder might be different each time the software is installed.

what code and at what point do I set the relevant parameters to ensure that the data and software
recognise each other

Is there an easy way to do this in the dbisam software with special consideration
while developing the software and later for installation to any other shared folder.

Thanks for your help in advance

best regards

Kamran
Wed, Nov 16 2011 6:44 AMPermanent Link

Roy Lambert

NLH Associates

Team Elevate Team Elevate

kamran


My suggestion would be:

1. Use a directory outside of the MS recommended structure (ie don't put the software into Program Files)
2. Store the data in a sub-directory in the directory the software is installed in
3. In the app use \data as the path to the database for the tables

All that's needed then is to set up a shortcut on both users PCs pointing to the exe

It may not be the best approach but its a nice easy one

Roy Lambert [Team Elevate]
Wed, Nov 16 2011 7:42 AMPermanent Link

kamran

Thanks Roy thats helpful..

But in particular I wanted to know:

eg I have a TDBISAMDatabase Directory setting of  "\\Computer1\app"
which is where the data and software is all stored while i am developing it.
All works fine while I am developing.

Then later on I needed a good way of setting where the software and data is going to be installed
within my software.  I am guessing that I should store the directory path in a text file and read it in
to the software so that after the install everying works fine on a computer in which you do not know
the share information or network setup prior to installation.

Should this directory path be read/set on the beforeconnect event ?
or am I missing something here.

If that is the case then i can just keep a simple text file with the directory path stored in it.


Thanks


Kamran

Roy Lambert wrote:

kamran


My suggestion would be:

1. Use a directory outside of the MS recommended structure (ie don't put the software into Program Files)
2. Store the data in a sub-directory in the directory the software is installed in
3. In the app use \data as the path to the database for the tables

All that's needed then is to set up a shortcut on both users PCs pointing to the exe

It may not be the best approach but its a nice easy one

Roy Lambert [Team Elevate]
Wed, Nov 16 2011 8:35 AMPermanent Link

Raul

Team Elevate Team Elevate

Kamran,

The best way to do it as suggested by Roy is to set database path dynamically at runtime relative to the exe path. This way you do not need to store anything and user can eve move the exe and database to new folder without anythign breaking.

Your exe can obtain its own path when running (e.g. ExtractFilePath (ParamStr(0))) and then you just append "\data" to it to get the database path.

Any other PC simply needs to run the exe from this shared folder and it would still works since now the network path of the exe + "\data" again points to correct database folder

Raul

<<
Should this directory path be read/set on the beforeconnect event ?
or am I missing something here.

If that is the case then i can just keep a simple text file with the directory path stored in it.
>>
Wed, Nov 16 2011 9:14 AMPermanent Link

Roy Lambert

NLH Associates

Team Elevate Team Elevate

kamran

>eg I have a TDBISAMDatabase Directory setting of "\\Computer1\app"
>which is where the data and software is all stored while i am developing it.
>All works fine while I am developing.
>
>Then later on I needed a good way of setting where the software and data is going to be installed
>within my software. I am guessing that I should store the directory path in a text file and read it in
>to the software so that after the install everying works fine on a computer in which you do not know
>the share information or network setup prior to installation.
>
>Should this directory path be read/set on the beforeconnect event ?
>or am I missing something here.
>
>If that is the case then i can just keep a simple text file with the directory path stored in it.

That should work BUT my suggestion was

3. In the app use \data as the path to the database for the tables

If you have the \data directory as a subdirectory of where the executable is then no matter which computer its on it should find it. All you need to do is arrange your development environment so that the data is in a subdirectory of the one in which your project is.

So on your PC you would have eg

C:\Development

where you develop the app

C:\Development\Data

where you store the data

The tables would have \Data as their database name, or if you use a TDBISAMDatabase it would have \Data as its directory.

On the fileserver PC you would have

C:\MyApp

where the application lives

C:\MyApp\Data

for the data

On the fileserver PC you would have a shortcut pointing to C:\MyApp\prog.exe with Start In set to C:\MyApp

On the other PC you would have a shortcut pointing to \\fileserver\cdrive\MyApp\prog.exe with start in set to \\fileserver\cdrive\MyApp

That's it - job done.

Roy Lambert [Team Elevate]
Wed, Nov 16 2011 9:19 AMPermanent Link

Roy Lambert

NLH Associates

Team Elevate Team Elevate

Raul

>The best way to do it as suggested by Roy is to set database path dynamically at runtime relative to the exe path. This way you do not need to store anything and user can eve move the exe and database to new folder without anythign breaking.

Yes and no - if they're using desktop shortcuts either method will require those resetting (unless you trust Windows to find it for you).

>Your exe can obtain its own path when running (e.g. ExtractFilePath (ParamStr(0))) and then you just append "\data" to it to get the database path.
>
>Any other PC simply needs to run the exe from this shared folder and it would still works since now the network path of the exe + "\data" again points to correct database folder

While what you say is correct its not actually required if you set things up as I suggest (see my other post).

Roy Lambert [Team Elevate]
Wed, Nov 16 2011 7:08 PMPermanent Link

Jan Ferguson

Data Software Solutions, Inc.

Team Elevate Team Elevate

Kamran,

I think I might have posted this solution in one of these NGs once
before but this is what I use and it has worked perfectly for many
years.

I created a small application which the end-user runs to create/edit an
INI file. The application just makes it easier but you can also have
the end-user directly edit the INI file themselves. In the INI file I
write to several keys, among them being RemoteAddress, RemotePort,
RemoteHost, SessionType and DataDirectory. I call my INI file
"NetConfig.ini" and reference it through ConfigIni.

Then in my data module's "OnCreate" event I check for the INI file's
contents and act accordingly. In the below code I cover both
possibilities of Client/Server and Local data.

procedure TdmMyApp.DataModuleCreate(Sender: TObject);
var RemoteAddress: String[15];
   RemotePort: String[5];
   RemoteHost: String[25];
   SessionType: String[10];
   DataDirectory: String;
begin
if Session1.Active = True then Session1.Active := False;
 with ConfigIni do
   begin
   RemoteAddress :=
ReadString('Configuration','RemoteAddress','RemoteAddress');
   RemotePort := ReadString('Configuration','RemotePort','RemotePort');
   RemoteHost := ReadString('Configuration','RemoteHost','RemoteHost');
   SessionType :=
ReadString('Configuration','SessionType','SessionType');
   DataDirectory :=
ReadString('Configuration','DataDirectory','DataDirectory');
   end;
 if SessionType = 'Remote' then
   begin
   Session1.SessionType := stRemote;
   Session1.RemotePort := StrToInt(RemotePort);
   Session1.RemoteHost := RemoteHost;
   Session1.RemoteAddress := RemoteAddress;
     try
       Session1.Active := True;      //Connect remote session
       Database1.Connected := True;   //Connect remote database
     except
         MessageDlg('Cannot connect to the Server! This might be
caused by one of the following reasons:' +
         #10#13#10#13 + '1. Your network connection is not active' +
         #10#13 + '2. The server is undergoing maintenance updates' +
         #10#13 + '3. The server is not accepting new connections in
preparation for maintenance updates' +
         #10#13 + '4. You have changed the network settings
incorrectly in the configuration file' +
         #10#13#10#13 + 'Please try again in 15-30 minutes. If your
network connection is active '+
                   'and you still cannot connect to the application,
please notify your Network ' +
                   'or Database Administrator.', mtWarning, [mbOK], 0);
         Application.Terminate;
     end;
   end else
   if SessionType = 'Local' then
     begin
     Session1.SessionType := stLocal;
     Database1.Directory := DataDirectory;
       try
         Database1.RemoteDatabase := '';
         Session1.Active := True;      //Connect remote session
         Database1.Connected := True;   //Connect remote database
       except
           MessageDlg('Cannot connect to the data! This application
will now shut down.' +
           #10#13#10#13 + 'Please contact your Database
Administrator.', mtWarning, [mbOK], 0);
           Application.Terminate;
       end;
     end;

I hope this helps you!

--
Jan Ferguson [Team Elevate]


kamran wrote:

> Hi
>
> Just needed some guidance as to what is the best way to set up my
> application to work over a local area network using a shared folder /
> simple share
>
> c:/computer1/app       (data + software)
> c:/computer2/app       (software)
>
> The problem I have is the computer name and folder might be different
> each time the software is installed.
>
> what code and at what point do I set the relevant parameters to
> ensure that the data and software recognise each other
>
> Is there an easy way to do this in the dbisam software with special
> consideration while developing the software and later for
> installation to any other shared folder.
>
> Thanks for your help in advance
>
> best regards
>
> Kamran
Mon, Nov 21 2011 1:02 PMPermanent Link

Tim Young [Elevate Software]

Elevate Software, Inc.

Avatar

Email timyoung@elevatesoft.com

Kamran,

<< Is there an easy way to do this in the dbisam software with special
consideration while developing the software and later for installation to
any other shared folder. >>

Yes, the easiest way to handle this is via code like what is found in the
dbisamut.pas unit, which you can find as part of the DBISAM Additional
Software and Utilities download in the \utilcomps subdirectory.

It has code like this in it (all of the function/procedure calls that you
don't recognize are either in the dbisamlb unit or the dbisamut unit):

function GetExeFileName: AnsiString;
var
  TempBuffer: array [0..MAX_PATH] of AnsiChar;
begin
  FillChar(TempBuffer,SizeOf(TempBuffer),#0);
  GetModuleFileNameA(hInstance,pAnsiChar(@TempBuffer),SizeOf(TempBuffer));
  Result:=AnsiString(pAnsiChar(@TempBuffer));
end;

procedure ReadVersionInformation(var VersionInfo: TVersionInfo);
var
  VersionInfoBuffer: pAnsiChar;
  VersionInfoSize: DWORD;
  VersionInfoHandle: DWORD;
  VersionInfoPtr: Pointer;
  VersionInfoLanguage: AnsiString;
  VersionEntryBuffer: pAnsiChar;
  VersionEntrySize: DWORD;
  VersionEntryPrefix: AnsiString;
  TempResult: Boolean;
begin
  with VersionInfo do
     begin
     VersionInfoSize:=GetFileVersionInfoSizeA(pAnsiChar(GetExeFileName),VersionInfoHandle);
     if (VersionInfoSize <> 0) then
        begin
        VersionInfoBuffer:=AllocMem(VersionInfoSize);
        try
           TempResult:=GetFileVersionInfoA(pAnsiChar(AnsiString(GetExeFileName)),VersionInfoHandle,
                                          VersionInfoSize,VersionInfoBuffer);
           if TempResult then
              begin
              if
VerQueryValue(VersionInfoBuffer,'\VarFileInfo\Translation',
                               VersionInfoPtr, VersionEntrySize ) then
                 begin
                 VersionInfoLanguage:=IntToHex(pInteger(VersionInfoPtr)^,8);
                 VersionEntryPrefix:='\StringFileInfo\'+
                                     Copy(VersionInfoLanguage,5,4)+
                                     Copy(VersionInfoLanguage,1,4);
                 VerQueryValueA(VersionInfoBuffer,pAnsiChar(VersionEntryPrefix+'\FileDescription'),
                           Pointer(VersionEntryBuffer), VersionEntrySize );
                 SetString(FileDescription,VersionEntryBuffer,StrLen(VersionEntryBuffer));
                 VerQueryValueA(VersionInfoBuffer,pAnsiChar(VersionEntryPrefix+'\FileVersion'),
                           Pointer(VersionEntryBuffer), VersionEntrySize );
                 SetString(FileVersion,VersionEntryBuffer,StrLen(VersionEntryBuffer));
                 VerQueryValueA(VersionInfoBuffer,pAnsiChar(VersionEntryPrefix+'\OriginalFileName'),
                           Pointer(VersionEntryBuffer), VersionEntrySize );
                 SetString(OriginalFileName,VersionEntryBuffer,StrLen(VersionEntryBuffer));
                 FileNameRoot:=ExtractFileRoot(OriginalFileName,'');
                 VerQueryValueA(VersionInfoBuffer,pAnsiChar(VersionEntryPrefix+'\CompanyName'),
                           Pointer(VersionEntryBuffer), VersionEntrySize );
                 SetString(CompanyName,VersionEntryBuffer,StrLen(VersionEntryBuffer));
                 VerQueryValueA(VersionInfoBuffer,pAnsiChar(VersionEntryPrefix+'\ProductName'),
                           Pointer(VersionEntryBuffer), VersionEntrySize );
                 SetString(ProductName,VersionEntryBuffer,StrLen(VersionEntryBuffer));
                 VerQueryValueA(VersionInfoBuffer,pAnsiChar(VersionEntryPrefix+'\ProductVersion'),
                           Pointer(VersionEntryBuffer), VersionEntrySize );
                 SetString(ProductVersion,VersionEntryBuffer,StrLen(VersionEntryBuffer));
                 VerQueryValueA(VersionInfoBuffer,pAnsiChar(VersionEntryPrefix+'\InternalName'),
                           Pointer(VersionEntryBuffer), VersionEntrySize );
                 SetString(InternalName,VersionEntryBuffer,StrLen(VersionEntryBuffer));
                 VerQueryValueA(VersionInfoBuffer,pAnsiChar(VersionEntryPrefix+'\LegalCopyright'),
                           Pointer(VersionEntryBuffer), VersionEntrySize );
                 SetString(LegalCopyright,VersionEntryBuffer,StrLen(VersionEntryBuffer));
                 end;
              end;
        finally
           DeAllocMem(Pointer(VersionInfoBuffer));
        end;
        end;
     end;
end;

function GetIniFileName(const VersionInfo: TVersionInfo): AnsiString;
begin
  Result:=AddBS(OSGetAppDataDirectory)+AddBS(VersionInfo.CompanyName)+
          AddBS(VersionInfo.ProductName)+VersionInfo.FileNameRoot+'.ini';
  if (not DirectoryExists(ExtractFilePath(Result))) then
     ForceDirectories(ExtractFilePath(Result));
end;

You can then use code like this to open and read/write to the .ini file:

procedure TMainForm.FormCreate(Sender: TObject);
begin
  ReadVersionInformation(VersionInformation);
  ForceDirectories(ExtractFilePath(GetIniFileName(VersionInformation)));
  MyDataModule:=TMyDataModule.Create(nil);
  SetupSession;
  with MyDataModule do
     OpenTables;
end;

procedure TMainForm.SetupSession;
var
  TempIniFile: TIniFile;
begin
  TempIniFile:=TIniFile.Create(GetIniFileName(VersionInformation));
  try
     with TempIniFile, MyDataModule do
        begin
        Session.PrivateDir:=OSGetTempDirectory;
        MyDatabase.Directory:=ReadString('Data','Support Database
Directory',
                                                             AddBS(OSGetAppDataDirectory)+AddBS(VersionInfo.CompanyName)+
                                                             AddBS(VersionInfo.ProductName)+'data');
        end;
  finally
     TempIniFile.Free;
  end;
end;

This allows you to set your version information in your application and use
it to determine the location of the .ini file in the user application data
directory tree that is the standard location for storing application data
under Windows.  You can then store all of your application configuration
information in the .ini file, and read it from there.  The only restriction
is that you must have the applicable TDBISAMSession and TDBISAMDatabase
components *closed* before setting most of their properties, so make sure
that you keep them closed at design-time, or close them before recompiling
your application.

--
Tim Young
Elevate Software
www.elevatesoft.com
Image