Přidat otázku mezi oblíbenéZasílat nové odpovědi e-mailemVyřešeno Win7 32b, softwarové ovládání DOSovské aplikace...

Zdar borci!

Původně jsem chtěl napsat nadpis jako:

Život není lehký

nebo

Hardcore porno

Ale tak bych mohl zahrát na nervy administrátorům. A teď k věci. Jestli tohle vyřeší nějaký borec, tak bude lepší, než já.

Jde o tohle. Pokud chcete posílat klávesové výstupy("z klávesnice") nějaké aplikaci ve Windows, je nejjednodušší řešení
použit prográmek .NET, kde zavoláte něco na způsob:

...
System.Windows.Forms.Sendkeys.Sendwait("{ENTER}");
...

Stačí si defakto ošéfovat, aby daná aplikace měla focus a jste na koni...

Jenže....

Život není lehký

nebo

Hardcore porno

Tyto .NETovské legrace kompletně ztrácí úplný význam, pokud jde o DOS aplikaci.
V lepším případě na tyto "povely" nereagují, nebo se aplikace ukončí.....

Podle mého testování to vypadá, že cesta vede skrz nativní "user32.dll" ......
Je však potřeba mimo jiné v programu získat pointer na DOSovský proces.

Ukázka z fce Main v přiloženém kódu:

int procesId = YourEnumerateClass.Enum16BitProcesses();
                                                    
            Process processes = Process.GetProcessById(procesId);

           
            if (processes == null)
                throw new Exception("Could not find the process; is running?");

            
            IntPtr WindowHandle = processes.MainWindowHandle; 
            PressKey('a', true); // druhý parametr určuje stisknuto/odstisknuto
            System.Threading.Thread.Sleep(100);
            PressKey('a', false);

Testuju to na starém M602 a bohužel program žádnou chybu nehlásí, ale nefunguje to (nedělá to opticky nic).

V příloze přikládám samostatný consolový, kompilovatelný projekt.
Předem díky za cenné rady, soudruzi.....

Jsou zobrazeny jen nové odpovědi. Zobrazit všechny
Předmět Autor Datum
klavesa sa neposiela procesu ale oknu. Okno nemusi mat focus a aj tak mu mozes poslat WM_KEYDOWN mes…
MM.. 11.08.2014 20:24
MM..
Jjj. S tím jsem už taky bojoval. Ale dělám to v nenativním C#.... :-) A tam mi to nejak nefachcilo.…
Flash_Gordon 11.08.2014 20:28
Flash_Gordon
Musis hladat spravny titulok okna konzoly. Napr. tusim Spy++ ti vypise jake su vo Win okna a s jakym…
MM.. 11.08.2014 20:35
MM..
No. Já sem na titulky použil: http://www.codeproject.com/Articles/18366/Sending- Keystrokes-to-anoth…
Flash_Gordon 11.08.2014 20:42
Flash_Gordon
A hlavne prestan snivat o tom ze budes komunikovat s 16bit aplikaciou. Nebudes. Nikdy. Komunikujes s… nový
MM.. 11.08.2014 20:46
MM..
A nemas hladat podokno "Edit", to plati pre notepad (ten ma editbox childokno) a ne pre konzolu. T.j… nový
MM.. 11.08.2014 20:59
MM..
To je tak staré ako Windows samotné... Už dávno som to neriešil, ale narýchlo som niečo našiel: mc-c… nový
pme 11.08.2014 20:46
pme
Pokud je to standardní konzole, bude fungovat stdin a stdout. Ale musis zapomenout na frontu zprav,… nový
Jan Fiala 11.08.2014 21:04
Jan Fiala
Dobře soudruzi..... nějak jsem si to přebral. Bohužel mám teď pouze 64b Win a tam mi DOSovské app ne… nový
Flash_Gordon 11.08.2014 22:28
Flash_Gordon
ScanCode je kod klavesy, ale ne ASCII hodnota, ale hodnota prirazena kazde konkretni kavese na klave… nový
Jan Fiala 12.08.2014 06:56
Jan Fiala
Uffff. Podporujeme dinosaury (TM). Testoval jsem jak tu slavnou knihovnu pro simulaci kláves, tak… nový
Flash_Gordon 12.08.2014 21:26
Flash_Gordon
Ale obecně to funguje všelijak. V závislosti na Windows a DOSovské aplikaci. keby si posielal wm_ke… poslední
MM.. 13.08.2014 10:09
MM..

Jjj. S tím jsem už taky bojoval.
Ale dělám to v nenativním C#.... :-)

A tam mi to nejak nefachcilo.

Bylo to neco jako:

using System;
using System.Runtime.InteropServices;
using System.Diagnostics;

    [DllImport("user32.dll", EntryPoint = "FindWindowEx")]
    public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter,          string lpszClass, string lpszWindow);
    [DllImport("User32.dll")]
    public static extern int SendMessage(IntPtr hWnd, int uMsg, int wParam, string lParam);

     static void Send(string message)
     {
     Process[] notepads = Process.GetProcessesByName("notepad");  // Ale tady byl titulek DOSove aplikace, hlasilo nenalezena
     if (notepads.Length == 0)
     return;
     if (notepads[0] != null)
     {
     IntPtr child = FindWindowEx(notepads[0].MainWindowHandle, new   IntPtr(0), "Edit", null);
     SendMessage(child, 0x000C, 0, message);
     }
     }

No. Já sem na titulky použil:
http://www.codeproject.com/Articles/18366/Sending- Keystrokes-to-another-Application-in-C
(toto vůbec nefunguje na DOS aplikace)

Jenže jinde jsem zase četl (teď to nemůžu najít), že..... 16bitové aplikace se tam údajně ani nevypisují.
Respektive vypisuje se tam název konzole (který je dle cesty k aplikaci), ale jestli je to totéž co ta aplikace.....

A taky jsem našel tuto srandu:
http://inputsimulator.codeplex.com/SourceControl/l atest#README.md
hodlám ji taky vyzkoušet, ale je tam ticho po pěšině o 16b aplikacích...

A nemas hladat podokno "Edit", to plati pre notepad (ten ma editbox childokno) a ne pre konzolu. T.j. riadok

IntPtr child = FindWindowEx(notepads[0].MainWindowHandle, new   IntPtr(0), "Edit", null);

je pre konzolu nezmysel. Mas si najst len hlavne okno konzoly, a poslat mu WM_CHAR message so spravnymi parametrami (viz google a WM_CHAR)

Dobře soudruzi..... nějak jsem si to přebral.
Bohužel mám teď pouze 64b Win a tam mi DOSovské app nejedou.

Podle zdejších inspirací by na to měla stačit keybd_event z user32.dll .
Bude stačit tohle?

[DllImport("user32.dll")]
        private static extern void keybd_event(byte bVirtualKey, byte bScanCode, int dwFlags, int dwExtraInfo);
      
        private const byte VK_LSHIFT = 0xA0;
        private const int KEYEVENTF_KEYUP = 0x0002;  //Key up flag
        private const int KEYEVENTF_EXTENDEDKEY = 0x0001; //Key down flag

        private const byte VK_LEFT = 0x25; // Leva sipka

....
....
// volani kláves:
 keybd_event(VK_LEFT, 0x45, KEYEVENTF_EXTENDEDKEY, 0);


Mimochodem, co znamená parametr byte bScanCode ve fci keybd_event?
Můžu někde najít tuto tabulku v bytech? (Myslím ty bScanCode)

No zítra večer dám úplný report.
A s tím simulátorem kláves to vypadá nadějně:
http://inputsimulator.codeplex.com/discussions/228 707

Jediné co nefunguje je posílání řetězců (jak to vypadá...) ale ty já ani nepotřebuju
a je možné se bez nich obejít.

Uffff.

Podporujeme dinosaury (TM).

Testoval jsem jak tu slavnou knihovnu pro simulaci kláves, tak keybd_event.
Nefungovalo nic.
Zkoušel jsem všechny návrhy, ale zafungovalo mi až jediné řešení.
Tak jsem to úplně haluzácky pořešil.
Win32 API se moc nechytá, protože pokud nemá okno focus, tak snad není ani aktivní pro příjem podle některých zdrojů.
Našel jsem List of Virtual Key Codes.

Ale obecně to funguje všelijak. V závislosti na Windows a DOSovské aplikaci.
Někde například nefunguje směrová šipka dolů, jinde zase pomůže deaktivovat Num lock na klávesnici a podobně.
Prostě vzrůšo.

    [DllImport("user32.dll")]
    public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, uint dwExtraInfo);

            
    [DllImport("user32.dll")] 
    static extern int MapVirtualKey(uint uCode, uint uMapType);

public static void Main()
        {
         const byte KEYEVENTF_KEYUP = 2;
         
          int ScanKey2 = MapVirtualKey(	0x09, 0);   // 	0x09 =  tabulátor 
         Console.WriteLine("int kode:{0} "+ ScanKey2);
        System.Threading.Thread.Sleep(3000);
        keybd_event(0x28, (byte)ScanKey2, 0, 0);
        keybd_event(0x28, (byte)ScanKey2, KEYEVENTF_KEYUP, 0); 

        }

V podstatě stačí nastavit virtuální ScanKey2 a je vymalováno.
Bez zajímavosti také není, že aplikace se chová úplně jinak na 32b Windows a úplně jinak na 64b.
Například tentýž kód způsobuje v jednom případě odeslání Enteru a ve druhém případě key_down.

Navíc se to, jak jsem již psal chová odlišně v různých DOSovských aplikacích.

MISSION ACCOMPLISHED

Ale obecně to funguje všelijak. V závislosti na Windows a DOSovské aplikaci.

keby si posielal wm_keydown a wm_keyup message jak som pisal tak by IMHO fungovalo vsetko vzdy. Nechapem preco furt kazdy chce lepit nejake cudzie kniznice

P.S. a pracuj rovno so scan kodmi, a ne s ascii a lepit cosi s konverznymi fciami ktore pisal nejaky pako v MS. Klavesnica neposiela ziadne ascii. Viz MSDN WM_KEYDOWN

Zpět do poradny Odpovědět na původní otázku Nahoru