|
| |
Home Up
Kan dll niet vinden
Hallo,
Ik maak in mijn Delphi programma gebruik van een standaard Windows dll. Deze dll is echter niet altijd aanwezig.
Als deze dll niet aanwezig is, is een bepaalde functionaliteit van mijn programma niet beschikbaar. Dit is echter geen
probleem. Maar wanneer deze dll niet aanwezig is geeft mijn programma de foutmelding “Kan dll niet vinden” en start niet
op en dat is wel een probleem!!
Nu is mijn vraag hoe kan ik dit voorkomen, of hoe kan ik deze melding onderdrukken.
Groetjes Greta.
--
Greta,
Uit je verhaal haal ik dat je de DLL probeert te laden zodra je programma start. Is de DLL er niet, dan lukt het inderdaad
niet om je programma te starten. Hieronder staat een stukje voorbeeldcode waarin de DLL 'dynamisch' wordt geladen, en er
zit zelfs een check op om te kijken of het is gelukt :
begin
Handle := LoadLibrary('DATETIME.DLL');
if Handle <> 0 then begin
@GetTime := GetProcAddress(Handle, 'GetTime');
if @GetTime <> nil then begin
GetTime(Time);
with Time do
WriteLn('The time is ', Hour, ':', Minute, ':', Second);
end;
FreeLibrary(Handle);
end;
end;
hopelijk is dit je oplossing.
Hans
--
Ja Hans, dat is precies wat ik bedoel. Alleen begrijp ik nog niet hoe dit zou moeten inpassen in mijn programma.
Ik maak namelijk gebruik van een unit voor het opzetten van een ras verbinding waarin het volgende geladen wordt:
implementation
{ Externals from rasapi32.dll }
const
rasapi32 = 'rasapi32.dll';
function RasEnumEntries; external rasapi32 name 'RasEnumEntriesA';
function RasGetEntryDialParams; external rasapi32 name 'RasGetEntryDialParamsA';
etc.
Heb jij misschien enig idee hoe dit moet?
Groetjes Greta.
--
Greta, ik weet het zo niet zeker, maar ik verwacht niet dat de declaratie van de methodes zorgt voor het direct geladen
worden van de DLL, maar dat is uit te proberen.
Voor de gegeven methode zou je (per DLL-methode een aparte methode kunnen maken die je aanroept met de te verwerken
variabelen. In die methode gebruik je dan de aanroep zoals hierboven om de DLL te activeren indien nodig. Je verbergt
dan dus de hele DLL in methodes van een 'interface' unit.
Hans
--
Ik heb ook geen idee, maar ik ga het gewoon proberen. We zien wel hoever we komen.
Groetjes Greta.
--
Hoi Greta,
Zou je de aanroep van de functie 'RasEnumEntries' kunnen posten
ik heb denk ik een oplossing voor je probleem allen zit ik met da parameters te klooien
Roelof
--
Natuurlijk, zeker als jij denk een oplossing te hebben. Voor het gemak de gehele unit:
unit Ras;
interface
uses
Windows, RichEdit;
const
NETBIOS_NAME_LEN = 16;
UNLEN = 256;
PWLEN = 256;
CNLEN = 15;
DNLEN = CNLEN;
RAS_MaxDeviceType = 16;
RAS_MaxPhoneNumber = 128;
RAS_MaxIpAddress = 15;
RAS_MaxIpxAddress = 21;
//#if (WINVER >= 0x400)
RAS_MaxEntryName = 256;
RAS_MaxDeviceName = 128;
RAS_MaxCallbackNumber = RAS_MaxPhoneNumber;
//#else
// RAS_MaxEntryName 20
// RAS_MaxDeviceName 32
// RAS_MaxCallbackNumber 48
//#endif
RAS_MaxAreaCode = 10;
RAS_MaxPadType = 32;
RAS_MaxX25Address = 200;
RAS_MaxFacilities = 200;
RAS_MaxUserData = 200;
RASCS_PAUSED = $1000;
RASCS_DONE = $2000;
// ovo su trebale da budu enum konstante, ali pascal ne podrzava predefinisanje vrednosti,
// RASCONNSTATE
// vec samo linearno povecavanje vrednosti enum konstanti
RASCS_Interactive = RASCS_PAUSED;
RASCS_RetryAuthentication = RASCS_Interactive +1;
RASCS_CallbackSetByCaller = RASCS_RetryAuthentication + 1;
RASCS_PasswordExpired = RASCS_CallbackSetByCaller + 1;
RASCS_Connected = RASCS_DONE;
RASCS_Disconnected = RASCS_Connected + 1;
// RASPROJECTION
RASP_Amb = $10000;
RASP_PppNbf = $803F;
RASP_PppIpx = $802B;
RASP_PppIp = $8021;
type
LPVOID = Pointer;
LPTSTR = LPSTR;
BOOL = Integer;
LONG = LongInt;
LPBOOL = ^BOOL;
HRASCONN = DWORD;
LPHRASCONN = ^HRASCONN;
RASPROJECTION = Integer;
RASCONNSTATE = (
RASCS_OpenPort , // 0
RASCS_PortOpened, // 1
RASCS_ConnectDevice, // 2
RASCS_DeviceConnected, // 3
RASCS_AllDevicesConnected, // 4
RASCS_Authenticate, // 5
RASCS_AuthNotify, // 6
RASCS_AuthRetry, // 7
RASCS_AuthCallback, // 8
RASCS_AuthChangePassword, // 9
RASCS_AuthProject, // 10
RASCS_AuthLinkSpeed, // 11
RASCS_AuthAck, // 12
RASCS_ReAuthenticate, // 13
RASCS_Authenticated, // 14
RASCS_PrepareForCallback, // 15
RASCS_WaitForModemReset, // 16
RASCS_WaitForCallback, // 17
RASCS_Projected, // 18
//#if (WINVER >= 0x400)
RASCS_StartAuthentication, // 19
RASCS_CallbackComplete, // 20
RASCS_LogonNetwork, // 21
//#endif
RASCS_SubEntryConnected, // 22
RASCS_SubEntryDisconnected // 23
{ definisano kao konstanta
RASCS_Interactive = RASCS_PAUSED, // 4096
RASCS_RetryAuthentication, // 4097
RASCS_CallbackSetByCaller, // 4098
RASCS_PasswordExpired, // 4099
RASCS_Connected = RASCS_DONE, // 8192
RASCS_Disconnected // 8193
}
);
LPRASCONNSTATE = ^RASCONNSTATE;
RASENTRYNAME = record
dwSize : DWORD;
szEntryName : array[0 .. RAS_MaxEntryName + 1 -1] of CHAR;
end;
LPRASENTRYNAME = ^RASENTRYNAME;
RASAMB = record
dwSize : DWORD;
dwError : DWORD;
szNetBiosError : array[0 .. NETBIOS_NAME_LEN + 1 -1] of CHAR;
bLana : BYTE;
end;
RASCONN = record
dwSize : DWORD;
hrasconn : HRASCONN;
szEntryName : array[0 .. RAS_MaxEntryName + 1 -1] of CHAR;
//#if (WINVER >= 0x400)
szDeviceType : array[0 .. RAS_MaxDeviceType + 1 -1] of CHAR;
szDeviceName : array[0 .. RAS_MaxDeviceName + 1 -1] of CHAR;
//#endif
end;
LPRASCONN = ^RASCONN;
RASCONNSTATUS = record
dwSize : DWORD;
rasconnstate : RASCONNSTATE;
dwError : DWORD;
szDeviceType : array[0 .. RAS_MaxDeviceType + 1 -1] of CHAR;
szDeviceName : array[0 .. RAS_MaxDeviceName + 1 -1] of CHAR;
end;
LPRASCONNSTATUS = ^RASCONNSTATUS;
RASDIALEXTENSIONS = record
dwSize : DWORD;
dwfOptions :DWORD;
hwndParent : HWND;
reserved : DWORD;
end;
LPRASDIALEXTENSIONS = ^RASDIALEXTENSIONS;
RASDIALPARAMS = record
dwSize : DWORD;
szEntryName : array[0 .. RAS_MaxEntryName + 1 -1] of CHAR;
szPhoneNumber : array[0 .. RAS_MaxPhoneNumber + 1 -1] of CHAR;
szCallbackNumber : array[0 .. RAS_MaxCallbackNumber + 1 -1] of CHAR;
szUserName : array[0 .. UNLEN + 1 -1] of CHAR;
szPassword : array[0 .. PWLEN + 1 -1] of CHAR;
szDomain : array[0 .. DNLEN + 1 -1] of CHAR;
//#if (WINVER >= 0x401)
// dwSubEntry : DWORD;
// dwCallbackId : DWORD;
//#endif
end;
LPRASDIALPARAMS = ^RASDIALPARAMS;
RASPPPIP = record
dwSize : DWORD;
dwError : DWORD;
szIpAddress : array[0 .. RAS_MaxIpAddress + 1 -1] of CHAR;
end;
RASPPPIPX = record
dwSize : DWORD;
dwError : DWORD;
szIpxAddress : array[0 .. RAS_MaxIpxAddress + 1 -1] of CHAR;
end;
RASPPPNBF = record
dwSize : DWORD;
dwError : DWORD;
dwNetBiosError : DWORD;
szNetBiosError : array[0 .. NETBIOS_NAME_LEN + 1 -1] of CHAR;
szWorkstationName : array[0 .. NETBIOS_NAME_LEN + 1 -1] of CHAR;
bLana : BYTE;
end;
{Ras function prototypes }
function RasEnumEntries (
reserved : LPTSTR; // reserved, must be NULL
lpszPhonebook : LPTSTR; // pointer to full path and filename of phonebook file
lprasentryname : LPRASENTRYNAME; // buffer to receive phonebook entries
lpcb : LPDWORD; // size in bytes of buffer
lpcEntries : LPDWORD // number of entries written to buffer
) : DWORD; stdcall;
function RasGetEntryDialParams(
lpszPhonebook : LPTSTR; // pointer to the full path and filename of the phonebook file
lprasdialparams : LPRASDIALPARAMS; // pointer to a structure that receives the connection parameters
lpfPassword : LPBOOL // indicates whether the user's password was retrieved
) : DWORD; stdcall;
function RasDial(
lpRasDialExtensions : LPRASDIALEXTENSIONS; // pointer to function extensions data
lpszPhonebook : LPTSTR; // pointer to full path and filename of phonebook file
lpRasDialParams : LPRASDIALPARAMS; // pointer to calling parameters data
dwNotifierType : DWORD; // specifies type of RasDial event handler
lpvNotifier : LPVOID; // specifies a handler for RasDial events
lphRasConn : LPHRASCONN // pointer to variable to receive connection handle
) : DWORD; stdcall;
function RasHangUp(
hrasconn : HRASCONN // handle to the RAS connection to hang up
) : DWORD; stdcall;
function RasEditPhonebookEntry(
hwnd : HWND; // handle to the parent window of the dialog box
lpszPhonebook : LPTSTR; // pointer to the full path and filename of the phonebook file
lpszEntryName : LPTSTR // pointer to the phonebook entry name
) : DWORD; stdcall;
function RasCreatePhonebookEntry(
hwnd : HWND; // handle to the parent window of the dialog box
lpszPhonebook :LPTSTR // pointer to the full path and filename of the phonebook file
) : DWORD; stdcall;
function RasGetConnectStatus(
hrasconn : HRASCONN; // handle to RAS connection of interest
lprasconnstatus : LPRASCONNSTATUS // buffer to receive status data
) : DWORD; stdcall;
function RasEnumConnections(
lprasconn : LPRASCONN; // buffer to receive connections data
lpcb : LPDWORD; // size in bytes of buffer
lpcConnections : LPDWORD // number of connections written to buffer
) : DWORD; stdcall;
function RasGetErrorString(
uErrorValue : UINT; // error to get string for
lpszErrorString : LPTSTR; // buffer to hold error string
cBufSize : DWORD // size, in characters, of buffer
) : DWORD; stdcall;
function RasGetProjectionInfo(
hrasconn : HRASCONN; // handle that specifies remote access connection of interest
rasprojection : RASPROJECTION; // specifies type of projection information to obtain
lpprojection : LPVOID; // points to buffer that receives projection information
lpcb : LPDWORD // points to variable that specifies buffer size
) : DWORD; stdcall;
function RasSetEntryDialParams(
lpszPhonebook : LPTSTR; // pointer to the full path and filename of the phonebook file
lprasdialparams : LPRASDIALPARAMS; // pointer to a structure with the new connection parameters
fRemovePassword : BOOL // indicates whether to remove password from entry's parameters
) : DWORD; stdcall;
function ConnStatusToStr(i : Integer) : string; // Returns Status string based on integer value
implementation
{ Externals from rasapi32.dll }
const
rasapi32 = 'rasapi32.dll';
function RasEnumEntries; external rasapi32 name 'RasEnumEntriesA';
function RasGetEntryDialParams; external rasapi32 name 'RasGetEntryDialParamsA';
function RasDial; external rasapi32 name 'RasDialA';
function RasHangUp; external rasapi32 name 'RasHangUpA';
function RasEditPhonebookEntry; external rasapi32 name 'RasEditPhonebookEntryA';
function RasCreatePhonebookEntry; external rasapi32 name 'RasCreatePhonebookEntryA';
function RasGetConnectStatus; external rasapi32 name 'RasGetConnectStatusA';
function RasEnumConnections; external rasapi32 name 'RasEnumConnectionsA';
function RasGetErrorString; external rasapi32 name 'RasGetErrorStringA';
function RasGetProjectionInfo; external rasapi32 name 'RasGetProjectionInfoA';
function RasSetEntryDialParams; external rasapi32 name 'RasSetEntryDialParamsA';
function ConnStatusToStr(i : Integer) : string; // Returns Status string based on integer value
var
RetValue : string;
begin
RetValue := '';
case i of
0 : RetValue := 'Device is ready.';
1 : RetValue := 'Device is busy.';
2 : RetValue := 'Connecting device.';
5 : RetValue := 'Authenticating.';
14 : RetValue := 'Authenticated.';
19 : RetValue := 'Starting authentication.';
21 : RetValue := 'Logging to network.';
8192:RetValue := 'Connected.';
8193:RetValue := 'Disconnected.';
else RetValue := '';
end; //case
ConnStatusToStr := RetValue;
end;
end.
--
Ik ben zo vrij geweest de unit een beetje te veranderen. Bij het starten van de app. wordt de DLL geladen.
Bestaat deze niet dan wordt er geen foutmelding gegenereerd. Bestaat deze wel dan worden alle routines 'assigned'.
Je kunt heel simpel middels if Assigned(RasApiFunctionName) then RasApiFunctionName(Parameters); de DLL-functie aanroepen,
hier volgt de gewijzigde code:
unit RAS;
interface
uses
Windows;
const
NETBIOS_NAME_LEN = 16;
UNLEN = 256;
PWLEN = 256;
CNLEN = 15;
DNLEN = CNLEN;
RAS_MaxDeviceType = 16;
RAS_MaxPhoneNumber = 128;
RAS_MaxIpAddress = 15;
RAS_MaxIpxAddress = 21;
{$IFDEF WIN32}
RAS_MaxEntryName = 256;
RAS_MaxDeviceName = 128;
RAS_MaxCallbackNumber = RAS_MaxPhoneNumber;
{$ELSE}
RAS_MaxEntryName=20;
RAS_MaxDeviceName=32;
RAS_MaxCallbackNumber=48
{$ENDIF}
RAS_MaxAreaCode = 10;
RAS_MaxPadType = 32;
RAS_MaxX25Address = 200;
RAS_MaxFacilities = 200;
RAS_MaxUserData = 200;
RASCS_PAUSED = $1000;
RASCS_DONE = $2000;
RASCS_Interactive = RASCS_PAUSED;
RASCS_RetryAuthentication = RASCS_PAUSED+1;
RASCS_CallbackSetByCaller = RASCS_RetryAuthentication + 1;
RASCS_PasswordExpired = RASCS_CallbackSetByCaller + 1;
RASCS_Connected = RASCS_DONE;
RASCS_Disconnected = RASCS_Connected + 1;
RASP_Amb = $10000;
RASP_PppNbf = $803F;
RASP_PppIpx = $802B;
RASP_PppIp = $8021;
type
LPVOID = Pointer;
LPTSTR = LPSTR;
BOOL = Integer;
LONG = LongInt;
LPBOOL = ^BOOL;
HRASCONN = DWORD;
LPHRASCONN = ^HRASCONN;
RASPROJECTION = Integer;
LPRASCONNSTATE = ^RASCONNSTATE;
RASCONNSTATE =
(RASCS_OpenPort, RASCS_PortOpened, RASCS_ConnectDevice, RASCS_DeviceConnected,
RASCS_AllDevicesConnected, RASCS_Authenticate, RASCS_AuthNotify, RASCS_AuthRetry,
RASCS_AuthCallback, RASCS_AuthChangePassword, RASCS_AuthProject, RASCS_AuthLinkSpeed,
RASCS_AuthAck, RASCS_ReAuthenticate, RASCS_Authenticated, RASCS_PrepareForCallback,
RASCS_WaitForModemReset, RASCS_WaitForCallback, RASCS_Projected,
{{$ifdef WIN32}
RASCS_StartAuthentication, RASCS_CallbackComplete, RASCS_LogonNetwork,
{#ENDIF}
RASCS_SubEntryConnected, RASCS_SubEntryDisconnected);
LPRASENTRYNAME = ^RASENTRYNAME;
RASENTRYNAME = record
dwSize : DWORD;
szEntryName : array[0 .. RAS_MaxEntryName + 1 -1] of CHAR;
end;
RASAMB = record
dwSize : DWORD;
dwError : DWORD;
szNetBiosError : array[0 .. NETBIOS_NAME_LEN + 1 -1] of CHAR;
bLana : BYTE;
end;
LPRASCONN = ^RASCONN;
RASCONN = record
dwSize : DWORD;
hrasconn : HRASCONN;
szEntryName : array[0..RAS_MaxEntryName] of CHAR;
{$IFDEF WIN32}
szDeviceType : array[0..RAS_MaxDeviceType] of CHAR;
szDeviceName : array[0..RAS_MaxDeviceName] of CHAR;
{$ENDIF}
end;
LPRASCONNSTATUS = ^RASCONNSTATUS;
RASCONNSTATUS = record
dwSize : DWORD;
rasconnstate : RASCONNSTATE;
dwError : DWORD;
szDeviceType : array[0..RAS_MaxDeviceType] of CHAR;
szDeviceName : array[0..RAS_MaxDeviceName] of CHAR;
end;
LPRASDIALEXTENSIONS = ^RASDIALEXTENSIONS;
RASDIALEXTENSIONS = record
dwSize : DWORD;
dwfOptions :DWORD;
hwndParent : HWND;
reserved : DWORD;
end;
LPRASDIALPARAMS = ^RASDIALPARAMS;
RASDIALPARAMS = record
dwSize : DWORD;
szEntryName : array[0..RAS_MaxEntryName] of CHAR;
szPhoneNumber : array[0..RAS_MaxPhoneNumber] of CHAR;
szCallbackNumber : array[0..RAS_MaxCallbackNumber] of CHAR;
szUserName : array[0..UNLEN] of CHAR;
szPassword : array[0..PWLEN] of CHAR;
szDomain : array[0..DNLEN] of CHAR;
end;
RASPPPIP = record
dwSize : DWORD;
dwError : DWORD;
szIpAddress : array[0..RAS_MaxIpAddress] of CHAR;
end;
RASPPPIPX = record
dwSize : DWORD;
dwError : DWORD;
szIpxAddress : array[0..RAS_MaxIpxAddress] of CHAR;
end;
RASPPPNBF = record
dwSize : DWORD;
dwError : DWORD;
dwNetBiosError : DWORD;
szNetBiosError : array[0..NETBIOS_NAME_LEN] of CHAR;
szWorkstationName : array[0..NETBIOS_NAME_LEN] of CHAR;
bLana : BYTE;
end;
TRasEnumEntries = function
(reserved: LPTSTR; lpszPhonebook: LPTSTR; lprasentryname: LPRASENTRYNAME;
lpcb: LPDWORD; lpcEntries: LPDWORD): DWORD; stdcall;
TRasGetEntryDialParams = function
(lpszPhonebook: LPTSTR; lprasdialparams: LPRASDIALPARAMS;
lpfPassword: LPBOOL): DWORD; stdcall;
TRasDial = function
(lpRasDialExtensions: LPRASDIALEXTENSIONS; lpszPhonebook: LPTSTR;
lpRasDialParams: LPRASDIALPARAMS; dwNotifierType : DWORD;
lpvNotifier: LPVOID; lphRasConn: LPHRASCONN): DWORD; stdcall;
TRasHangUp = function
(hrasconn: HRASCONN): DWORD; stdcall;
TRasEditPhonebookEntry = function
(hwnd: HWND; lpszPhonebook: LPTSTR; lpszEntryName: LPTSTR): DWORD; stdcall;
TRasCreatePhonebookEntry = function
(hwnd: HWND; lpszPhonebook: LPTSTR): DWORD; stdcall;
TRasGetConnectStatus = function
(hrasconn: HRASCONN; lprasconnstatus: LPRASCONNSTATUS): DWORD; stdcall;
TRasEnumConnections = function
(lprasconn: LPRASCONN; lpcb: LPDWORD; lpcConnections: LPDWORD): DWORD; stdcall;
TRasGetErrorString = function
(uErrorValue: UINT; lpszErrorString: LPTSTR; cBufSize: DWORD): DWORD; stdcall;
TRasGetProjectionInfo = function
(hrasconn: HRASCONN; rasprojection: RASPROJECTION; lpprojection : LPVOID;
lpcb: LPDWORD): DWORD; stdcall;
TRasSetEntryDialParams = function
(lpszPhonebook: LPTSTR; lprasdialparams: LPRASDIALPARAMS;
fRemovePassword: BOOL): DWORD; stdcall;
function ConnStatusToStr(const I: Integer): string;
var
RasEnumEntries: TRasEnumEntries;
RasEntryGetDialParams: TRasGetEntryDialParams;
RasDial: TRasDial;
RasHangUp: TRasHangUp;
RasEditPhonebookEntry: TRasEditPhonebookEntry;
RasCreatePhonebookEntry: TRasCreatePhonebookEntry;
RasGetConnectStatus: TRasGetConnectStatus;
RasEnumConnections: TRasEnumConnections;
RasGetErrorString: TRasGetErrorString;
RasGetProjectionInfo: TRasGetProjectionInfo;
RasSetEntryDialParams: TRasGetEntryDialParams;
implementation
const
RASAPI32DLL = 'rasapi32.dll';
var
RASAPI32Handle: THandle;
function ConnStatusToStr(const I: Integer): string;
begin
Result := '';
case I of
0 : Result := 'Device is ready.';
1 : Result := 'Device is busy.';
2 : Result := 'Connecting device.';
5 : Result := 'Authenticating.';
14 : Result := 'Authenticated.';
19 : Result := 'Starting authentication.';
21 : Result := 'Logging to network.';
8192: Result := 'Connected.';
8193: Result := 'Disconnected.';
end;
end;
initialization
RASAPI32Handle := LoadLibrary(RASAPI32DLL);
if (RASAPI32Handle<>0) then
begin
@RasEnumEntries:=GetProcAddress(RASAPI32Handle, 'RasEnumEntriesA');
@RasEntryGetDialParams:=GetProcAddress(RASAPI32Handle, 'RasGetEntryDialParamsA');
@RasDial:=GetProcAddress(RASAPI32Handle, 'RasDialA');
@RasHangUp:=GetProcAddress(RASAPI32Handle, 'RasHangUpA');
@RasEditPhonebookEntry:=GetProcAddress(RASAPI32Handle, 'RasEditPhonebookEntryA');
@RasCreatePhonebookEntry:=GetProcAddress(RASAPI32Handle, 'RasCreatePhonebookEntryA');
@RasGetConnectStatus:=GetProcAddress(RASAPI32Handle, 'RasGetConnectStatusA');
@RasEnumConnections:=GetProcAddress(RASAPI32Handle, 'RasEnumConnectionsA');
@RasGetErrorString:=GetProcAddress(RASAPI32Handle, 'RasGetErrorStringA');
@RasGetProjectionInfo:=GetProcAddress(RASAPI32Handle, 'RasGetProjectionInfoA');
@RasSetEntryDialParams:=GetProcAddress(RASAPI32Handle, 'RasGetEntryDialParamsA');
end;
finalization
if (RASAPI32Handle<>0) then
FreeLibrary(RASAPI32Handle);
end.
Suc6 ermee!
--
Hartelijk dank voor je reactie en oplossing natuurlijk.
Werkt perfect!! Zat alleen even vreemd te kijken dat de function RasGetEntryDialParams niet meer werkte. Dit klopt ook
wel want hij heet nu RasEntryGetDialParams.
Groetjes Greta.
|