2012-03-22 2 views
1

작은 키로거 (악의적이지 않은 목적으로)를 개발 중이며 모든 기록 된 키 누르기를 텍스트 상자에 쓰고 싶습니다. 현재 WriteOutput에 대한 모든 호출은 시작 및 중지 방법을 제외하고 상자에 아무 것도 쓰지 않습니다. 내가 도대체 ​​뭘 잘못하고있는 겁니까? 여기 텍스트가 Windows Forms 텍스트 상자에 나타나지 않습니다.

내 코드입니다 :

Program.cs

using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Diagnostics; 
using System.Runtime.InteropServices; 
using System.Windows.Forms; 
using System.Drawing; 

namespace Logger 
{ 
    /// <summary> 
    /// Class with program entry point. 
    /// </summary> 
    internal sealed class Program 
    { 
     public static bool log = false; 

     private const int WH_KEYBOARD_LL = 13; 
     private const int WM_KEYDOWN = 0x0100; 
     private static LowLevelKeyboardProc _proc = HookCallback; 
     private static IntPtr _hookID = IntPtr.Zero; 

     [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
     private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId); 

     [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
     [return: MarshalAs(UnmanagedType.Bool)] 
     private static extern bool UnhookWindowsHookEx(IntPtr hhk); 

     [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
     private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam); 

     [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
     private static extern IntPtr GetModuleHandle(string lpModuleName); 

     private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam); 

     /// <summary> 
     /// Program entry point. 
     /// </summary> 
     [STAThread] 
     private static void Main(string[] args) 
     { 
      Application.EnableVisualStyles(); 
      Application.SetCompatibleTextRenderingDefault(false); 
      _hookID = SetHook(_proc); 
      Application.Run(new MainForm()); 
      UnhookWindowsHookEx(_hookID); 
     } 

     private static IntPtr SetHook(LowLevelKeyboardProc proc) 
     { 
      using (Process curProcess = Process.GetCurrentProcess()) 
      using (ProcessModule curModule = curProcess.MainModule) 
      { 
       return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0); 
      } 
     }  

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

       MainForm MF = new MainForm(); 
       //THIS IS THE CALL THAT DOESN'T OUTPUT ANYTHING! 
       MF.WriteOutput(vkCode.ToString()); 
      } 
      return CallNextHookEx(_hookID, nCode, wParam, lParam); 
     }  
    } 
} 

Mainform.cs

using System; 
using System.Collections.Generic; 
using System.Drawing; 
using System.Windows.Forms; 
using System.IO; 

namespace Logger 
{ 
    /// <summary> 
    /// Description of MainForm. 
    /// </summary> 
    public partial class MainForm : Form 
    {  
     public MainForm() 
     { 
      InitializeComponent(); 
     } 

     public void WriteOutput(string input) 
     { 
      output.AppendText(string.Format(input)); 
      using (StreamWriter sr = new StreamWriter("log.log", true)) 
      { 
       sr.Write(input.ToString()); 
      } 
     } 

     private void StartClick(object sender, System.EventArgs e) 
     { 
      Program.log = true; 
      output.AppendText(string.Format("Logging started\n")); 
     } 

     private void StopClick(object sender, EventArgs e) 
     { 
      Program.log = false; 
      output.AppendText(string.Format("Logging stopped\n")); 
     } 
    } 
} 

답변

2

당신은 새로운 형태마다 인스턴스화하는 대신

MainForm MF = new MainForm(); 
MF.WriteOutput(vkCode.ToString()); 

을 , 같은 것을 다시 사용하십시오. MainForm 인스턴스. Program.cs에서 :

private static MainForm mainForm; 

.... 

[STAThread] 
private static void Main(string[] args) 
{ 
    ... 
    mainForm = new MainForm(); 
    Application.Run(mainForm); 
    ... 
} 

.... 

mainForm.WriteOutput(vkCode.ToString()); 
+0

이렇게하면 정적 속성, 정적 메서드 또는 정적 필드 초기화 프로그램에서 'this'키워드가 유효하지 않습니다. –

+1

@ ryansworld10 제 나쁜 .... 물론 mainForm은 정적이어야합니다. 업데이트 된 답변보기 – ken2k

1

KeysvkCode 캐스팅 시도하고 텍스트 상자에 기록. 이처럼

: 나는 특정 문자를 캡처하는 스위치 문에서 전에이 동일한 코드를 사용하고이 캐스트를 사용하여 잘 작동하고있다

if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN && log == true) 
{     
    int vkCode = Marshal.ReadInt32(lParam); 
    MainForm MF = new MainForm(); 
    MF.WriteOutput((Keys)vkCode); 
} 

.

희망이 도움이됩니다.

+0

이 작업을 수행 한 후에도 여전히 텍스트 상자에 출력되지 않습니다. 그래도 출력 파일을 받고있다. –

관련 문제