5

When using SendKeys.Send() of System.Windows.Forms to send a caret ^

SendKeys.Send ("{^}")

it will send an ampersand & instead.

Why?

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Tobias Knauss
  • 3,361
  • 1
  • 21
  • 45
  • Maybe you have `Fat Fingers` and you are hitting the `Key next to the ^` – MethodMan Dec 04 '17 at 14:10
  • @MethodMan: definitely NOT! – Tobias Knauss Dec 04 '17 at 14:12
  • Being that I am in America @TobiasKnauss, I run the code and it works so perhaps it's something with the region you're in or your KeyBoard – MethodMan Dec 04 '17 at 14:14
  • @MethodMan: see my own answer below. ;-) – Tobias Knauss Dec 04 '17 at 14:15
  • I really would like to know the reason for the downvotes... – Tobias Knauss Dec 04 '17 at 14:16
  • @TobiasKnauss Sometimes SO is a bit strange, i give you +1 to even it out. – ViRuSTriNiTy Dec 04 '17 at 14:17
  • Probably because you answered your own question is my best guess – MethodMan Dec 04 '17 at 14:17
  • @MethodMan: AFAIK, SO encourages to share your knowledge, and thus to also answer your own questions. at ViRuSTriNiTy: thanks! – Tobias Knauss Dec 04 '17 at 14:18
  • 2
    @TobiasKnauss Perhaps the statement mentioned at https://msdn.microsoft.com/library/system.windows.forms.sendkeys.send.aspx is relevant? "If your application is intended for international use with a variety of keyboards, the use of Send could yield unpredictable results and should be avoided." – ViRuSTriNiTy Dec 04 '17 at 14:21
  • well @TobiasKnauss I didn't downvote it so couldn't tell you why someone else did – MethodMan Dec 04 '17 at 14:21
  • @ViRuSTriNiTy: thanks, I didn't see that. But which methods exist for international use? The only thing I can think of is inserting text into the clipboard and sending "CTRL+V" to paste it at the target. – Tobias Knauss Dec 04 '17 at 14:23
  • It has to send *virtual* keys, not characters, that is not so simple to do since keyboard layout is a per-process property. The language bar tends to be popular for German programmers that post to an English web site. Inevitably, the active language for the program is used to figure out what keys to send, but it might not be the same as the active language of the process in the foreground. SendKeys should have been left out of the framework, but they could not omit it. – Hans Passant Dec 04 '17 at 15:18
  • @HansPassant: it works well for all characters except the caret, also with German KB layout. So I doubt that this is about _virtual_ keys. Any suggestion for alternatives? – Tobias Knauss Dec 04 '17 at 15:21
  • Of all the possible ways to automate another program, emulating keystrokes is by far the worst choice. There is a decent api for it, wrapped by the System.Windows.Automation namespace in .NET. – Hans Passant Dec 04 '17 at 15:25
  • @HansPassant: I cannot find anything suitable in that namespace for automated access to a foreign application that accepts nothing else but keyboard and mouse inputs. – Tobias Knauss Dec 04 '17 at 15:32

2 Answers2

1

I solved this for a german keyboard layout.

The Problem is that some keys are hardcoded like this:

static SendKeys()
{
    keywords = new KeywordVk[49]
    {
        ...
        new KeywordVk("+", 107),
        new KeywordVk("%", 65589),
        new KeywordVk("^", 65590) // this is a problem !
    }
}

So the hack is to override the value of new KeywordVk("^", ...)

// fix caret, ^, circumflex on german keyboards
public static void FixSendKeys_Caret()
{
    // SendKeys.keywords
    var keywordsField = typeof(SendKeys)
        .GetField("keywords", BindingFlags.NonPublic | BindingFlags.Static)
        .GetValue(null) as IList;

    // KeywordVk { keyword= "^", vk = xx }, should be at index 48
    var keywordVk_Obj = keywordsField[48];

    var keywordField = keywordVk_Obj.GetType().GetField("keyword", BindingFlags.NonPublic | BindingFlags.Instance);
    // KeywordVk.vk
    var vkField = keywordVk_Obj.GetType().GetField("vk", BindingFlags.NonPublic | BindingFlags.Instance); 

    if (keywordField.GetValue(keywordVk_Obj).ToString() != "^")
        throw new Exception("wrong KeywordVk");

    // SendKeys.keywords[48].vk = (int)Keys.Oem5;
    // For german keyboards "^" = Keys.Oem5
    vkField.SetValue(keywordVk_Obj, (int)Keys.Oem5);
    // check if its correct
    var getVal = vkField.GetValue(keywordVk_Obj); 
}

Call this once before your SendKeys code

Charles
  • 2,721
  • 1
  • 9
  • 15
  • Beautiful, thank you. Another thing to add - when using `SendKeys` to send `^`, always send a space character directly after: `SendKeys.Send ("{^} ");`. This way e.g. `^o` does not become `ô` inadvertently. – Tomalak Jul 06 '21 at 08:35
-1

According to

https://www.experts-exchange.com/questions/28994144/SendKeys-caret-sends-ampersand.html

it's a localization issue.

Changing the keyboard layout from german layout to english layout should help.

ViRuSTriNiTy
  • 5,017
  • 2
  • 32
  • 58
  • 1
    my keyboard layout already is German. Also, the link says that the German keyboard layout is the problem and you have to change it back to English. – Tobias Knauss Dec 04 '17 at 14:28
  • @TobiasKnauss ok, then change to english layout. – ViRuSTriNiTy Dec 04 '17 at 14:29
  • Incredible that the StackOverflow arch-enemy (Experts Exchange) gets cited as reference for an answer here. – Alejandro Dec 04 '17 at 16:13
  • @Alejandro Arch enemy? What? – ViRuSTriNiTy Dec 05 '17 at 06:39
  • 1
    @ViRuSTriNiTy [ExpertsExchange is considered the "arch enemry" of StackOverflow](https://blog.codinghorror.com/whos-your-arch-enemy/) and is in part what inspired Joel Spolsky and Jeff Atwood to create StackOverflow as we know now. Part joke, part real, long history, but certainly unrelated to the question :D – Alejandro Dec 05 '17 at 19:58