Get around 3rd party cyclic dll dependencies? - delphi

I am attempting to access text in a TE Edit (from ter32.dll) in a 3rd party application. (first post on this here) I looked through the API and tried to dynamically load the dll in order to access a function. Unfortunately, this (aftermarket rework) of ter32.dll has a load of dependencies. I tried dynamically loading each required dll as needed but ran into a cyclic dependency. ter32.dll requires x. x requires y. y won't load because it requires x. Would I have to statically load these with a delay? I sure hope not as I don't want the overhead/bloat/dependency in my application.
1) what am I missing?
2) is there some way around this?
3) does anybody have any other way of accessing the text in a TE Edit of ter32.dll?

When you load a DLL the loader will load all the dependencies for you. These dependencies are listed in the import tables of each DLL and the loader resolves them. You don't need to do anything.
Therefore I can't understand how you came to the conclusion that you yourself needed to process DLL dependencies. Are you loading this DLL in a non-standard way? Do you need a manifest for WinSxS dependencies, i.e. if the MS C runtime is needed? Is there something else we need to know?
All that said, having this DLL loaded into your process is not likely, in my view, to help much in extracting text from a different process which has its own separate virtual memory. In other words, I am quite confident that your current attempt to extract the text will fail. The way to get around the virtual memory barrier is to run your code in the other process using a hook.

Related

How to get access to an object between dynamically loaded packages?

I need to know the user name and other data of the logged-in user in a project organized using BPLs. That is, how and where do I need to declare the user object and its creation, and how to get access to that object when a package is loaded at runtime? I don't have enough experience working with packages.
In a regular app, for the programmer there is no difference between using runtime packages or all in a single exe
You can change the project to go with runtime packages or not, and your code won't change at all
That changes when you make a modular app that loads BPL modules on demand, chosing at runtime if a given module will be load, and doing it dynamically (ex. app made with a plugin-architecture in mind), then you need to design your own strategy to handle that
Myself, I work in that second way, and I do have some main modules wich give services to the "plugins", so when they are loaded, they do register themselves with the system: user control, navigation, whatever
There is nothing special to use objects in a package. You just add the unit name where the object is defined to the uses clause of the unit where the object is to be used.
You should really read the documentation on this topic. The you may ask more questions to clarify things you don't understand.

Delphi DLL Organization - Static and Dynamic Loading

I imagine this is a common issue, but googling around hasn't presented a solution. I'm just having some trouble loading a library.
The source that I have for the library is utilizing static loading, which is fine. The rest of the libraries I am using are loaded dynamically.
The problem is that my program is now being loaded up as a library (it is a plugin), by a different application (a host). This means that the directory for the HOST executable, is NOT the program directory for my application.
The library that is being statically loaded (just a simple library for font rendering), is inside of my program's directory, and when loading my software as a plugin, it is not found. When I load up my software as a 'standalone' program (without a host), there is no issue.
I was able to resolve the issue by putting the 'missing' library into the folder for the host application, but this is a bad solution.
I was also able to resolve it by providing a direct path to the name of the library, but this is also a bad solution. I do not know where the end user will be installing my software.
Is there any way around this issue without having to rewrite the code to use dynamic loading?
To continue using static loading, must the library be registered? I think that registering this library is too invasive, as other programs may be using a different version of it.
const
ft_lib = 'freetype6.dll'; //here is our problem. I could put a direct path
//here, to fix it, but I will not know this path
//on an end-user's machine
type
FT_Library = Pointer;
function FT_Init_FreeType(out alibrary : FT_Library ) : FT_Error;
cdecl; external ft_lib name 'FT_Init_FreeType';
The program loader looks for DLLs on the system path. Just make sure that your freetype6.dll (and the DLLs that it requires) is either in the same directory as the host exe, or is in a directory that is in the file path (PATH environment variable).
For reference: http://msdn.microsoft.com/en-us/library/7d83bc18(v=vs.71).aspx
I would suggest that modifying PATH is a very invasive solution. I would recommend attempting to avoid that. You may be able to do that using SetDllDirectory. This will add a directory to the search path, but will make that change locally to your process.
Your host app should call SetDllDirectory immediately before loading your DLL. Then any dependencies of the DLL will be resolved using the modified search path. When the DLL has successfully loaded, call SetDllDirectory again to restore the search path to its default value.
If you aren't in control of the host then it might be tricky to implement this. You'd need to call SetDllDirectory in your DLL and then it would be too late. You could put another layer between the host and plugin. That layer could modify the DLL search path and then use LoadLibrary to load the DLL that used implicit linking.
The other obvious option is to stop using implicit linking. Use LoadLibrary to resolve all your dependencies. That's actually not as hard as it sounds.
In a modern Delphi you could use delay loading also. So long as the DLL search path is modified, before you call into the delay loaded imports, they will resolve.

Dynamicly resolving Assemblies without the file name

Yes, I've read the warning label, and I know that dynamically loading assemblies is somewhat discouraged. That said, I have an application that loads assemblies - that's just how it works. It works fine on Windows. Works fine on Windows CE. I need it to "work fine" on Android, even if it takes some massaging.
Basically the app is an engine that loads up plug-in DLLs (we'll call it an Adapter) that meet specific interfaces at run time. Under Windows, it even detects the appearance of a DLL at any point and goes and loads it - I'm fine if that's not going to work under Android.
What I'm having trouble getting working is having the Engine load an Adapter that it knew about at design/compile time but without hard coding the name of that Adapter into the Engine code. I'm fine with adding a reference to the Adapter to get it to not get linked out, but I really, really don't want to have to add in the DLL name every time, as the DLLs change with different deployments, and that would lead to a huge headache.
So I figured that if it's referenced, it would get into the APK, and I could use reflection to load it like this:
var asm = Assembly.Load("TheAdapterName.dll");
Initial tests show that this works for the Adapter if I just hard code in the name, but again, I really, really want to avoid that.
So I thought that maybe I could reflect through the references and extract the name, but oddly, not all references actually show up when I do that. So I do this:
var refs = asm.GetReferencedAssemblies().Select(a => a.Name).ToArray();
And I get back an array of 14 assembly names. But the assembly (asm) has 16 references, one of which is the Adapter plug-in I need to load. The Adapter is definitely there - heck I used Assembly.Load with the full name two lines above and it resolved.
I thought, ok, maybe I can figure out the "path" to the folder from which I'm running, and then look for DLLs there and load that way. Ha. After several hours of trying to figure out a way to get the path that would work under Debug and Release, I came up with nothing but more grey hair.
Sooooo...... any thoughts on how I might get the name of a DLL that I know is in my APK, but that I don't "know" the name of at build time (I'm loading them and looking for interfaces via reflection to detect their "Adapterness").
If those methods aren't working for you, then the only suggestion I can think of is to add a prebuild step which updates either a C# or an Assets file in order to provide the list you need.
Obviously this is extra work, but should be fully automated and is guaranteed to work no matter what platform changes get thrown at you.
As an aside, I also just looked at one of my mvx projects using reflector - it shows the same asm.GetReferencedAssemblies() list as your investigations report - runtime-loaded plugins are not listed. I guess that the GetReferencedAssemblies method is reporting only on assemblies actually used to import Type references at the IL level - so if you reference an assembly in the csproj but don't import any types then it doesn't list them as references in the compiled code.

Using EXE's instead of DLL's as plugins - Ways to "one way, one time" transfer information

tldr; at bottom.
Ok, so once again an interesting problem and I'm looking for a fun and interesting solution.
My current project involves being very modular, meaning the program functionality will be easily changed based on different modules and the program would adapt.
So I started out with the typical route, which is using DLL plugins. Now this is just way to normal, I want to think outside the box a bit.
The modules included in my program are long running campaigns that may take weeks to finish, and there will be many running at a time. So stability is a big issue, so I thought about what Google Chrome does. Processes, not DLLs or threads.
So I have a framework going and I need a way to get some information about each module (which are now EXEs). Now for my DLL framework I was exporting a "Register" function that would fill in some information.
So I thought to myself, hey EXEs can export functions, let's see if that actually works...It doesn't. I did some research into how Windows handles theses things and I don't feel like hacking the PE headers on the fly (but it's the out of the box kind of thinking I'm going for).
I'm planning on using named pipes and CLI parameters to transfer data between the main program and the module exe's. I could use that in a register fashion, but I want to here other peoples thoughts.
tldr: I'm using EXE's instead of DLL's for plugins. Looking for a way to easily export one time information like a exported "Register" function would on a DLL. Thoughts?
You might still consider having the modules written as DLLs with defined entrypoints (e.g., the Register function). Then you write the executable that loads the specified DLL. Your main application would fire off the driver executable and give it a name of a plugin DLL.
That way it is still easy to define and export the set of APIs that must be provided yet still run it as a separate process. The one executable that you write can load the specified DLL and then handle the necessary IPC with the main app.
You could define a protocol via the stdin/stdout, named pipes, sockets, etc.
I have successfully used 'plain' COM for several projects, and objects inheriting from TAutoObject. The bonusses here are IDL; the interopability with .Net, VBA and other non-Delphi things; and the fact that implementors still can choose wether to supply a DLL, an exe, an NT-service, and optionally run hosted over the network (COM+/DCOM). There may be several considerations you should handle about multi-threading and locking, but I found all that I needed to know online.
You can, of course, not use symbols exported by a (running) exe since it is running in another boundary. But, you can load an exe as an image (as you would do with a library) using LoadLibrary(Ex) and then, use the functions exported by the exe. I have tested (just for fun) when debugging PeStudio. See the snapshot below of chrome.exe loaded in the process space of PeStudio.exe using LoadLibrary.

Need to create a compiled delphi app that can make a separate compiled app

I need to make an app that will let users select some options, click a button, and a separate compiled app is created. Is this possible? I am using delphi 7 and 2010.
Thanks for the replies. Here is a little more info.
It would have to be a graphical app and create a graphical app.
What I want is the user to fire up 'App A' (I originally made), be able to select some options (I apologize for the secrecy. I think this is a million dollar idea that probably 3 people may find useful :) then use the program to create 'App B.' 'App B' can then be distributed to end users and 'App B' is a single executable that includes a compiled app plus the configuration data. I don't care how, but I need 'App B' to be a single executable.
I wouldn't even need to use Delphi for the final compiled app. If there is some sort of "pseudo-compiler" that I can call from Delphi that would marry a precompiled exe and a separate config file into a single executable. That would work just fine as well.
Thank you for the replies and help.
Thank you.
I also faced a similar situation once. I had to produce an exe using my exe. I didn't want to go the compiling a source code because of complexity and license problems.
Lets call the parent app P and child app C. Also lets assume that whatever option C needs can be summed up in a config file (XML/INI etc). What I ended-up doing was:
Create P and C. Inserted C in resource data of P.
When user clicked the button after selecting options, P would extract C from its resource data.
Created an XML file containing the options selected by user and inserted it in C's resource data.
So whenever C will run, it will use the options given in the XML file stuffed in it. It looks like complicated and hacky but is reliable and simple. Do a google on "delphi embedding resource in exe" and you will find plenty of articles to do above.
It is possible. You will need a Delphi 7 (or compatible) compiler (command line at least) on the target machine. You will also need all the source code for the compiled application and that includes all the third party libraries if you use any.
When you have it all set just call the command line compiler (DCC32.EXE) with the proper parameters and paths.
You can use two approaches for this:
Call ShellExecute
Call CreateProcess
You will have more control over the execution with CreateProcess. Also you will have to watch out for legal issues and licences if you plan to use the compiler this way.
Given that the Delphi compiler can't be redistributed, one solution if the user has not a copy of Delphi may be to use a script engine (i.e. RemObjects PascalScript, but there are others), generate code for it, and embed that code (i.e. within a resource) in an executable that will execute it when launched.
Create a separate stub executable that implements all the logic you need, and that reads its configuration from its own local resources (look at the TResourceStream class to help you load a resource at runtime).
Include that stub executable as an RCDATA resource in your main app's resources when it is compiled.
At runtime, the main app can extract the stub executable from its resources when needed, save it to disk, and insert the necessary configuration data into the stub's resources using the Win32 API UpdateResource() function.
Without knowing more about why you think you need to do this, I assume you don't actually need to do this. Given the stated requirements, I'd simply have one app, written in Delphi, that looks for the existence of configuration data (.ini file, registry, etc..) In the absence of this, it presents a screen that "will let users select some options, click a button". Then the options are stored in a .ini file, and the rest of the program proceeds, making use of those options.
Alternately, I'd use some pascal scripting, such as provided by TMS.
If you are looking for a way to crank out custom-branded versions of an app, maybe use Inno Setup with a ResHacker step. i.e. gather requirements in Inno, spit out your .exe into a temp directory, use ResHacker to modify the .exe, copy it into the program folder.

Resources