Poprawne użycie wątków i metod statycznych

0

Tak jak w tytule. Jak poprawnie użyć tutaj wątku i metody statycznej aby dało się korzystać ze zmiennej litera_A?
Teraz mi pokazuje błąd, że oczekuje obiektu:

Dla niestatycznego pola, metody lub właściwości „Form1.litera_A” wymagane jest odwołanie do obiektu

Oraz czy będzie to poprawne użycie Wątku, który obsłuży FORME? Zależałoby mi aby niezależnie od funkcji, która sobie w tle działała był dostęp do okienka FORM i była możliwość aktualizować dane w oknie, w funkcji zapisu / odczytu danych z pliku TXT, które mają zamiar powstać...

PS:
Czy ktoś mi wyjaśni co tu robi pętla WHILE?
Kod na żywca zerżnięty z pomocnej odpowiedzi z wątku: Zliczanie wciśniętych przycisków przez klawiaturę

A chodzi mi o to, że bez tego While nie działa :) I nie przechwytuje znaczków.

  public partial class Form1 : Form
    {
        [DllImport("user32.dll")]
        public static extern int GetAsyncKeyState(Int32 i);


        public Int64 litera_A = 0;

        public Form1()
        {
            InitializeComponent();

            Thread t  = new Thread(StartLogging);

            Show();
            StartLogging();
        }


       static void StartLogging()
        {
           

while (true)
            { 
                for (Int32 i = 0; i < 255; i++)
                {
                    int keyState = GetAsyncKeyState(i);
                    if (keyState == 1 || keyState == -32767)
                    {
                        //   Console.WriteLine((ConsoleKey)i + "  a jego kod to: " + i.ToString());

                        Console.WriteLine(litera_A.ToString());
                        switch (i)
                        {
                            case 65:
                                {
                                    litera_A++;
                                    break;
                                }
                        }
                   
                    }
                }
            }
        }
0

Myślę że najpierw powinieneś zrozumieć jak działają metody statyczne, a dopiero potem brać się za wątki.

Weź pod uwagę, że skoro StartLogging jest statyczna, to można ją wywołać bez żadnego obiektu Form1, więc ta Twoja zmienna A wcale nie musi być zainicjalizowana.

Bo domyślam się że chcesz zrobić jakiegoś key-loggera?

1

Przed metodami statycznymi ogarnąłbym jeszcze co robi pętla while.

0

Nie chce keyllogera pisać o czym pisałem w poprzednim wątku.
Chcę tylko czysto statystycznie dla siebie, zbadać i zapisać ile razy walę palcami w klawiaturę ;] Stąd taki prosty programik ...

A nie wiem czy wątki potrzebuję, ale skoro while blokuje mi forme ...

Wiem co robi pętla while, ale nie wiem czemu bez niej program nie działa.

1
  1. Masz funkcję GetAsyncKeyState(), którą chcesz wywoływać co jakiś czas żeby sprawdzać jaki klawisz masz wciśnięty.
  2. Żeby wywoływać ją co jakiś czas i sprawdzać jaki masz klawisz, musisz to wsadzić do jakiejś pętli (obojętnie jakiej), prawdopodobnie z jakimś sleepem - albo wymyślić jakiś inny sposób jak dodać interwał do wywoływania GetAsyncKeyState().
  3. Mając taką pętlę musisz:
    a) Albo pogodzić się z tym że Form nie reaguje na zdarzenia - bo przecież jest zajęta tą nieskończoną pętlą która słucha na GetAsyncKeyState()
    b) Albo olać to, bo nie wiem w ogóle po co taki program potrzebuje interfejs graficzny i formularz? Obeszłoby się bez tego.
  4. Albo możesz to wsadzić do wątku, który będzie miał w sobie taką pętle. Ale oczywiście ten wątek nie powinien modyfikować pól w formularzu! Tylko mieć jakiś swój zestaw danych w którym będzie przetrzymywał informacje które chcesz zbierać.
  5. Potem jak zatrzymasz wątek, to możesz te dane zapisać gdzieś do pliku czy gdzieś.
0

Forma jest po to aby się aktualizowała i pokazywała w tej chwili statystykę danych, które są aktualizowane w pliku txt, i wyświetlane na formie.
No właśnie po to są chcę wątek zrobić.

Ale to się chrzani na używaniu zmiennych. ...

0

Po pierwsze

Thread t  = new Thread(StartLogging);  // instancjonowanie wątku, który umie odpalić StartLogging nieblokująco
 
Show();
StartLogging(); // odpalenie StartLogging() blokująco

Jak widzisz ostatnia linijka to wywołanie StartLogging(), która ma ogromną pętlę w środku. Pozbądź się tego. Dodatkowo, nigdzie nie startujesz wątku t. On się stworzył, ale się nie uruchomił, tylko go zadeklarowałeś.

I najważniejsza sprawa, dostęp do wszystkich danych w Twoim formularzu musi być synchronizowany - to jest głębszy temat, ale poczytaj o tym w google "c# synchronized fields".

0

A dobra po prostu:
public Form1()
{
InitializeComponent();

        Thread t  = new Thread(StartLogging);
        t.Start();
        Show();
     //   StartLogging();
    }

Ale dalej nie rozumiem co z ... zmiennymi ... czemu nie mogę ich używać w funkcji.

0
youmound napisał(a):

nie mogę zrobić

t.Start();

Błąd IDE1007 Nazwa „t” nie istnieje w bieżącym kontekście.
Błąd IDE1007 Nazwa „Start” nie istnieje w bieżącym kontekście.

Musisz to robić w złym miejscu, skoro linijke wyzej masz Thread t = new thread().

0

Nie chcę już zakładać nowego wątku.

Są postępy w kodzie:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Keylogger
{
    public partial class Form1 : Form
    {
        private GlobalKeyboardHook _globalKeyboardHook;

        public void SetupKeyboardHooks()
        {
            _globalKeyboardHook = new GlobalKeyboardHook();
            _globalKeyboardHook.KeyboardPressed += OnKeyPressed;
        }
        private void OnKeyPressed(object sender, GlobalKeyboardHookEventArgs e)
        {
            

            if (e.KeyboardState == GlobalKeyboardHook.KeyboardState.KeyDown)
            {
                var znak = $"{(char)e.KeyboardData.VirtualCode} {e.KeyboardData.VirtualCode}";


                //////////////////////    SEKCJA F1   ///////////////////////////////////////////
                if ((e.KeyboardData.VirtualCode >= 112) && (e.KeyboardData.VirtualCode <= 123))
                {
                    znak = "F" + (e.KeyboardData.VirtualCode - 111).ToString();
                }

                //////////////////////   SEKCJA NUMERYCZNA ///////////////////////////////////////////

                if ((e.KeyboardData.VirtualCode >= 96) && (e.KeyboardData.VirtualCode <= 105))
                {
                    znak = (e.KeyboardData.VirtualCode - 96).ToString();
                }


                if (e.KeyboardData.VirtualCode == 144)
                {
                    znak = "NumLock";
                }

                if (e.KeyboardData.VirtualCode == 111)
                {
                    znak = "/";
                }

                if (e.KeyboardData.VirtualCode == 106)
                {
                    znak = "*";
                }

                if (e.KeyboardData.VirtualCode == 109)
                {
                    znak = "-";
                }

                if (e.KeyboardData.VirtualCode == 107)
                {
                    znak = "+";
                }

                if (e.KeyboardData.VirtualCode == 107)
                {
                    znak = ",";
                }

                //////////////////////   SEKCJA GŁÓWNA ///////////////////////////////////////////

                if (e.KeyboardData.VirtualCode == 13)
                {
                    znak = "ENTER";
                }

                if (e.KeyboardData.VirtualCode == 192)
                {
                    znak = "`";
                }

                if (e.KeyboardData.VirtualCode == 9)
                {
                    znak = "tabulator";
                }

                if (e.KeyboardData.VirtualCode == 20)
                {
                    znak = "capslock";
                }

                if (e.KeyboardData.VirtualCode == 160)
                {
                    znak = "LewyShift";
                }

                if (e.KeyboardData.VirtualCode == 162)
                {
                    znak = "ctrl";
                }

                if (e.KeyboardData.VirtualCode == 91)
                {
                    znak = "win";
                }

                if (e.KeyboardData.VirtualCode == 32)
                {
                    znak = "spacja";
                }

                if (e.KeyboardData.VirtualCode == 37)
                {
                    znak = "←";
                }

                if (e.KeyboardData.VirtualCode == 39)
                {
                    znak = "→";
                }

                if (e.KeyboardData.VirtualCode == 38)
                {
                    znak = "↑";
                }

                if (e.KeyboardData.VirtualCode == 40)
                {
                    znak = "↓";
                }

                if (e.KeyboardData.VirtualCode == 8)
                {
                    znak = "backup";
                }

                if (e.KeyboardData.VirtualCode == 161)
                {
                    znak = "prawyShift";
                }

                if (e.KeyboardData.VirtualCode == 93)
                {
                    znak = "ppm";
                }

                if (e.KeyboardData.VirtualCode == 45)
                {
                    znak = "insert";
                }

                if (e.KeyboardData.VirtualCode == 44)
                {
                    znak = "printscreen";
                }

                if (e.KeyboardData.VirtualCode == 19)
                {
                    znak = "pause";
                }

                if (e.KeyboardData.VirtualCode == 166)
                {
                    znak = "back";
                }

                if (e.KeyboardData.VirtualCode == 36)
                {
                    znak = "home";
                }

                if (e.KeyboardData.VirtualCode == 35)
                {
                    znak = "end";
                }

                if (e.KeyboardData.VirtualCode == 46)
                {
                    znak = "delete";
                }

                if (e.KeyboardData.VirtualCode == 33)
                {
                    znak = "pageUp";
                }

                if (e.KeyboardData.VirtualCode == 34)
                {
                    znak = "pagDown";
                }

                if (e.KeyboardData.VirtualCode == 163)
                {
                    znak = "PrawyCtrl";
                }



                //////////////////////   INNE, POZOSTAŁE ///////////////////////////////////////////

                if (e.KeyboardData.VirtualCode == 1)
                {
                    znak = "LeftClick";
                }

                if (e.KeyboardData.VirtualCode == 2)
                {
                    znak = "RightClick";
                }



                Statystyki[znak] = Statystyki.ContainsKey(znak) ? ++Statystyki[znak] : 1;
            }
        }
        public new void Dispose()
        {
            base.Dispose();
            _globalKeyboardHook?.Dispose();
        }

       
        private DateTime data_zbierania_statystyk;
        private static readonly Dictionary<string, int> Statystyki = new Dictionary<string, int>();

        public Form1()
        {
            _globalKeyboardHook = new GlobalKeyboardHook();
            SetupKeyboardHooks();

            var dt = DateTime.Now;
            data_zbierania_statystyk = new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, 0);

            Timer timer = new Timer
            {
                Interval = 1 * 10 * 1000
            };
            timer.Tick += new EventHandler(Timer_Tick);
            timer.Start();

            Timer timer2 = new Timer
            {
                Interval = 1000
            };
            timer2.Tick += new EventHandler(Timer2_Tick);
            timer2.Start();

            InitializeComponent();

        }

        private void Timer2_Tick(object sender, EventArgs e)
        {
           richTextBox1.Text = StatystykiJakoText();
        }

        void Timer_Tick(object sender, EventArgs e)
        {
            Saves();
        }
        void Saves()
        {
            var dt = DateTime.Now;
            var now = new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, 0);

            if (data_zbierania_statystyk < now)
            {
                data_zbierania_statystyk = now;

                string sb = StatystykiJakoText();

                string path = $@"O:\statystyki{dt.Year}-{dt.Month}-{dt.Day}.txt";

                File.AppendAllText(path, sb);

                richTextBox1.Text = "";
                richTextBox1.Text = sb.ToString();
            }
        }

        private string StatystykiJakoText()
        {
            var sb = new StringBuilder();
            sb.Append(Environment.NewLine);
            sb.Append($"Statystyki za dzień: {data_zbierania_statystyk}{Environment.NewLine}");

            foreach (var literka in Statystyki)
            {
                sb.Append($"{literka.Key} - {literka.Value}{Environment.NewLine}");
            }

            return sb.ToString();
        }

       
    }
}

Jest jednak dalej problem:

  1. Nie łapie każdego znaku np. prawy alt, F Mode
  2. Nie łapie znaków pisanych w nie których programach np. Notepad++?

Ktoś jest wstanie powiedzieć dlaczego tak się dzieje i jak to naprawić?

  1. Jak obsługiwać skróty np. ctrl + c, ctrl + v?
  2. Jak zabezpieczyć się przed liczeniem wciśnięta klawisza, jeśli go trzymamy a nie puścimy?
1
youmound napisał(a):

Jest jednak dalej problem:

  1. Nie łapie każdego znaku np. prawy alt, F Mode
  2. Nie łapie znaków pisanych w nie których programach np. Notepad++?

Ktoś jest wstanie powiedzieć dlaczego tak się dzieje i jak to naprawić?

  1. Jak obsługiwać skróty np. ctrl + c, ctrl + v?
  2. Jak zabezpieczyć się przed liczeniem wciśnięta klawisza, jeśli go trzymamy a nie puścimy?

Znalazłem fajną bilbioteke, która znacznie ułatwi ci sprawe:
CodeProject: https://www.codeproject.com/Articles/7294/Processing-Global-Mouse-and-Keyboard-Hooks-in-C
Github: https://github.com/gmamaladze/globalmousekeyhook

1

Nie łapie każdego znaku np. prawy alt, F Mode

Prawy Alt (AltGr) to Alt+Ctrl, z tego co pamiętam. F Mode/Fn i inne tego typu mogą w ogóle nie przechodzić do systemu operacyjnego, więc możesz ich kompletnie nie wykryć.

Jak obsługiwać skróty np. ctrl + c, ctrl + v?

W swoim OnKeyPressed nie masz do każdego klawisza jakichś Modifiers oprócz VirtualKeyCode?

1 użytkowników online, w tym zalogowanych: 0, gości: 1