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.
Related
I have a large application to manage consisting of of three or four executables and as many as fifty .dlls. Many of the source code files are shared across many of the projects.
The problem is a familiar one to many of us - if I change some source code I want to be able to identify which of the binaries will change and, therefore, what it is appropriate to retest.
A simple approach would be simply to compare file sizes. That is an 80% acceptable solution, but there is at least a theoretical possibility of missing something. Secondly, it gives me very little indication as to WHAT has changed; It would be ideal to get some form of report on this so I can then filter out irrelevant (e.g. dates/versions copyrights etc..)
On the plus side :
all my .dcus are in a row - I mean they are all built into a single folder
the build is controlled by a script (.bat)(easy, for example, to emit .obj files if that helps)
svn makes it easy to collect together any (two) revisions for comparison
On the minus side
There is no policy to include all used units in all projects; some units get included because they are on a search path.
Just knowing that a changed unit is used/compiled by a project is not sufficient proof that the binary is affected.
Before I begin writing some code to solve the problem I would like to ask the panel what suggestions they might have as to how to approach this.
The rules of StackOverflow forbid me to ask for recommended software, but if anyone has any positive experiences of continuous integration tools that would help - great
I am open to any suggestion or observation that is relevant in this context.
It seems to me that your question boils down to knowing which units are contained in your various executables. Since you are using search paths, it will be hard for you to work this out ahead of time. The most robust way to find out is to consult the .map file that the compiler emits. This contains a list of all units contained in your executable.
Once you know which units are contained in each executable, you need to know whether or not anything has changed in those units. That information is contained in your revision control system. Put this all together and you have the information that you need.
Of course, just because the source code for a unit has changed, you might argue that re-testing is not needed. Perhaps the only change made was the version, or the date in a copyright label or some such. But it is asking too much to be able to ask a computer to make such a judgement. At some point you need a human to step up and take responsibility.
What is odd about this though is that you are asking the question at all. It seems to me to be enormously risky to attempt partial testing. I cannot understand why you don't simply retest the entire product.
After using it for > 10 years for commercial in-house and freelancer work in large projects, I can recommend to try Apache Ant. It is a build tool which supports dependencies, and has many very helpful features.
Apache Ant also integrates nicely with CI tools such as Hudson/Jenkins, Bamboo etc.
Another suggestion - based on experience with Maven - is to design the general software architecture as modular as possible. If modules (single or multiple source or DCU files in one directory) use a version number in the directory name as a version number, it is possible to control exactly how application are composed from these modules.
If you want to program such a tool yourself the approach would be something like this:
First you need to detect wheter there were any changes made to seperate source files. As you already figured out comparing the file size is bad idea as the file size can stay the same despite lots of changes made to it (as long as there is same amount of text in pas file its size won't change). So instead you could check the last modification time for specific file or create some hash value like MD5 hash for comparison (can be quite slow).
Then you need to generate yourself a dependancy tree which will tell you which files are used for which project/subproject.
Finally based on changes detected in seperate files you check the dependancy tree to see which projects needs to be recompiled.
The problem of such approach is that you would probably have to update the dependancy tree manually each time when new unit is added to the project or an existing one is removed from the project.
But the best way would be to go and use some version controll software istead of reinventing the wheel. I myself like the way how GIT works and I belive that with proper implementation of GIT into the project mannager itself could be quite powerfull do to GIT support of branching/subbranching (each project is its own branch, each version of your software can be its own subbranch).
Now latest version of Delphi does have GIT integration done though SVN but this unfortunately limits some of best GIT functionality. So if you maybe decide to go and integrate GIT support directly into Delphi I'm first in line to use it.
I am challenged with creating an automated release for a legacy Delphi (Delphi 2006) project.
I am a complete Delphi noob. So my question is maybe heading in a wrong direction ...
As far as I understood the release process of the given project it works like this:
A developer opens the project in Delphi Studio
Right-Click on the Project -> Properties -> Version Info
He sets the new version number of the next release in the Dialog.
He saves the project. This automatically generates the corresponding .resx file which contains the version number in binary form.
The .bsproj and the the .resx are checked in into source control
The automated build (Hudson) picks up the change and builds the release.
I would like to automate this process, since there are several projects that needs to get a new version number for each release.
I guess I could easily manipulate the .bsproj with a custom tool since it is xml.
However I am struggling with the generation of the .resx file which is currently done when saving the project in Delphi Studio.
Is there a way to automate the generation of the .resx? i.e. with a commandline-tool or something similar?
Or is there a smarter approach?
Any help is appreciated.
You can do it all in a batch file
Update the version numbers as specified in this SO question: change version number at build time
Use the DCC command-line compiler to build all the projects. There's plenty of documentation for that, basically you do just dcc32 <project>.dpr
DCC is e.g. documented here or here
I do wonder where your .resx files come from, but they can be converted as well. See this SO post.
Give it a go using these resources and for specific issues write a new SO question with your attempts so far.
I have a Delphi XE project and I'm trying to change the version number of the program before building it with MSBuild. Version number information is located in the DPROJ file but if I change these values the version number does not change. I think the reason for this is that when you change version number in the IDE, Delphi saves the changes to both DPROJ and RES files.
Is there a way to compile the RES file from the command line with the changes in DPROJ file? I found this question which suggested saving the version number in an INC file and including that to the project but this feels a bit more complex solution compared to just making changes in DPROJ.
shameless plug: http://www.dummzeuch.de/delphi/dzprepbuild/englisch.html
I ended up solving my problem with this answer. First I unchecked "Include version information in project" in Project Options and added VersionInformation.rc with dummy data. When my build batch file is executed, it generates the correct RC file and because that RC file is added in to the Delphi project, MSBuild uses the contained information for built executable.
I use FinalBuilder to handle the version info. Isn't the stripped version bundled with your Delphi? If not, it is definitely worth the money. Makes releasing a one click action.
Yes you are right. Delphi keeps the version number in both project file and resource file. Unfortunately, resource files' structure is a bit complicated so it is not easy to update programmatically. When I came across this need, I ended up using a tool "SetVersion.exe" which did the job for me. It might help you as well. See this link.
EDIT
Actually now I remember, I used a different tool named "ChangeRes.exe" and it worked smoothly (but it is not free). You can try both and see which one works for you.
Some years ago, I have writed a script to build and increment build number using ruby and rake. Very easy to use.
After the build, the script calls Inno Setup and generates a new installer.
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.
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.