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

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.

Related

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.

How to use project version information inside a Delphi application?

I use Project Options / Version to manage the version info (N.N.N.N format).
Anyway inside my project I duplicate those info.
So if in project options I am working on release 2.4.3.178
inside my application I have 4 integer variables that hold the 4 numbers.
I manually set them
Major := 2;
Minor := 4;
Release := 3;
Build := 178;
The reason of this is simple: I have licensing based on version number. So if the user buys release "2.4" it is not allowed to upgrade to version "3.0".
But if I rely on project version info the user can (with Resource Hacker tools) change the version info and therefore "activate" the product.
The user cannot change the 4 variables in the same way (not as easily at least).
This works but forces me duplicate the info.
Could you suggest a better approach?
Otherwise said: is there a way to write the version info using the data I write in those 4 variables. Something like in Post Build Events, but how do I pass data to post build events?
You'd need a pre-build event rather than a post-build event since you'd want to get the .res file built before linking.
I do something very similar with a simple Perl script that reads an include file (.inc) containing constant declarations of the version numbers. I read them in using a regex and then create my .rc file which I pass to brcc32. It's all invoked as a pre-build action.
Since you're on Delphi-XE and have Final Builder, why don't you put it to good use and make your "final" build from it? It can give a very nice solution to the version number problem, and can do a lot more.
Here's how I'd do it.
Set up a small INI file that holds the relevant parts of the version information.
Optionally make a small Delphi forms application that reads the version number from the INI files and gives you a chance to change it. When changes are saved to the INI file, the delphi application should automatically generate a small Delphi PAS file that defines the constants!
Create a FinalBuilder project that does the following:
Calls your Delphi exe to set up version number. You'll be in charge of changing whatever needs changing, and this is probably appropriate since your licensing scheme depends on version information.
Set up a few project variables to hold the version information numbers
Add "Read INI file" actions to read the version information from the ini files into your project variables.
(optional) Build the unit test project, if you have one.
(optional) Call the unit test project.
Add a "build Delphi project" action, set it up to build your project using whatever options you need. Add a small "Before" script to set up the version information numbers to what you've got in the project variables you just read from the INI file.
(optional) create setup packages using whatever tool you use.
(optional) upload those setup packages to a website.
In other words, take the opportunity to start using Final Builder.
Moving your version numbers into code is also easy to get around.
One way to pass the information is to generate a version.rc file programmatically (you write a tiny build tool yourself using delphi or a scripting language of your choice), and link the resources to the program, instead of using the built in version-info feature.
Your question seems to be fundamentally a matter of preventing the user from modifying (easily) the version number once you have determined it.
So my suggestion is that you encrypt the version number and you use the encrypted version, instead of the version in the VersionInfo structure.
I have used DCPCRYPT for things like this. But if you hope to be hacker-proof let me just say this; Anything you can do, hackers can undo. If you want to be more secure, you will also need to tamper proof your whole application. There are commercial tamper proofing solutions but none work fabulously out of the box with Delphi.

How can I automatically give an .exe a unique name at compile time?

I want the exe name of an application given 'ProgramExeName + version number' at compilation time (exemple: Filename18190.exe, Filename18191.exe...) - so the exe name is never the same. Considering i have the version number put in a str variable, how to automatically append this number to the exe name currently built? Tx
(Note: i want the renaming be done at compilation time, not manipulated after)
There are several directives to manipulate the filename of output binary {$EXT string}, {$LIBPREFIX 'string'}, {$LIBSUFFIX 'string'}, {$LIBVERSION 'string'} (btw, compiler have nothing with with forming output binary, this done by linker). Neither of them is dynamic, so you HAVE to write desired values right before building your project (good job for OpenToolAPI wizard in the IDE).
The other possibility is post-build activity which extracts version number (for example: VERSION_INFO) from PE binary and renames the file accordingly
If it must be done by the compiler, then no, Delphi simply wont do that. The name of the exe is the name of the project. Run a batch file after the build (I believe later delphi's let you do this) and rename the file to whatever you want. You may need to create a seperate helper program to extract the build number from the program's resources so that you can use that in the name.
the filename is generated automatically from the project file, you can't change that. But look at post build events, maybe you can figure out something that changes the filename after a successful build
You could write a batch file / makefile / Rakefile / whatever that runs the compile steps and then just renames it according to the system time or something like that. Your question is a little vague, so it's hard to say precisely, but it's a thought.
There is no way to do that in Delphi for normal executables. For packages there is the LIB suffix option, which could probably be manipulated to do what you want but that won't help you.
Hm, thinking about it, maybe it would be possible to write an IDE addon that uses the ToolsAPI to save the project with a different name every time you do a build. You would end up with as many project files as executables. I don't know whether it can be done.

How do you copy arbitrary data to the clipboard as a file?

We develop a database application. The user asks for a new feature: Copy blobs into the clipboard such that Windows Explorer can paste them as new files. One solution is to save the blobs into a temporary folder and add these temporary files to the clipboard.
But I'm looking for a better solution. Is it possible to hook the paste action in Windows Explorer and save the blobs to the destination path by myself?
I've never tried it but I think it is indeed possible. Please take a look at the MSDN Documentation for Shell Clipboard Formats. CFSTR_FILECONTENTS and CFSTR_FILEDESCRIPTOR are the formats you are likely supposed to handle.
Additionally, I found an article at Code Project which provides a demo program: How to drag a virtual file from your app into Windows Explorer.
Update: An example written in .NET:
Creating something from nothing
Creating something from nothing, asynchronously
From the MSDN article Handling Shell Data Transfer Scenarios
Existing files should be offered with the CF_HDROP format.
Offer file-like data with CFSTR_FILECONTENTS/CFSTR_FILEDESCRIPTOR
formats. This approach allows the
target to create a file from a data
object without needing to know
anything about the underlying data
storage. You should normally present
the data as an IStream interface. This
data transfer mechanism is more
flexible than a global memory object
and uses much less memory.
Two other good articles to read from MSDN are:
Shell Data Object
Shell Clipboard Formats
When I first started working on using the clipboard to transfer files I printed off all three articles and read them several times.
Dealing with the interfaces can be quite involved. I have found two good libraries out there to help with this.
The The Drag and Drop Component Suite for Delphi. If you scroll down on the home page you will see some FAQs are good reading. There are also a lot of sample applications with the download. I think the AsyncSource demos should be helpful for what you are looking for. The suite is freeware with source. The code seems to be well commented.
I am currently using the Transfer#Once component from Quasidata. It is not free but is very inexpensive. I initially used Transfer#Once because at the time it was better supported than the Drag and Drop component suite. However, that situation has reversed itself. Transfer#Once does not yet support Delphi 2009. When I get around to moving my application I will probably switch components. The Transfer#Once code is included with purchase. Personally I found the Drag and Drop code to be much easier to read and follow.
I'd say that explorer does the copying to the destination files itself, so there's no way to directly write the destination files. This makes sense, because the names of the source files can only come from the application that copied the data to the clipboard, which need not be explorer. OTOH the names of the destination files may actually differ, because files of the same name could already exist in the destination folder, and only explorer can create the modified names for the destination files (like by prepending "Copy of " or by appending " (2)" to the base file name).
You will need to provide the clipboard format for the Windows Explorer so that it can paste the files. The documentation of standard clipboard formats suggests that CF_HDROP is the right one. With this clipboard format you would provide a list of source file names, but the files do need to exist of course, so you will need to save them to disc.
You could try to make the process as light-weight as possible, though. Usually when a user copies data to the clipboard it is put there immediately, whether or not it will be used for a paste operation. For your application that would mean that you would need to create the files and put the list of file names into the clipboard, every time. However, Windows does support a mode called Delayed Rendering, which is used exactly for such cases. Basically you put only an empty stub of the data onto the clipboard, and only when another application tries to access the data it will be requested from your app. So you could implement this in a way that only when the user tries to paste the files into explorer you would save them to disc and return the list of file names.
It's been a while since I toyed with copy/paste, but I'm pretty sure you can do what you're suggesting (insert the blob as a new file into the clipboard).
I seem to remember that depending on how you add to the clipboard you can specify what sort of data you're copying. I think if you get that data type right, you'll be able to paste as though you'd copied from windows explorer.
I'll try and dig out some more details this evening if I have a chance (I don't have all my bookmarks here at work)...
[Edit] Have a look at the wxWidgets documentation on drag and drop. That was what I'd been working with and it gives some hints about data types.
What are you writing in? Delphi?
[Edit2] I think this may actually be a limitation of Windows(?). It might just be the wxWidgets documentation, but there's a suggestion that you only copy filenames rather than the files themselves. If that's the case, you're going to have to ue your original suggestion of creating a temp file first :-(

Organizing the search path

We create via "Tools | Options | Environment Variables" Variables like that:
$(Sources) = D:\Sources\Delphi
$(OurLib) = $(Sources)\OurLib\Src
$(OurApp1) = $(Sources)\Applications\App1\3.x
$(ThirdParty) = $(Sources)\ThirdPartyComponents
We use these Variables in the project search path like that:
($OurApp1)\Src\Core;($OurApp1)\Src\GUI;($OurApp1)\Src\Plugins;$(ThirdParty)\JVCL
But this is broken (meanwhile fixed) since Delphi 2009 as these variables are not evaluated completely anymore (see QC #73276). So the files in the directories are not found by the compiler. A workaround: Use only complete directories in the environment variables.
We use this approach because on all developer machines and the build servers the files can be found and we only have to point $(Sources) to the right place.
We don't have anything in our global library path (except the Delphi defaults), because that wouldn't be in the version control and isn't reflected on other developers or build machines.
One problem is: If one unit in $(OurLib) decides to include another new unit maybe in a new path, all projects break because they don't find this new unit. Then we have to go through all projects and add the search path. (BTW: I really hate the search path editor...wouldn't be a simple memo field much better to edit than this replace/add/delete logic?)
Another thing we do is not adding many units to our project. Especially everything from $(OurLib), but we often have units like plugins which add functionality only by including them. For different editions of our products, we want to include different units. As Delphi always messes up $IFDEFs in the uses clause in the .dpr we help us by including units named like "IncludePlugins" which then include the units depending on IFDEFs.
But not including units in the project makes navigating to a pain. The units don't appear in the project, they are not found by Ctrl+12 (Show Units), they are not shown in code completion etc.
Has anybody a better way to cope with these problems?
We use only relative paths, any libraries are always below the libs subdirectory while the project source code resides in the src subdir. So our search paths always look like:
..\libs\library1;..\libs\library2\common;
etc.
All libraries are added as svn:external to each project, so checking out the project will automatically check out the libraries as well and the search path will always point to the correct version of the library for that project.
Not perfect, but it works most of the time.
I have to agree about the search path editor, it is even worse for relative paths because you must not use the "..." buttons otherwise Delphi will insert an absolute path.
We use standard drive mappings.
Our current project is always on W: regardless if it is a network drive or a substitute.
This works great.
When you need to work on a different project, swap the W: and you can continue.
You can copy the search path out to an editor, modify it and then copy it back.
Your search path is much too big. It should contain only the things you want Delphi to recompile with your project. You don't really want to recompile the Jedi VCL every day, do you?
I create a single directory where all compiled units go. Say, C:\dcu. Specify that as the "unit output directory" in all packages. My "search path," then, is always just this:
$(Delphi)\Lib;C:\dcu
The compiler finds everything it needs, and it never finds any source code. The only source code it ever sees is in the files that directly belong to whatever project I'm compiling. The project's own source directories don't need to be on the search path because all of those files are already direct members of the project. The compiler knows exactly where they are.
For me, all a project's source files go in a single directory. If you want separate directories for different parts, like Core and GUI, then I would put those in separate packages so I could work on them and compile them separately. Even if the final program doesn't use the resultant BPLs, packages are still a good way of segmenting your project and defining dependencies.
When compiling units for one project doesn't automatically compile units for all the other projects, you're forced to change active projects. It takes a moment of your time, but it also serves as a mental reminder that you're "changing hats," too.
Although you're producing just one product, that doesn't mean you should have just one project in Delphi. You should have at least one project for each executable module (EXE, DLL, BPL) in your product. Use project groups to manage multiple projects in a single IDE session. No unit should be a member of more than one project.
I don't understand your part about plug-ins and different editions of your project. When you say "plug-in," I assume you're talking about separate executable modules, like DLLs or packages, that the customer can choose to include or not. Couldn't you turn your different editions' features into plug-in modules that simply don't include in the lesser editions? Then you don't have to worry about conditional compilation of your project; just have several different installer packagers that grab different sets of plug-ins.
I have always found it odd that this has never been addressed adequately. I suggested recently to David I that Delphi should allow the user to set up some sort of preferred development structure and that third party library publishers could be made aware of this so that they could automatically adjust their installers to install correctly in the preferred development framework. If the preferred development structure was stored in an XML file or similar, then, it could be copied from one computer to another on a development team.
As an alternative, it could make an interesting project to create a Delphi application that would allow a user to "refactor" their library installation in a high level way. You specify which folders on your system contain source or compiled components or whatever and where you want to keep source files or compiled units, hit Go and your system gets rearranged for you, while updating your Delphi environment so that when you start Delphi, it finds everything it should.
I've just recently discovered a way to have project specific environment variables in delphi builds using XE6, it's not quite as good as a full blown #define like in C but at least I can now have consistent search paths across multiple projects and create some shared option sets.
What I've done is setup environment variables in the same manner as the original poster and then override them in the dproj or optionset.
The BuildPaths.optset added to the project looks like
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<SVN_Root>..\..\..</SVN_Root>
<SVN_Riemann>$(SVN_Root)\Riemann</SVN_Riemann>
<SVN_Library>$(SVN_Root)\Library</SVN_Library>
<SVN_ThirdParty>$(SVN_Library)\Third Party</SVN_ThirdParty>
</PropertyGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType>OptionSet</Borland.ProjectType>
<BorlandProject>
<Delphi.Personality/>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
</Project>

Resources