How do I add an icon to a mingw-gcc compiled executable? - windows

In Windows, using mingw's gcc, is there anyway to specify that the output exe file is to take an icon file, so that the exe file shows with that icon in explorer?

You need to create the icon first. Then you need to create a RC file with the below content. Here we'll name it as my.rc.
id ICON "path/to/my.ico"
The id mentioned in the above command can be pretty much anything. It doesn't matter unless you want to refer to it in your code. Then run windres as follows:
windres my.rc -O coff -o my.res
Then while building the executable, along with other object files and resource files, include my.res which we got from the above step. e.g.:
g++ -o my_app obj1.o obj2.o res1.res my.res
And that should be all there is to it.
And, at no extra charge, if you want to include version information in your
application, add the following boilerplate to a new .rc file and follow the above mentioned steps.
1 VERSIONINFO
FILEVERSION 1,0,0,0
PRODUCTVERSION 1,0,0,0
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "080904E4"
BEGIN
VALUE "CompanyName", "My Company Name"
VALUE "FileDescription", "My excellent application"
VALUE "FileVersion", "1.0"
VALUE "InternalName", "my_app"
VALUE "LegalCopyright", "My Name"
VALUE "OriginalFilename", "my_app.exe"
VALUE "ProductName", "My App"
VALUE "ProductVersion", "1.0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x809, 1252
END
END
Note, the langID is for U.K. English (which is the closest localisation to
Australia I could identify.) If you want U.S. "English" then change the BLOCK
line to:
BLOCK "040904E4"
and the translation line to:
VALUE "Translation", 0x409, 1252
See VERSIONINFO resource for for info.

In the RC file, the nameID does not even have to be a name, it can just be
an integer. The filename must be quoted only if it contains a space. Instead
of:
windres my.rc -O coff -o my.res
You can use:
windres my.rc my.o
ICON resource
windres man page
Example

Try Resource Hacker. I was able to cross compile my project in Linux (WSL) and generate an icon from the logo on the homepage. Just needed a simple way to embed it in the exe and this program worked great.
Resource Hacker by Angus Johnson

Related

Including 'Run Script' phase output files in build

In Xcode 7, you can create 'Run Script' phases in the Build Phases tab. At the bottom of the area, there's an 'Input Files' section and an 'Output Files' section.
I have a script that generates a .cpp file at $(DERIVED_FILE_DIR)/myfile.cpp. The file is listed in the 'Output Files' section of the phase. However, it appears that it's not compiled into my program, as the symbol that it defines are identified as missing by the linker.
How can I tell Xcode to compile this file as well?
One possible solution (which feels like a hack) is to insert the built file into the project, set its location (in the Identity and Type section of the Utilities bar) and then edit its location in the project file with a text editor for computer independence. In my case, the file entry (with newlines for readability) now looks like:
DC40C4121C7FC98F0087702A /* bindings.cpp */ = {
isa = PBXFileReference;
lastKnownFileType = sourcecode.cpp.cpp;
name = myfile.cpp;
path = "$(DERIVED_FILE_DIR)/myfile.cpp";
sourceTree = "<absolute>";
};
This is interpreted by the file browser as a file whose absolute path is literally $(DERIVED_FILE_DIR)/myfile.cpp (and the file always shows in red in the project explorer), but the build system will grab the file from the correct location.

rename file with the name of installer name in NSIS installer?

I'm working with NSIS installer. I need to change file defined in install path to the same installer name.
I try to use rename function like:
Rename "$INSTDIR\app.exe" "$INSTDIR\installname.exe"
but I need the installer name automatic.
Take a look at the constants, $EXEFILE is the filename, or $EXEPATH for the full path. If you want the name attribute you used in your source file, it is $(^Name)...
From FileFunc header you can combine GetExeName and GetFileName macros to get the installer's name:
!include "FileFunc.nsh"
OutFile test.exe
section main
${GetExeName} $R0
${GetFileName} "$R0" $R1
MessageBox MB_OK "My installer's exe is $R1"
sectionend
Now you can test it yourself.

"File version" in Windows properties value is FILEVERSION not "FileVersion"

So Product Management have decreed that our software should have version numbers with 3 sets of digits rather than the usual 4 (e.g. 1.2.3 rather than 1.2.3.4)
This is easily accomplished in the "About" dialogs and elsewhere in UI, but I'm having issues with Windows properties.
When I change the values in VERSIONINFO block to:
FILEVERSION 1,2,3
PRODUCTVERSION 1,2,3
VALUE "FileVersion", "1.2.3"
VALUE "ProductVersion", "1.2.3"
I end up with the following in Windows 7's Properties > Details tab for the exe:
File version: 1.2.3.0
Product version: 1.2.3
Changing the values to all be different indicates that "File version" is taken from FILEVERSION and so always formatted as a 4-digit group value, but "Product version" is taken from "ProductVersion".
Is there any way to specify that "File version" should be taken from the "FileVersion" string value? If I remove the FILEVERSION block I just end up with a "File version" of 0.0.0.0.
I have reproduced this behaviour in VS2010 by creating an empty Win32 console application, then adding a default version resource:
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,1
PRODUCTVERSION 1,0,2
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "080904b0"
BEGIN
VALUE "CompanyName", "TODO: <Company name>"
VALUE "FileDescription", "TODO: <File description>"
VALUE "FileVersion", "1.0.3"
VALUE "InternalName", "VersionT.exe"
VALUE "LegalCopyright", "Copyright (C) 2012"
VALUE "OriginalFilename", "VersionT.exe"
VALUE "ProductName", "TODO: <Product name>"
VALUE "ProductVersion", "1.0.4"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x809, 1200
END
END
Resulting in the same issue:
properties http://media.use.com/images/s_1/4ba4e5b1b235179b1c9a.jpg
This image may come out small, so I'll just confirm that it says
File version 1.0.1.0
Product version 1.0.4
Before I tell Product Management that this is the best we can do, is there any way to get Windows to show the "FileVersion" string value instead? I've read through the VERSIONINFO documentation on MSDN, and can't see any flags that I can set to do this.
After building and installing this shell extension I found at CodeProject, it seems that this is due to Windows 7 displaying only a subset of the versioninfo properties, and there's nothing I can do to change it. The FileVersion string is present in the exe, it just isn't displayed in the default properties dialog.

How to programmatically change a project's product version?

I have several deployment projects. In order to deploy an application, I need to do several tasks, one of them is to change each deployment project's product version and product code.
I can't find a way to programmatically change them.
Since it's a Deployment project (which finally produces an executable installer), I'm not able to work with MSBuild, instead I'm using the Devenv from the command prompt.
I was searching for the exact same thing today. I found this using google:
static void Main(string[] args)
{
string setupFileName = #"<Replace the path to vdproj file>";
StreamReader reader = File.OpenText(setupFileName);
string file = string.Empty;
try
{
Regex expression = new Regex(#"(?:\""ProductCode\"" =
\""8.){([\d\w-]+)}");
Regex expression1 = new Regex(#"(?:\""UpgradeCode\"" =
\""8.){([\d\w-]+)}");
file = reader.ReadToEnd();
file = expression.Replace(file, "\"ProductCode\" = \"8:{" +
Guid.NewGuid().ToString().ToUpper() + "}");
file = expression1.Replace(file, "\"UpgradeCode\" = \"8:{"
+ Guid.NewGuid().ToString().ToUpper() + "}");
}
finally
{
// Close the file otherwise the compile may not work
reader.Close();
}
TextWriter tw = new StreamWriter(setupFileName);
try
{
tw.Write(file);
}
finally
{
// close the stream
tw.Close();
}
}
I know that the original poster is looking for a .NET 2.0 solution to this problem. However, since this wasn't tagged as .NET, I'll offer up my C++ solution to the problem. This may be applicable in .NET land, but I'll leave that to others.
This not only updates the version information in the about box and log file for my application, but also all of the Windows version info that is seen in Windows Explorer.
UPDATE: Added some changes that I've made to the process since my original answer.
First off, I moved the entire version info block from my Project.rc file to my Project.rc2 file:
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION FILE_VER
PRODUCTVERSION PROD_VER
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904e4"
BEGIN
VALUE "CompanyName", "MyCompany"
VALUE "FileDescription", "Software Description"
VALUE "FileVersion", 1,0,0,1
VALUE "InternalName", "FileName.exe"
VALUE "LegalCopyright", "(c) 2008 My Company. All rights reserved."
VALUE "OriginalFilename", "FileName.exe"
VALUE "ProductName", "Product Name"
VALUE "ProductVersion", 1,0,0,1
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1252
END
END
This essentially transports all of the version info stuff that you would edit from the resource editor into a separate file. This makes it so that you don't get errors when editing the resource file from outside of the editor. The downside is that you can no longer edit the version info from the resource editor. But, since we want this stuff updated automatically, that isn't a big deal.
Next, I created a VersionInfo.h file and added it to my project:
#pragma once
//major release version of the program, increment only when major changes are made
#define VER_MAJOR 2
//minor release version of the program, increment if any new features are added
#define VER_MINOR 0
//any bugfix updates, no new features
#define VER_REV 0
//if this is some special release (e.g. Alpha 1) put the special release string here
#define STR_SPECIAL_REL "Alpha 1"
#define FILE_VER VER_MAJOR,VER_MINOR,VER_REV
#define PROD_VER FILE_VER
//these are special macros that convert numerical version tokens into string tokens
//we can't use actual int and string types because they won't work in the RC files
#define STRINGIZE2(x) #x
#define STRINGIZE(x) STRINGIZE2(x)
#define STR_FILE_VER STRINGIZE(VER_MAJOR) "." STRINGIZE(VER_MINOR) "." STRINGIZE(VER_REV)
#define STR_PROD_VER STR_FILE_VER " " STR_SPECIAL_REL
#define STR_COPYRIGHT_INFO "©" BuildYear " Your Company. All rights reserved."
I then included VersionInfo.h in the rc2 file and made the following changes:
#include "VersionInfo.h"
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
<no changes>
VALUE "FileVersion", STR_FILE_VER
<no changes>
VALUE "LegalCopyright", STR_COPYRIGHT_INFO
<no changes>
VALUE "ProductVersion", STR_PROD_VER
<no changes>
With this setup, I could edit my build script (which uses Perl) to modify the version info in the VersionInfo.h file before rebuilding the entire project using the devenv command line.
One additional step that I added that may also be of interest (although it is not completely perfected yet, and may be a future question here) is to generate a unique build number every time the project is built. In the current incarnation, it always works for complete rebuilds, but only sporadically on incremental builds. What I did was create a file called build_number.incl that contains the following:
#define CurrentBuildNumber "20081020P1525"
Which is essentially the date and time that the build was started. I created a batch file that is run as a pre-build event to the project that generates this file. The script also defines BuildYear so that the copyright in the VersionInfo.h file always contains the year of the most recent build. The batch script is the following:
echo Generating Build Number
#For /F "tokens=2,3,4 delims=/ " %%A in ('Date /t') do #(
Set Month=%%A
Set Day=%%B
Set Year=%%C
)
#For /F "tokens=1,2,3 delims=/M: " %%A in ('Time /t') do #(
Set Hour=%%A
Set Minute=%%B
Set AmPm=%%C
)
#echo #define CurrentBuildNumber "%Year%%Month%%Day%%AmPm%%Hour%%Minute%" > "$(ProjectDir)\build_number.incl"
#echo #define BuildYear "%Year%" >> "$(ProjectDir)\build_number.incl"
echo ----------------------------------------------------------------------
This file is then included in any file in the project that needs to use the build number (i.e. the about box).
Some of this was gleaned from this CodeProject post.
Hopefully this info proves helpful.
I had the same problem, and I found out that modifying the .vdproj file in a prebuildevent does not exactly do what I like.
I used some other code to modify the msi file file after the the setup project has been build, so I use the postbuildevent.
See my blog-post here.
We use a program that updates each AssemblyInfo.cs or AssemblyInfo.vb based on a configuration file value. we run this executable before each build. That was the best we could do to automate this process. You can add a call to this batch process in your projects configuration as a pre build step.
You could use the msbuild task to update you product version. Check out this post from the MSBuild team on this subject.
Embedding SVN Revision number at compile time in a Windows app
In my answer to this question, I describe how I accomplish this task using SVN.
This may not be quite what you're after, but way back in the mists of time I wrote something called stampver, which can auto-increment a build number directly in the .exe file as a post-build step.
Resource Tuner Console
This console resource editor allows creating a reliable and repeatable
process for updating Product Version Information resources during the final
stage of the build process from the command prompt.
See specifically the batch manipulation of file version information page for greater details:
http://www.reseditor.com/rtc-solution-version-info.htm
I know this a very old thread, but here's a vbs solution to achieve the same end. Simply place this in your deployment folder next to the .vdproj file.
Function CreateGuid()
CreateGuid = Left(CreateObject("Scriptlet.TypeLib").Guid,38)
End Function
Const ForReading = 1, ForWriting = 2, ForAppending = 8
Set fso = CreateObject("Scripting.FileSystemObject")
Set RegEx = CreateObject("VBScript.RegExp")
For Each file in fso.GetFolder(".").Files
if (fso.GetExtensionName(file.Name) = "vdproj") then
WScript.Echo "Updating: " + file.Name
Set oFile = fso.OpenTextFile(file.Name, ForReading, True)
fileContents = oFile.ReadAll
oFile.Close
RegEx.Pattern = """ProductCode"" = ""8:{.*-.*-.*-.*-.*}"
fileContents=Regex.Replace(fileContents, """ProductCode"" = ""8:" & CreateGuid)
Set oFile = fso.OpenTextFile(file.Name, ForWriting, True)
oFile.Write fileContents
oFile.Close
end if
Next
Then in your real project, have a post build event similar to:
cd $(SolutionDir)\CustomWebSetup
cscript -nologo UpdateProductCode.vbs
This will update the vdproj with a new ProductCode in preparation for the next build. After the build is complete, VS will prompt for a reload of the deployment project.
Look into the use of RCS, CVS and/or subversion. I am only familiar with RCS; my understanding is that CVS is based on RCS but more comprehensive. I have read on various boards that subversion is the better, but I have never used it. RCS has been adequate for keeping track of changes and versions on all my documents and software projects.
RCS is here: http://www.cs.purdue.edu/homes/trinkle/RCS/
CVS is here: http://www.nongnu.org/cvs/
Subversion is here: http://subversion.tigris.org/

Programmatically updating FILEVERSION in a MFC app w/SVN revision number

How do I go about programmatically updating the FILEVERSION string in an MFC app? I have a build process that I use to generate a header file which contains the SVN rev for a given release. I'm using SvnRev from http://www.compuphase.com/svnrev.htm to update a header file which I use to set the caption bar of my MFC app. Now I want to use this #define for my FILEVERION info.
What's the best way to proceed?
An .rc file can #include header files just like .c files can. I have an auto-generated version.h file, which defines things like:
#define MY_PRODUCT_VERSION "0.47"
#define MY_PRODUCT_VERSION_NUM 0,47,0,0
Then I just have my .rc file #include "version.h" and use those defines.
VS_VERSION_INFO VERSIONINFO
FILEVERSION MY_PRODUCT_VERSION_NUM
PRODUCTVERSION MY_PRODUCT_VERSION_NUM
...
VALUE "FileVersion", MY_PRODUCT_VERSION "\0"
VALUE "ProductVersion", MY_PRODUCT_VERSION "\0"
...
I haven't tried this technique with an MFC project. It might be necessary to move your VS_VERSION_INFO resource to your .rc2 file (which won't get edited by Visual Studio).
Don't have enough points to comment yet, but whatever solution you choose keep in mind that FILEVERSION fields can only support a short integer. In our situation, our SVN revision was already above this and resulted in an invalid revision number in our FILEVERSION.
In your application.rc file there is a version block. This block controls the version info displayed in the filesystem.
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,1
PRODUCTVERSION 1,0,0,1
You can programmatically update this file. Make sure to open and save the file as binary. We have had issues where edits are done as text and the file gets corrupted.
Changing VS_VERSION_INFO will reflect when you right click on the file in Explorer and see properties only.
If you want to show the current SVN revision number in the Caption bar, i would suggest:
Have a script get the version number and generate version.h file just with
#define SVN_VERSION_NO xxx
Your project includes this version.h and uses that number to show in caption.
Maybe this can be helpful: Versioning Controlled Build

Resources