I made a simple tool (LogAndMailApplication) that sends logs to my gmail account, for this I used the Indy component TIdSSLIOHandlerSocketOpenSSL. To work it needs ssleay32.dll and libeay32.dll.
So at application start I extract from exe resources the 2 dll and I copy them to the application folder.
All the indy compoennts are in a datamodule I destroy before closing the application.
After destroying the datamodule I try to delete the dlls but I cannot.
I just used DeleteFile, but that worked great for all the other files I delete on application exit (incluging an ini file).
I tried to make a simple exe that just deletes the 2 dll and it works. So the problem is that the 2 dll are somehow locked until the LogAndMailApplication is not closed, how to solve the problem?
Indy dynamically loads the OpenSSL DLLs at runtime, and then by default does not unload them until app shutdown. If you want to unload the DLLs sooner, you need to call IdSSLOpenSSL.UnLoadOpenSSLLibrary() directly. This will unload the DLLs and clean up all references and allocated objects related to them.
You can do the following: at the very end of your code use
FreeLibrary(GetModuleHandle('ssleay32.dll'));
FreeLibrary(GetModuleHandle('libeay32.dll'));
DeleteFile(PathToDLL1);
DeleteFile(PathToDLL2);
This should work.
Alternatively you can get rid of OpenSSL and use SSL components from our SecureBlackbox.
Alternatively you can delete the DLL's in the finalization section of the data module unit...
Related
I wanted to debug a data module that I've created and which is a part of a DLL, but for some reasons, I can't debug it. The debugger doesn't seems to be hitting the break point, is there a way i can debug my Dll/ data module.
Check list:
be sure your DLL have included debug info
if it's COM DLL - be sure it is registered on same place where you build it
try to rebuild the DLL, rebuild the App if you have changed the interface
check in EventLog when debugger loads the DLL does it says it have or dont have debug info.
To debug the DLL, the project loaded in Delphi must be the DLL itself. You enter a host application (Your application server executable), the one which will load the DLL. Make sure the host application load the DLL exactly where you have built it. You cannot move the DLL once constructed.
If the DLL must be in some fixed place, be sure to set the DLL's project options so that the DLL is produced at the right place.
And of course you must activate the debug build configuration for the DLL.
Using a tool such as ProcessExplorer (https://learn.microsoft.com/en-us/sysinternals/downloads/process-explorer), you can see if the DLL you built was actually the one loaded by your application server.
I made an application that uses the openssl dlls (libeay32.dll and ssleay32.dll).
It is indy using them, I don't call the dlls directly.
The simplest workaround i found to avoid an installer (i just delpoy an exe and i am ok with this approach) is to:
put the dlls as resources of the exe
on program start I extract them in the exe folder
the exe uses them
This is perfect but I would like to improve the approach by extracting the dlls in a temp folder and not on the exe folder (that in many cases is the desktop).
The problem is that I don't know how to force the application to use the dlls in the temp folder, because now the behaviour is:
if dlls are not in current directory try to search in the directories defined in the system path.
Who knows a solution to force indy to use the dlls in my temp path? (like "temporarly registering the dlls")
If you are using an up-to-date version of Indy 10, the IdSSLOpenSSLHeaders unit has a public IdOpenSSLSetLibPath() function to tell Indy which custom folder to look in for the OpenSSL DLLs:
procedure IdOpenSSLSetLibPath(const APath: String);
Load the DLLs yourself with LoadLibrary as soon as you have written them to the temp folder.
This will make Indy's LoadLibrary use your DLLs when they need them:
If lpFileName does not include a path and there is more than one
loaded module with the same base name and extension, the function
returns a handle to the module that was loaded first.
You can use SetDllDirectory to manipulate the DLL search order.
In the delphi 7 project folders a lot of *.Mb files are generated. The files are named like Del1.MB, Del2.MB etc. The projects connect to firebird databases via the BDE. Also there are quite a few other non standard components being used. Does anyone know what these MB files are and if they can be safely deleted?
These DEL*.MB files as well as DEL*.DB files are created automatically by Borland Database Engine (BDE)1 components for data access, for example when a query (by TQuery component) run.
They are temporary files, so they will be removed automatically if the BDE session terminates correctly2. If some app crashes these files will be held until the next execution when most of them will be replaced, so, a manual cleaning may be necessary.
If the folder where these files are being created is shared (or an app changed its current dir to same folder, e.g. by use of SetCurrentDir function), it may cause more problems since different apps may lock files making other apps confused and causing other crashes.
I think these "del*.mb" files are temp BDE PARADOX format files, by default BDE creates them in the application folder and delete them on application close:
http://www.borlandtalk.com/image-vp141388.html
http://www.rhinocerus.net/forum/lang-pascal-delphi-databases/212042-bde-generating-del-mb-files.html
Suppose I've got a large ActiveX library written in Delphi, let's call it Lib1.dll. It contains multiple interfaces. The task is to rename the library to Lib2.dll in such a way, that another application can call both methods from Lib1 and Lib2 at the same time.
I thought to do it in next way:
Rename Delphi project to Lib2 (that will rename the library).
Replace *Lib1_TLB.pas* file with *Lib2_TLB.pas* with the same content, but with new GUIDs of interfaces and coclasses.
Paste new GUIDs to Lib2.ridl.
Generate new Lib2.tlb file from that ridl and that should be ok.
But it isn't. I'm getting Delphi error "Couldn't find Lib1.ridl file". Okay, rename both ridl and tlb.pas back to Lib1, compile&build ok, but registering ActiveX server crashes the IDE.
Please suggest me a way to rename the lib or how to make my current progress work.
I assume you are using a recent version of Delphi using .ridl files for COM interfaces so keep in mind that it is the central unit for dealing with COM. You may start with copying and renaming the ridl file from Lib1.ridl to Lib2.ridl. Then inside Lib2.ridl, not _TLB.pas (which is recreated automatically) regenerate the library's GUID and those of coclasses. Interfaces may remain unchanged. After that you should be able to generate tlb and refresh _TLB.pas and finally build and register the new library.
I have a problem which I do not understand. I am using a DLL in my application. This DLL requires other DLL's and I have all of them. If I put the libraries in my appliction folder everything works fine.
However, having a bunch of DLLs in application folder looks quite ugly so I wanted to move them to application\lib subfolder.
After this change now I am getting External Exception when I try to use some of its functions.
I've only changed one line of code:
The original code
DLLHandle := LoadLibrary(Pchar(ExtractFilePath(ParamStr(0)) + 'External.dll'))
The code after change
DLLHandle := LoadLibrary(Pchar(ExtractFilePath(ParamStr(0)) + 'lib\External.dll'))
In both cases DLLHandle have a handle after loading the library. I am also not getting any error after calling GetProcAddress( DLLHandle, '_SomeFunction#8')
No exceptions, and return value of GetLastError is always 0.
Do you have any idea what could be wrong?
Thanks.
Life is far easier if you keep the DLLs in the same folder as the executable. That's the first folder searched when libraries are loaded. To move all the DLLs into a sub folder of the executable directory requires cooperation from all DLLs.
Most likely you have secondary DLL dependencies that are not cooperating. So exe loads A fine, but then A fails to load B. You can debug this further with Dependency Walker running in profile mode. It's quite possible that a secondary DLL is being loaded with implicit linking and that this throws and exception. Whatever the cause, Depenency Walker will lead you to the problem.
Whilst you can modify the PATH variable this is generally not advisable. If you do choose to go down this route then don't modify system wide, just modify the executable process environment at runtime before the first LoadLibrary. This is tenable so long as all your DLL linking is explicit using GetProcAddress.
All accepted wisdom recommends that you put your DLLs in the same folder as your executable. I would echo this recommendation. If you did this then you would be able to use implicit linking which would greatly simplify your code.
Yet another option may be to abandon DLLs and link everything straight into your executable. Unless you have a plugin type architecture, a single big exe is by far the simplest approach.
The other DLL's that need to be loaded must be on the system path for Windows to find them. Your application can find the External.dll as you explicitly define the path. Try adding the lib folder to your system path.