使Autohotkey忽略字符串中的任何特殊字符

时间:2016-06-08 07:10:55

标签: string autohotkey

我们正在使用一个解析器程序(我无权访问)解析一堆计算机生成的邮件,但需要一些帮助来决定它特别需要做什么。因此,员工kann使用主题行来获取其他命令。由于我们每天向该程序提供的邮件超过500封,而且所有命令看起来都类似于Ba,Vi;#TD*; x0003,因此无法手动编写它们。所以我写了一个小的C#脚本,它创建了一个Autohotkey脚本,可以完成90%的工作。理论上。只要我不使用任何特殊字符,例如, : & % etc,它就可以工作。

我试过了:

clipboard := Ba{,}Vi{;}{#}TD{*}{;} x0003
clipboard := "Ba,Vi;#TD*; x0003"
clipboard := Ba',Vi';'#TD'*'; x0003
clipboard := {raw} Ba,Vi;#TD*; x0003
(plus some others that I probably forgot here)


这是带有注释的整个AHK脚本。您在Outlook中选择了一封电子邮件时启动它:

;Win+z -> start script
#z:: 

;Currently only one iteration
loop,1 
{

    ;CTRL+F to forward selected mail, 
    ;which then automatically selects the "To:" line
    Send, {CTRLDOWN}f{CTRUP} 
    Sleep, 500
    Send, someemail@adress
    Sleep, 500

    ;Initialize GUI
    Gui, +AlwaysOnTop
    Gui, Font, S5, Verdana, bold
    Gui, Add, Text,, SCANNING-BOOSTER:
    Gui, Color,  F4A460

    ;Example for the C# generated buttons below (they all do the same thing):
    ;Clicking the Button "Google" will run the following script
    ;Start: 
    ;clipboard := www.Google.com
    ;return
    ;This is the part where AHK fails because instead 
    ;of www.Google.com I have codes like "Ba,Vi;#TD*; x0003" which crash AHK

    Gui,add,Button,gLabel,Google
    Gui,add,Button, ......
    Gui,add,Button, ......
    Gui,add,Button, ......
    Gui,add,Button, ......
    Gui,add,Button, ......
    ..... (around 60 more auto-generated buttons)
    Gui,show
    Return
    Label:
    ;run the script that has the same name as the Button
    ;in this case it would be Google.ahk
    Run, % A_GuiControl ".ahk"

    GuiClose: 
            Gui, Hide 

    Sleep, 1000


    ;after the user has pressed a button and the according code
    ;has been copied to the clipboard, the GUI closes, the
    ;mail window becomes active again and we can continue to paste
    ;the code into the subject line

    ;Go to subject line
    Send, {ALTDOWN}r{ALTUP} 
    Sleep, 500

    ;CTRL+a
    Send, {CTRLDOWN}a{CTRUP}
    Sleep, 500

    ;Write text from your clipboard to the subject line
    Send, %clipboard%
    Sleep, 500

    return
}

1 个答案:

答案 0 :(得分:0)

显然目前无法在Autohotkey中将(或多或少)随机字符串复制到剪贴板,然后将其粘贴到其他地方而不会收到太多值得追求的错误。除了在C#中自己编程之外别无选择。我是这样做的:

首先,启动一个新的控制台应用程序,然后将其更改为Windows应用程序
How to change a console application to a windows form application?
这是使程序对用户完全不可见的最简单方法。

接下来,我们需要一个关键的监听器。这是我使用的那个:
https://blogs.msdn.microsoft.com/toub/2006/05/03/low-level-keyboard-hook-in-c/
我建议你把它放在一个新的课堂上。无论如何,这个代码需要稍微更改,因为它会将每个按键打印到控制台。我们不希望这样,我们想从中调用一个方法。将HookCallback更改为:

private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
    if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
    {
        int vkCode = Marshal.ReadInt32(lParam);

        if (KeyPressed == vkCode)
            DoWork();
    }
    return CallNextHookEx(_HookID, nCode, wParam, lParam);
}

要使上面的代码工作,我们需要在我们的类中添加一个新的委托和一个新的int变量:

private static int KeyPressed;
public delegate void SomethingToDo();
private static SomethingToDo DoWork;

SetHook还需要一些小改动:

private static IntPtr SetHook(KeyboardProc _proc, int KeyCode, SomethingToDo GiveMeWork)
{
    DoWork = GiveMeWork;
    KeyPressed = KeyCode;
    ...(leave the rest as it is)...
}

该程序现在完全不可见,可以对按键做出反应。让我们相反,模拟键!
Ctrl key kept down after simulating a ctrl key down event and ctrl key up event
这简单得多。我做了三个方法,PressKey,ReleaseKey和TapKey。请记住,ALT和F10是特殊的系统密钥,可能无法正常工作。

[DllImport("user32.dll", SetLastError = true)]
static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);
private const int KeyPressCode = 0x0001;
private const int KeyReleaseCode = 0x0002;

    public static void PressKey(System.Windows.Forms.Keys Key)
    {
        keybd_event((byte)Key, 0, KeyPressCode | 0, 0);
        Thread.Sleep(10);
    }

    public static void ReleaseKey(System.Windows.Forms.Keys Key)
    {
        keybd_event((byte)Key, 0, KeyPressCode | KeyReleaseCode, 0);
        Thread.Sleep(10);
    }

    public static void TapKey(System.Windows.Forms.Keys Key)
    {
        PressKey(Key);
        ReleaseKey(Key);
    }

就是这样,一个可以处理字符串的基本Autohokey-Clone。如果你想更进一步,并为它做一个尝试图标:
https://translate.google.de/translate?sl=de&tl=en&js=y&prev=_t&hl=de&ie=UTF-8&u=https%3A%2F%2Fdotnet-snippets.de%2Fsnippet%2Fvorlage-fuer-tray-notifyicon-anwendung%2F541&edit-text=&act=url
显示带按钮的GUI也非常简单:

using (Form _form = new Form())
{
    _form.size = ...
    //....

   Button MyButton = new Button();
   //....
   //closing is also pretty simple, just like your everyday Windows Forms Application:
   MyButton.Click += new EventHandler((sender, e) => { Application.Exit(); });

    _form.ShowDialog();
}

将所有内容放在主方法中:

    private static NotifyIcon TrayIcon = new NotifyIcon();

    [STAThread]
    static void Main(string[] args)
    {

        bool WindowOpen = true;

        try
        {
            //Make a new method above or below Main() and replace DoSomething with it.
            //It will be executed everytime the F2 key is pressed.
            KeyListener._HookID = KeyListener.SetHook(proc, System.Windows.Forms.Keys.F2, DoSomething);


            System.Windows.Forms.ContextMenu SmallMenu = new System.Windows.Forms.ContextMenu();
            System.Windows.Forms.MenuItem MenuElement;
            int MenuIndex = 0;

            MenuElement = new System.Windows.Forms.MenuItem();
            MenuElement.Index = ++MenuIndex;
            MenuElement.Text = "Close";
            MenuElement.Click += new EventHandler((sender, e) => { WindowOpen = false; System.Windows.Forms.Application.Exit(); });
            SmallMenu.MenuItems.Add(MenuElement);

            TrayIcon.Icon = new System.Drawing.Icon("Ghost.ico");
            TrayIcon.Text = "String Compatible AHK";
            TrayIcon.Visible = true;
            TrayIcon.ContextMenu = SmallMenu;


            while (WindowOpen)
                System.Windows.Forms.Application.Run();
        }
        finally
        {
            TrayIcon.Dispose();
            KeyListener.UnhookWindowsHookEx(KeyListener._HookID);
        }
    }