2

エミュレーションで文字列送信で全角が送信できない

文字列送信ノードも安定しない

LCtrlとRCtrlの区別が出来ない

このような問題に対応する方法がテーマです。

まずは文字列送信について

Param(
  [Parameter(Mandatory=$true)]
  [int]$hWnd,
  [Parameter(Mandatory=$true)]
  [string]$sendString
)

$source = @'
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;
public class SendInputAPI
{
  [DllImport("user32.dll")]
  public static extern bool SetForegroundWindow(IntPtr hWnd);

  [StructLayout(LayoutKind.Sequential)]
  private struct Input
  {
      public int Type;
      public InputUnion ui;
  }
  [StructLayout(LayoutKind.Explicit)]
  private struct InputUnion
  {
      [FieldOffset(0)]
      public MouseInput Mouse;
      [FieldOffset(0)]
      public KeyboardInput Keyboard;
      [FieldOffset(0)]
      public HardwareInput Hardware;
  }
  [StructLayout(LayoutKind.Sequential)]
  private struct MouseInput
  {
      public int x;
      public int y;
      public int Data;
      public int Flags;
      public int Time;
      public IntPtr ExtraInfo;
  }
  [StructLayout(LayoutKind.Sequential)]
  private struct KeyboardInput
  {
      public ushort VirtualKey;
      public ushort ScanCode;
      public uint Flags;
      public uint Time;
      public IntPtr ExtraInfo;
  }
  [StructLayout(LayoutKind.Sequential)]
  private struct HardwareInput
  {
      public int uMsg;
      public short wParamL;
      public short wParamH;
  }

  private const int INPUT_KEYBOARD = 0x1;
  private const int KEYEVENTF_KEYDOWN = 0x0;
  private const int KEYEVENTF_KEYUP   = 0x2;
  private const int KEYEVENTF_EXTENDEDKEY = 0x1;
  private const int KEYEVENTF_UNICODE = 0x4;

  [DllImport("user32.dll")]
  private static extern uint SendInput(int nInputs, Input[] pInputs, int cbsize);

  public static void SendString(int hWnd, string s){
    SetForegroundWindow(new IntPtr(hWnd));
    Input[] inputs = new Input[2 * (s.Length)];
    for(int k=0; k < s.Length; k++)
    {
      ushort tk = s[k];

      inputs[2 * k] = new Input()
      {
          Type = INPUT_KEYBOARD,
          ui = new InputUnion() {
              Keyboard = new KeyboardInput()
              {
                  VirtualKey = 0,
                  ScanCode = tk,
                  Flags = KEYEVENTF_UNICODE | KEYEVENTF_KEYDOWN,
                  Time = 0,
                  ExtraInfo = IntPtr.Zero
              }
          }
      };
      inputs[2 * k + 1] = new Input()
      {
          Type = INPUT_KEYBOARD,
          ui = new InputUnion()
          {
              Keyboard = new KeyboardInput()
              {
                  VirtualKey = 0,
                  ScanCode = tk,
                  Flags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP,
                  Time = 0,
                  ExtraInfo = IntPtr.Zero
              }
          }
      };
    }
    SendInput(inputs.Length, inputs, Marshal.SizeOf(inputs[0]));
  }
}
'@
Add-Type -TypeDefinition $source -ReferencedAssemblies System.Windows.Forms,System.Drawing
[SendInputAPI]::SendString($hWnd,$sendString)
 
長いですがpowershellスクリプトです
ポイントはKEYEVENTF_UNICODEでこれを付与することによってunicode送信できます
WinActorから使用する場合SetForegroundWindowしないと安定しなかったので操作対象のhWndが必要です
WinActorから使用する場合は
ウインドウハンドル取得で hWnd を取得
文字列連結で -ExecutionPolicy RemoteSigned -File スクリプトのパス hWnd 送信文字列
を組み立て(ExecutionPolicyはお好みで)
コマンド実行でpowershell実行オプションに上記で連結した文字列

LCtrl送信

Param(
  [Parameter(Mandatory=$true)]
  [int]$hWnd
)

$source = @'
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;
public class SendInputAPI
{
  [DllImport("user32.dll")]
  public static extern bool SetForegroundWindow(IntPtr hWnd);

  [StructLayout(LayoutKind.Sequential)]
  private struct Input
  {
      public int Type;
      public InputUnion ui;
  }
  [StructLayout(LayoutKind.Explicit)]
  private struct InputUnion
  {
      [FieldOffset(0)]
      public MouseInput Mouse;
      [FieldOffset(0)]
      public KeyboardInput Keyboard;
      [FieldOffset(0)]
      public HardwareInput Hardware;
  }
  [StructLayout(LayoutKind.Sequential)]
  private struct MouseInput
  {
      public int x;
      public int y;
      public int Data;
      public int Flags;
      public int Time;
      public IntPtr ExtraInfo;
  }
  [StructLayout(LayoutKind.Sequential)]
  private struct KeyboardInput
  {
      public ushort VirtualKey;
      public ushort ScanCode;
      public uint Flags;
      public uint Time;
      public IntPtr ExtraInfo;
  }
  [StructLayout(LayoutKind.Sequential)]
  private struct HardwareInput
  {
      public int uMsg;
      public short wParamL;
      public short wParamH;
  }

  private const int INPUT_KEYBOARD = 0x1;
  private const int KEYEVENTF_KEYDOWN = 0x0;
  private const int KEYEVENTF_KEYUP   = 0x2;
  private const int KEYEVENTF_EXTENDEDKEY = 0x1;

  [DllImport("user32.dll")]
  private static extern uint SendInput(int nInputs, Input[] pInputs, int cbsize);

  public static void SendLCtrlKey(int hWnd){
    SetForegroundWindow(new IntPtr(hWnd));
    Input[] inputs = new Input[2];
    inputs[0] = new Input()
    {
        Type = INPUT_KEYBOARD,
        ui = new InputUnion() {
            Keyboard = new KeyboardInput()
            {
                VirtualKey = (ushort)Keys.LControlKey,
                Flags = KEYEVENTF_KEYDOWN,
                Time = 0,
                ExtraInfo = IntPtr.Zero
            }
        }
    };
    inputs[1] = new Input()
    {
        Type = INPUT_KEYBOARD,
        ui = new InputUnion()
        {
            Keyboard = new KeyboardInput()
            {
                VirtualKey = (ushort)Keys.LControlKey,
                Flags = KEYEVENTF_KEYUP,
                Time = 0,
                ExtraInfo = IntPtr.Zero
            }
        }
    };
    SendInput(inputs.Length, inputs, Marshal.SizeOf(inputs[0]));
  }
}
'@
Add-Type -TypeDefinition $source -ReferencedAssemblies System.Windows.Forms,System.Drawing
[SendInputAPI]::SendLCtrlKey($hWnd)

RCtrl送信

Param(
  [Parameter(Mandatory=$true)]
  [int]$hWnd
)

$source = @'
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;
public class SendInputAPI
{
  [DllImport("user32.dll")]
  public static extern bool SetForegroundWindow(IntPtr hWnd);

  [StructLayout(LayoutKind.Sequential)]
  private struct Input
  {
      public int Type;
      public InputUnion ui;
  }
  [StructLayout(LayoutKind.Explicit)]
  private struct InputUnion
  {
      [FieldOffset(0)]
      public MouseInput Mouse;
      [FieldOffset(0)]
      public KeyboardInput Keyboard;
      [FieldOffset(0)]
      public HardwareInput Hardware;
  }
  [StructLayout(LayoutKind.Sequential)]
  private struct MouseInput
  {
      public int x;
      public int y;
      public int Data;
      public int Flags;
      public int Time;
      public IntPtr ExtraInfo;
  }
  [StructLayout(LayoutKind.Sequential)]
  private struct KeyboardInput
  {
      public ushort VirtualKey;
      public ushort ScanCode;
      public uint Flags;
      public uint Time;
      public IntPtr ExtraInfo;
  }
  [StructLayout(LayoutKind.Sequential)]
  private struct HardwareInput
  {
      public int uMsg;
      public short wParamL;
      public short wParamH;
  }

  private const int INPUT_KEYBOARD = 0x1;
  private const int KEYEVENTF_KEYDOWN = 0x0;
  private const int KEYEVENTF_KEYUP   = 0x2;
  private const int KEYEVENTF_EXTENDEDKEY = 0x1;

  [DllImport("user32.dll")]
  private extern static uint SendInput(int nInputs, Input[] pInputs, int cbsize);

  [DllImport("user32.dll", EntryPoint = "MapVirtualKeyA")]
  private extern static uint MapVirtualKey(uint wCode, uint wMapType);

  private const int MAPVK_VK_TO_VSC_EX = 4;

  public static void SendRCtrlKey(int hWnd){
    SetForegroundWindow(new IntPtr(hWnd));
    Input[] inputs = new Input[2];
    uint vsc = MapVirtualKey((uint)Keys.RControlKey, MAPVK_VK_TO_VSC_EX);
    inputs[0] = new Input()
    {
        Type = INPUT_KEYBOARD,
        ui = new InputUnion() {
            Keyboard = new KeyboardInput()
            {
                VirtualKey = (ushort)Keys.RControlKey,
                ScanCode = (ushort)vsc,
                Flags = KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYDOWN,
                Time = 0,
                ExtraInfo = IntPtr.Zero
            }
        }
    };
    inputs[1] = new Input()
    {
        Type = INPUT_KEYBOARD,
        ui = new InputUnion()
        {
            Keyboard = new KeyboardInput()
            {
                VirtualKey = (ushort)Keys.RControlKey,
                ScanCode = (ushort)vsc,
                Flags =  KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP,
                Time = 0,
                ExtraInfo = IntPtr.Zero
            }
        }
    };
    SendInput(inputs.Length, inputs, Marshal.SizeOf(inputs[0]));
  }
}
'@
Add-Type -TypeDefinition $source -ReferencedAssemblies System.Windows.Forms,System.Drawing
[SendInputAPI]::SendRCtrlKey($hWnd)

LCtrl と RCtrl の違いは KEYEVENTF_EXTENNDKEY 及び ScanCode の部分です
長くなりましたが、まあ興味があるひと向けです

この質問は解決済みのためクローズされています。
John 質問の投稿
回答とコメントは、会員登録(無料)で閲覧できるようになります。