Sometimes it is useful to create a native Windows application that has no DLL dependencies. An example would be creating a simple tool application that you wish to share with others. If you need to ensure that end users have a large DLL installed to support the run time environment, this is can be counterproductive to making it easy. The solution is to use a native Windows application and statically link all required libraries into the single executable file. The user can run the application without installing anything, just by having the single executable.
Back in the days of Microsoft Visual Studio 6, you could by default make small Dialog-based executables that would compile into an EXE of only a few hundred kB in size. Somewhere along the road from 1998 to Microsoft's 2017 version of Visual Studio, the default size got a lot larger. Today, if you accept all default options, your Dialog-based GUI application will begin weighing in at a hefty 3.3MB.
Can't we do better than that? Yes! By judiciously selecting options and following the advice below, we can trim that number down by a factor of ten. Here's how to do it:
Using the New Project Wizard to create a SMALL MFC GUI EXE
1. Run the Wizard and select MFC Application.
2. Select Application Type: "Dialog based".
3. Turn off SDL Checks.
4. Select Dialog based Options: "No enhanced MFC controls".
5. Select "Use MFC in static library".
6. Turn OFF all advanced features, including:
a. Print and Print Preview
b. ActiveX Controls
c. Common Control Manifest
d. Support Restart Manager
7. Let the Wizard complete its actions.
8. Go into the project properties, and change Unicode char setting to Multi-Byte Char set.
9. Edit stdafx.h to be as follows below. This helps the EXE be very small.
#pragma once
#define _WIN32_WINNT 0x0601 // This defines oldest OS allowed.
#include <sdkddkver.h>
#define _AFX_NO_MFC_CONTROLS_IN_DIALOGS
#define VC_EXTRALEAN
#define WIN32_LEAN_AND_MEAN
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS
#define _AFX_ALL_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#include <afxwin.h> // MFC core and standard components.
#include <afxext.h> // MFC extensions.
#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls.
#include <afxcmn.h> // MFC support for Windows Common Controls.
10. Remove the file targetver.h. The edited stdafx.h as above makes this file OBE.
11. Open the ICON section of the resource, and delete all of the icons except 32x32, 8-bit.
12. In the main dialog class, delete the call to SetIcon() for small icon. Not needed.
13. Test building the Release target. It should be a nice small ~293 kB size.
Other tips:
A. Hand-edit the *.vcxproj file and make sure stdafx is built first. Both h and cpp in their respective lists. As new files are added later to the project, you will have to go in and move these to the bottom too. I consider this a bug with the tool because it puts new files at the top and this sometimes breaks the build. Nothing should build prior to stdafx.
B. Turn off Precompiled Headers option. Many times this option creates mysterious problems. Then remove the precompiled header related lines from *.vcxproj.
C. Click the dropdown for "x86/x64" (right of "Release/Debug") and go to Configuration manager and remove the x64 option. This will remove it from the solution file, but you will have to go in by hand and find and remove them from the project file. Search for "x64".
Back in the days of Microsoft Visual Studio 6, you could by default make small Dialog-based executables that would compile into an EXE of only a few hundred kB in size. Somewhere along the road from 1998 to Microsoft's 2017 version of Visual Studio, the default size got a lot larger. Today, if you accept all default options, your Dialog-based GUI application will begin weighing in at a hefty 3.3MB.
Can't we do better than that? Yes! By judiciously selecting options and following the advice below, we can trim that number down by a factor of ten. Here's how to do it:
Using the New Project Wizard to create a SMALL MFC GUI EXE
1. Run the Wizard and select MFC Application.
2. Select Application Type: "Dialog based".
3. Turn off SDL Checks.
4. Select Dialog based Options: "No enhanced MFC controls".
5. Select "Use MFC in static library".
6. Turn OFF all advanced features, including:
a. Print and Print Preview
b. ActiveX Controls
c. Common Control Manifest
d. Support Restart Manager
7. Let the Wizard complete its actions.
8. Go into the project properties, and change Unicode char setting to Multi-Byte Char set.
9. Edit stdafx.h to be as follows below. This helps the EXE be very small.
#pragma once
#define _WIN32_WINNT 0x0601 // This defines oldest OS allowed.
#include <sdkddkver.h>
#define _AFX_NO_MFC_CONTROLS_IN_DIALOGS
#define VC_EXTRALEAN
#define WIN32_LEAN_AND_MEAN
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS
#define _AFX_ALL_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#include <afxwin.h> // MFC core and standard components.
#include <afxext.h> // MFC extensions.
#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls.
#include <afxcmn.h> // MFC support for Windows Common Controls.
10. Remove the file targetver.h. The edited stdafx.h as above makes this file OBE.
11. Open the ICON section of the resource, and delete all of the icons except 32x32, 8-bit.
12. In the main dialog class, delete the call to SetIcon() for small icon. Not needed.
13. Test building the Release target. It should be a nice small ~293 kB size.
Other tips:
A. Hand-edit the *.vcxproj file and make sure stdafx is built first. Both h and cpp in their respective lists. As new files are added later to the project, you will have to go in and move these to the bottom too. I consider this a bug with the tool because it puts new files at the top and this sometimes breaks the build. Nothing should build prior to stdafx.
B. Turn off Precompiled Headers option. Many times this option creates mysterious problems. Then remove the precompiled header related lines from *.vcxproj.
C. Click the dropdown for "x86/x64" (right of "Release/Debug") and go to Configuration manager and remove the x64 option. This will remove it from the solution file, but you will have to go in by hand and find and remove them from the project file. Search for "x64".
Comments
Post a Comment