how to programmatically install a keyboard layout?

Alan Sinclair 11 Reputation points
2020-10-21T19:49:20.803+00:00

I need to package several different keyboard layouts aka "input locale identifiers" together, so I need to write some code to install a layout in Windows, but haven't found any documentation. Can anyone show me example code or point me to documentation? Backgound: Microsoft's MSKLC tool enables creation of Keyboard Layouts. Each single layout is 'contained' in a DLL; for a layout MSKLC creates four DLLs for various flavors of Windows (naming them i386, amd64, ia64, wow64). MSKLC also creates the three appropriate MSI installers for that single layout, but those installers cannot be used in this situation. Just deploying the DLLs doesn't enable them, there is obviously some action needed to add the new locale identifiers to what Windows knows about its keyboards.

(I'm unsure this is the right place for this question, and what tags should be used .. please correct me if necessary)

Windows API - Win32
Windows API - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Previously known as Win32 API.
2,426 questions
{count} vote

17 answers

Sort by: Most helpful
  1. Robert Sullivan 11 Reputation points
    2020-12-09T14:51:29.73+00:00

    Alan, this thread is getting somewhat off topic
    I have always believed it is best to attempt to keep on topic.

    In todays world, this is becoming increasingly difficult as it is near impossible to get any reasonable answers from posting on sites like this. I believe that the developers community is either to busy to answer such questions now a days, or has deteriorated into a group of 'Knowledge Campers'. I believe the former is true.

    What I find surprising is our inability to get the attention from Microsoft to actually answer the original question here, and to address what I consider to be a more than reasonable request to expose the Custom Action Dll source code within the MSKLC.

    I am pretty sure I am going to end up wasting a MSDN subscription support ticket to finally get this answer.

    In the mean time I have a wad of C++ code I have written to interrogate, change KLID's, change HKL's, analyze keyboard layout Dll's (such as KBDUS.dll,KBDGR.dll, KBDUK.dll,..) and so on. It is a whole lot of source code. Since we are sharing some goals (specifically, how to install a custom keyboard layout) I would be more than happy to share this source code with you.

    I am not all that familiar with Github. Are you?

    I am pretty sure we could set up a 'private' repository. I could then upload the code I mentioned above. This would cut down on time spent with us both doing the same things.

    We could then work through the real issue (how to install a custom keyboard properly), and post a synopsis of our findings back here to be polite to other members.

    There used to be a way to contact MSDN members (send a private message) directly. This was at least a decade ago. I am unable to find a way to do so now. If we could find a way to contact each other directly we could by pass the whole github thing.

    Any thoughts?

    0 comments No comments

  2. Alan Sinclair 11 Reputation points
    2020-12-09T17:25:08.003+00:00

    Robert, yes this test code is a simple console exe.
    One thing I omitted from my description above is that after running the exe (where the second showKbdName shows the active layout is the one we're activating, i.e. our modified UK English one) neither the exe's 'cin->cout' nor any other app gets the newly-activated UK layout; further, showKbdName in the next run of the exe still shows US English.

    Our goal is that we need an install package (MSI preferably) which can update a keyboard layout. The installer which MSKLC creates doesn't support updates.

    The problem is that when a layout is active, the DLL can't be updated by an MSI (even with a reboot included in the install sequence) so my hope is that by activating a different layout ours can update; that works when the active layout is switched using the Language Bar.

    0 comments No comments

  3. Robert Sullivan 11 Reputation points
    2020-12-09T19:23:11.26+00:00

    Alan.

    First:
    Make sure you have not set a debug break point in your code when you attempt
    to load the keyboard. It will not work because your application will not have focus.

    NOTE:
    Keyboard layouts may be pre-loaded.
    See: HKEY_CURRENT_USER\Keyboard Layout
    If you are attempting to physically replace something like KBDUK.dll, and it is pre-loaded
    I am not sure if you will be able to do so. If in the end you find this is the case perhaps
    you should simply create a new keyboardlayout Dll as I am.

    I am NOT including KLF_ACTIVATE on my LoadKeyboardLayout() calls.

    I am NOT including KLF_REORDER on my ActivateKeyboardLayout() call.

    I AM including KLF_SETFORPROCESS on my ActivateKeyboardLayout() call.

    I create a list of keyboard layouts from GetKeyboardLayoutList().
    This gives me all of the Keyboard layouts that are loaded. (See Pre-Load above)
    I keep this list in Big->KeyBoardLayoutList:
    class KeyBoardLayout {
    public:
    HKL KeyboardHkl;
    TCHAR KLID[9];
    TCHAR Language[50];
    TCHAR LayoutText[100];
    };

    The only keyboard I have currently on my system are ENG US (0x0409409) and ENG DE (0x0407409)
    I have my test application running while I am typing into this reply.
    This shows that the keyboard layout is in fact being changed system wide.
    0x0407409 is a QWERTZ keyboard layout.
    0x0409409 is a QWERTY keyboard layout.

    Load ENG DE (This is a QWERTZ keyboard).
    -- NewLayout=LoadKeyboardLayout(Big->Layouts[Index].KLID,0); (My Index is for ENG DE)
    Note: My Flags are 0
    -- OldLayout=ActivateKeyboardLayout(NewLayout,KLF_SETFORPROCESS)

    Type: QWERTZ

    Load ENG US (This is a QWERTY keyboard).
    -- NewLayout=LoadKeyboardLayout(Big->Layouts[Index].KLID,0); (My Index is for ENG US)
    Note: My Flags are 0
    -- OldLayout=ActivateKeyboardLayout(NewLayout,KLF_SETFORPROCESS)

    Type: QWERTY

    My test application is a Win32 application (I.e. it has a MessageLoop).

    If you expect to install your keyboard layout via an .msi (I am also fluent with WIX as you are), and you are planning on replacing an existing keyboard layout .Dll, this may be problematic.

    I have created a free GitHub organization. I created a private repository. I am still trying to figure out how to go about 'inviting' members. I think this approach would behoove us!

    0 comments No comments

  4. Alan Sinclair 11 Reputation points
    2020-12-10T16:20:12.82+00:00

    very many thanks Robert
    my direct email is anadem@Stuff .com
    sorry for the delay .. I only get to look at this sporadically, and I won't be able to follow up your ideas until the weekend
    Alan


  5. Robert Sullivan 11 Reputation points
    2021-02-18T22:01:40.11+00:00

    Hey Remy.
    What exactly do you need to do?
    -- Install a keyboard layout.
    -- Will the keyboard layout only be used by a single application?.
    -- What is the purpose of your layout?