hexcoder has asked for the wisdom of the Perl Monks concerning the following question:

Hello dear fellow nuns and monks!

While researching for a encoding problem, I wanted to retrieve the value of the current windows ANSI code page.
This can be done e.g. with Powershell like this:

Get-WinSystemLocale | Select-Object -ExpandProperty TextInfo | Select-Object -Property ANSICodePage
which gives the following output:

ANSICodePage ------------ 1252

Instead of calling PowerShell and parsing its output, I tried to use Perl's own facilities.

perl -MWin32 -we "print Win32::GetACP()"
which however gave the following output:

65001
indicating an UTF8 ANSI code page instead of Western-Europe one (cp1252) from above.

I am using Strawberry Perl 5.38.0 64-bit with its own W32 module running on Windows 11.

Is this behavior understood and known? Did I miss something or could it be a bug?
Thanks very much for your attention!

Replies are listed 'Best First'.
Re: confusing result from Win32::GetACP()
by ikegami (Patriarch) on Aug 20, 2025 at 14:12 UTC

    The Active Code Page is the encoding used by the "A" functions of the Windows API (as opposed to the "W" functions which use UTF-16le).

    The ACP was system-wide until very recently, and it's based on Windows's language. A US English Windows uses 1252.

    An application can now choose to use UTF-8 (65001) instead.

    Did you perhaps change your perl's code page to UTF-8 using this procedure?

    could it be a bug?

    No.

      Thanks!
      I did activate that checkbox Beta: Use Unicode UTF-8 for worldwide language support while experimenting last week, but since then I have switched back and rebooted several times. Now it is definitively deactivated. Could this be a caching effect?

      Also I wonder, how would you write the test for Win32::getACP() to actually compare the return value against the value reported by windows. Currently it is like this and rather coarse:

      use strict; use Test; use Win32; #plan tests => 8; my $ansicp = Win32::GetACP(); ok($ansicp > 0 && $ansicp <= 65001);

        GetACP returns the value reported by Windows. Windows reports the encoding the application must use, which is 65001 for your perl. Again, this (now) varies by process (just like chcp).

        To test if Win32::GetACP and thus Windows's GetACP return the correct value, you'd have to re-implement Windows's GetACP. That's just not feasible. You'd actually be testing your re-implementation, not Win32::GetACP.


        The following is the implementation of the Perl sub / XS function:

        XS(w32_GetACP) { dXSARGS; if (items) Perl_croak(aTHX_ "usage: Win32::GetACP()"); EXTEND(SP,1); XSRETURN_IV(GetACP()); }

        As you can see, it simply calls GetACP.


        And please stop calling it the ANSI Code Page. These calls (including the Power Shell one) all return the *Active* Code Page, which is going to be *one of* the ANSI Code Pages (as opposed to one of OEM Code Pages), and the ANSI Code Pages *aren't ANSI*.

        For example, 1250 and 1252 are "ANSI" Code Pages, but the process only has one Active Code Page which may or may not be 1250 or 1252.

        For example, 1252 was based on the what became the ANSI standard for iso-8851-1, but 1252 is different from the ANSI standard / iso-8859-1.

Re: confusing result from Win32::GetACP()
by Corion (Patriarch) on Aug 20, 2025 at 14:03 UTC

    On two random Windows 11 machines in cmd.exe, with Perl 5.26 or Perl 5.40.0, I get:

    > perl -MWin32 -E "say Win32::GetACP()" 1252 > chcp Aktive Codepage: 850

    I guess this is what you expect?

    Maybe this has something to do with the environment you're launching cmd.exe in? In my case this was Windows Terminal, but I'm unsure whether that matters.

Re: confusing result from Win32::GetACP()
by hexcoder (Curate) on Aug 20, 2025 at 13:46 UTC
    I am sure Win32::getACP() has worked some time before.

    I also wrote a small C++ program which calls the getACP() function. The result was 1252 as expected.

    I also had a look in the module tests (codepage.t), but they only check, if the returned value is in the range 0-65001.

    It might be that something changed with the API in newer windows versions, and the module needs to be adapted, but that is pure speculation.

Re: confusing result from Win32::GetACP()
by Anonymous Monk on Aug 27, 2025 at 04:28 UTC

    I can think of only two possible reasons why GetACP() is returning 65001:

    The first one was already mentioned, the UTF-8 region setting.

    The second one is that you modified your perl.exe manifest, specifically the activeCodePage property: https://learn.microsoft.com/en-us/windows/apps/design/globalizing/use-utf8-code-page

    (Note that this is *not* something that can happen by accident)

        Sorry, I missed it somehow!