A new tool to save and restore the console font

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
jfl
Posts: 226
Joined: 26 Oct 2012 06:40
Location: Saint Hilaire du Touvet, France
Contact:

A new tool to save and restore the console font

#1 Post by jfl » 07 Dec 2018 08:27

Hello,

Earlier this week, I've been hit by a problem with the console font unexpectedly changing when I ran a new batch script on one of my test systems.
I quickly found the root cause, which was another PowerShell script called from a batch script.
Surprisingly, the PowerShell script was innocent. It's PowerShell itself that always changes the cmd.exe console font to the Terminal raster font, anytime it's invoked on that machine.
I have no idea why this happens on that machine, and not on the other test machines I have.

This apparently has a different cause, but the same disrupting effects, as the problem reported in thread 8205.

Anyway, I started thinking about how to work around that, and I eventually found a way to automate it:
I already had a C program that enumerated the console font sizes.
All I had to do was to add options for saving the current font name and size, then restoring them later on.

Here comes font.exe version 2.0, available at:
https://github.com/JFLarvoire/SysToolsLib/releases

Example run on the machine that has the unstable font issue:

Display the current font:

Code: Select all

F:\Temp>font
[TrueType] Lucida Console (8 x 14)

F:\Temp>
List fixed size fonts usable in the console:

Code: Select all

F:\Temp>font -l
CHARACTERS      CHARSET     TYPE         NAME
'\x01'-'\xFE'   OEM         Raster       Terminal
'\x20'-'\xFF'   ANSI        Raster       Fixedsys
'\x20'-'\xFF'   ANSI        Raster       Courier
'\x00'-'\xFF'   ANSI        Device       HPE Simple
'\x00'-'\xFF'   ANSI        Device       HPE Simple Light
'\x00'-'\xFF'   ANSI        TrueType     Consolas
'\x1E'-'\xFF'   ANSI        TrueType     Courier New
'\x1E'-'\xFF'   BALTIC      TrueType     Courier New Baltic
'\x1E'-'\xFF'   EASTEUROPE  TrueType     Courier New CE
'\x1E'-'\xFF'   RUSSIAN     TrueType     Courier New CYR
'\x1E'-'\xFF'   GREEK       TrueType     Courier New Greek
'\x1E'-'\xFF'   TURKISH     TrueType     Courier New TUR
'\x1E'-'\xFF'   ANSI        TrueType     Lucida Console
'\x00'-'\xFF'   ANSI        TrueType     MS Gothic
'\x00'-'\xFF'   ANSI        TrueType     @MS Gothic
'\x1E'-'\xFF'   ANSI        TrueType     NSimSun
'\x1E'-'\xFF'   ANSI        TrueType     @NSimSun
'\x1E'-'\xFF'   ANSI        TrueType     SimSun-ExtB
'\x1E'-'\xFF'   ANSI        TrueType     @SimSun-ExtB
'\x1E'-'\xFF'   ANSI        TrueType     Lucida Sans Typewriter
Total: 20 fonts

F:\Temp>
Save the current font; Run the breaking script; Restore the initial font:

Code: Select all

F:\Temp>for /f "delims=" %f in ('font -s') do @set OLD_FONT=%f

F:\Temp>set OLD_FONT
OLD_FONT="Lucida Console" 8x14

F:\Temp>powershell -c $PSVersionTable

Name                           Value
----                           -----
PSVersion                      5.1.16299.666
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.16299.666
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1



F:\Temp>font
[Raster] Terminal (8 x 12)

F:\Temp>font %OLD_FONT%

F:\Temp>font
[TrueType] Lucida Console (8 x 14)

F:\Temp>
Recommended: Create a savefont.bat script, with the same for ... instruction, just changing both %f to %%f in the batch.

Limitations:
  • Does not work in Windows XP, due to the GetCurrentConsoleFontEx() API missing there. font.exe runs, but does not detect the current font name.
    Any help at achieving the same results with the old APIs is welcome!
  • Conversely, in Windows 10, the GetConsoleFontInfo() API returns no information about other available font sizes.
    And for the older versions of Windows up to 8, the information it returns is indirect only, leading to font.exe option -p sometimes listing incorrect sizes (especially for large font sizes).
    Any help at finding a reliable way to get available font sizes for all versions of Windows is welcome!
The program source is available there on GitHub.

Enjoy!

Jean-François

aGerman
Expert
Posts: 4654
Joined: 22 Jan 2010 18:01
Location: Germany

Re: A new tool to save and restore the console font

#2 Post by aGerman » 08 Dec 2018 10:47

That's neat, Jean-François :)
jfl wrote:
07 Dec 2018 08:27
Any help at finding a reliable way to get available font sizes for all versions of Windows is welcome!
I don't care about old Windows versions anymore. But I think the only way to work around is a code switch depending on the current Windows version. Two functions that may help you:

Code: Select all

#include <stdio.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

/** \brief Get the current Windows version.
 *  \param  No parameter.
 *  \return Pointer to an array that contains the major version, minor version, and build number. NULL if the function failed. */
ULONG *GetWinVer(void)
{
  static ULONG buffer[69] = {69 * sizeof(ULONG)}; // Replacement for the RTL_OSVERSIONINFOW structure having the same size.
  if (buffer[1] != 0u) // That is, the function was called more than once and the buffer already contains the version information.
    return buffer + 1; // Skip the first element that contains the size of the buffer.

  long(__stdcall *p_RtlGetVersion)(ULONG*) = NULL;
  HMODULE ntoskrnl = LoadLibraryA("NtosKrnl.exe");
  if (ntoskrnl != NULL)
  {
    if ((p_RtlGetVersion = (long(__stdcall *)(ULONG*))GetProcAddress(ntoskrnl, "RtlGetVersion")) != NULL)
      p_RtlGetVersion(buffer);

    FreeLibrary(ntoskrnl);
  }

  return p_RtlGetVersion == NULL ? NULL : buffer + 1;
}


/** \brief Compare the current Windows version with a certain major and minor version.
 *  \param p_ver  Array with at least two elements containing the current major and minor version.
 *  \param major  Major version to be compared with the current version.
 *  \param minor  Minor version to be compared with the current version.
 *  \return 1 if the current version is newer, -1 if the current version is older, 0 if the current version is equal. */
int CompWinVer(const ULONG *const p_ver, const ULONG major, const ULONG minor)
{
  // compare major versions first
  if (p_ver[0] < major) return -1;
  if (p_ver[0] > major) return 1;
  // at that point major versions are equal, compare minor versions
  if (p_ver[1] < minor) return -1;
  if (p_ver[1] > minor) return 1;
  // both major and minor versions are equal
  return 0;
}


int main(void)
{
  ULONG *p_version = GetWinVer();

  if (p_version != NULL)
  {
    printf("%lu.%lu.%lu\n", p_version[0], p_version[1], p_version[2]); // Major version, minor version, build number.

    int comp = CompWinVer(p_version, 6, 1);
    printf("The current version %s Windows 7.\n", comp == 0 ? "is" : (comp > 0 ? "is newer than" : "is older than"));

    return 0;
  }

  return 1;
}
Steffen

carlos
Expert
Posts: 503
Joined: 20 Aug 2010 13:57
Location: Chile
Contact:

Re: A new tool to save and restore the console font

#3 Post by carlos » 26 Dec 2018 19:55

Hello jfl, nice tool. As said aGerman, support for old windows xp I see unnecesary. For change the font with undocumented functions the only font available is Terminal.
On windows xp also exists a undocumented function for get the sizes of that font, but that undocumented function stopped working with windows 10, the undocumented function was: "GetConsoleFontInfo"
The undocumented "SetConsoleFont" continues working.
I have source code related with setting the raster fonts compatible with windows xp here:
In the bg program in the function font, and in the program pixelfnt.
https://web.archive.org/web/20180926041 ... .com/p/bg/

misol101
Posts: 475
Joined: 02 May 2016 18:20

Re: A new tool to save and restore the console font

#4 Post by misol101 » 28 Dec 2018 04:51

If I understand correctly, then Cmdwiz "savefont" and "setfont" would also do what you needed to do here

jfl
Posts: 226
Joined: 26 Oct 2012 06:40
Location: Saint Hilaire du Touvet, France
Contact:

Re: A new tool to save and restore the console font

#5 Post by jfl » 07 May 2019 07:50

font.exe version 2.1.1 is now available on https://github.com/JFLarvoire/SysToolsLib/releases, with the following changes:
  • Fixed the TrueType fonts setting, which sometimes ended up looking blurry.
  • Added an optional font weight argument.
Run 'font -?' to get a help screen.

Post Reply