Board index » delphi » Problems with an OLE Server opening Access DB

Problems with an OLE Server opening Access DB

I have a problem opening an Access DB in an OLE server created with
Delphi 3.
I have prepared a very short example that demonstrate how the server
work (and crash):

- the client ask the server to open the DB
- the server open the db
- the server close the db
- the user close the client
- the user get "Access violation ...." :-(

I have tried not to use a db in the server, and everything seem to go
right; I have tried to use a Paradox DB, and everything seem to go
right; the problem seems to happen only when I open an Access 95/97 db
in the OLE server; I'm using Delphi 3.02, BDE 4.50, DAO 3.5.
Is someone able to give me a possible solution for this problem?
Does the problem regard DAO, OLE, BDE, Delphi or my inexperience with OLE?

this is the source code of the minimal example:

**** This is the server code:

library DBServer;

uses
  ComServ,
  DBServer_TLB in 'DBServer_TLB.pas',
  Unit1 in 'Unit1.pas' {DBAServer: CoClass};

exports
  DllGetClassObject,
  DllCanUnloadNow,
  DllRegisterServer,
  DllUnregisterServer;

{$R *.TLB}

{$R *.RES}

begin
end.

--------------------------------------------------------------------

unit Unit1;

interface

uses
  Forms, DBTables, Dialogs, ComObj, ActiveX, DBServer_TLB;

type
  TDBAServer = class(TAutoObject, IDBAServer)
  protected
        procedure Apri; safecall;
  end;

implementation

uses ComServ;

procedure TDBAServer.Apri;
var DatLocale: TDatabase;
begin
        showmessage('OLE Server');
        DatLocale:= TDatabase.Create(Application);
        DatLocale.AliasName:= '';
        DatLocale.DatabaseName:= 'MyDatabase1';
        DatLocale.DriverName:= 'MSACCESS';
        //DatLocale.DriverName:= 'STANDARD';
        DatLocale.LoginPrompt:= False;
        DatLocale.Params.Values['DATABASE NAME']:=
'h:\Documenti\db1.mdb';
        //DatLocale.Params.Values['DATABASE NAME']:=
'H:\Progetti\Prg_delphi3\ProvaOLE\Server\db\tAnagrafica.db';
        DatLocale.Params.Values['USER NAME']:= '';
        DatLocale.Params.Values['OPEN MODE']:= 'READ/WRITE';
        DatLocale.Params.Values['LANGDRIVER']:= '';
        DatLocale.Params.Values['SYSTEM DATABASE']:= '';
        DatLocale.Params.Values['PASSWORD']:= '';
        DatLocale.SessionName:= 'Default';
        DatLocale.open;
        showmessage('connected = true');
        DatLocale.close;
        DatLocale.free;
        showmessage('connected = false');
end;

initialization
  TAutoObjectFactory.Create(ComServer, TDBAServer, Class_DBAServer,
ciMultiInstance);
end.

--------------------------------------------------------------------

unit DBServer_TLB;

{ This file contains pascal declarations imported from a type library.
  This file will be written during each import or refresh of the type
  library editor.  Changes to this file will be discarded during the
  refresh process. }

{ DBServer Library }
{ Version 1.0 }

interface

uses Windows, ActiveX, Classes, Graphics, OleCtrls, StdVCL;

const
  LIBID_DBServer: TGUID = '{4FD075B0-E00F-11D1-91DE-0020A9004BBC}';

const

{ Component class GUIDs }
  Class_DBAServer: TGUID = '{4FD075B2-E00F-11D1-91DE-0020A9004BBC}';

type

{ Forward declarations: Interfaces }
  IDBAServer = interface;
  IDBAServerDisp = dispinterface;

{ Forward declarations: CoClasses }
  DBAServer = IDBAServer;

{ Dispatch interface for DBAServer Object }

  IDBAServer = interface(IDispatch)
    ['{4FD075B1-E00F-11D1-91DE-0020A9004BBC}']
    procedure Apri; safecall;
  end;

{ DispInterface declaration for Dual Interface IDBAServer }

  IDBAServerDisp = dispinterface
    ['{4FD075B1-E00F-11D1-91DE-0020A9004BBC}']
    procedure Apri; dispid 1;
  end;

{ DBAServerObject }

  CoDBAServer = class
    class function Create: IDBAServer;
    class function CreateRemote(const MachineName: string):
IDBAServer;
  end;

implementation

uses ComObj;

class function CoDBAServer.Create: IDBAServer;
begin
  Result := CreateComObject(Class_DBAServer) as IDBAServer;
end;

class function CoDBAServer.CreateRemote(const MachineName: string):
IDBAServer;
begin
  Result := CreateRemoteComObject(MachineName, Class_DBAServer) as
IDBAServer;
end;

end.

--------------------------------------------------------------------

**** This is the client code:

program DBClient;

uses
  Forms,
  Unit1 in 'Unit1.pas' {Form1},
  DBServer_TLB in 'C:\Program Files\Borland\Delphi
3\Imports\DBServer_TLB.pas';

{$R *.RES}

begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

--------------------------------------------------------------------

unit Unit1;

interface

uses
  DBServer_TLB,  Windows, Messages, SysUtils, Classes, Graphics,
Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
        cmdApri: TButton;
        procedure cmdApriClick(Sender: TObject);
  private
        { Private declarations }
  public
        { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.cmdApriClick(Sender: TObject);
var Mydb: IDBAServer;
begin
        Mydb:= CoDBAServer.Create;
        Mydb.Apri;
end;

end.

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/   Now offering spam-free web-based newsreading

 

Re:Problems with an OLE Server opening Access DB


Quote
l...@dei.unipd.it wrote in message <6ifaan$12...@nnrp1.dejanews.com>...
>I have a problem opening an Access DB in an OLE server created with
>Delphi 3.
>I have prepared a very short example that demonstrate how the server
>work (and crash):

<snip>

I access a Access DB from an Automation Server, but the BDE Native Access
drivers can be slow...
Here is my source code:

Automation server code:
,,,
procedure TMyAutoServer.Initialize;
begin
  // create a database to connect to the DB
  try
    db := TDatabase.Create(nil);
    with db do
    begin
      AliasName := 'ComsCtr';          // BDE alias to DB
      DatabaseName := 'aComsCtr'; // dummy not used
      LoginPrompt := False;
      Params.Add('USER NAME=MyUserName');
      Params.Add('PASSWORD=foo');
      Connected := TRUE;
    end;
  except
    // problem! BDE installed? Alias 'ComCentre' pointing to a ComCtr.MDB?
  end;
end;

// returns true if user logged in OK, False otherwise
function TMyAutoServer.Login: WordBool;
var
  qUsers     : TQuery;
begin
  result := BOOLFALSE; // by default
  qUsers := nil;       // suppress warning re qUsers may not have been
init'd
 try
    qUsers := TQuery.Create(nil);
    qUsers.DatabaseName := db.DatabaseName;
    qUsers.SQL.Add('SELECT *');
    qUsers.SQL.Add('FROM Users');
    qUsers.SQL.Add(WHERE   usr_Name = "'+FUserName+'"');
    qUsers.SQL.Add('AND   usr_Password = "'+FPassword+'"');
    qUsers.Open;
    if not qUsers.EOF then   // user found
    begin
      result := BOOLTRUE;
      FUserName        := qUsers.FieldByName('usr_Name').AsString;
      FUserAccessLevel := qUsers.FieldByName('usr_AccessLevel').AsInteger;
    end; // if located user
  finally
   if qUsers <> nil then qUsers.Free;
 end; // with dmodule
end;

and the client:
...
begin
  try
    ComControl := CreateOleObject('TVDComCtr.MyAutoServer);
  except
     on e: Exception do
        ShowMessage(e.Message);
  end;

  ComControl.UserName := eName.Text;
  ComControl.Password := ePassword.Text;
  if ComControl.Login then
    begin
      ModalResult := mrOK;
    end
  else
    begin
      MessageBeep(MB_ICONASTERISK);
      FlashWindow(LoginDlg.Handle,FALSE);
    end;
end;

Regards,
Grant

Other Threads