2012-12-28 25 views
0

我從user32.dll中 註冊一個熱鍵爲「RegisterHotKey」按下熱鍵將觸發這確實Console.WriteLine(「熱鍵」)在事件發生後,熱鍵停止工作幾個Process.Getprocess調用

正常工作,但我有一個問題,約5秒後停止工作。事件不再被觸發。 通過評論事情,我已經縮小到1行代碼: Process [] p = Process.GetProcessesByName(「notepad」); 即獲取進程名稱(名稱無關緊要,記事本或任何東西)

GetProcessesByName在System.Timers計時器上每秒調用一次。就像我說的那樣,大約5秒後(有時候是3或4,隨機),熱鍵停止工作。

我該如何解決這個問題?

下面是我使用的代碼(from this website

難道這個問題有什麼做RegisterHotKey的第一個參數? (HWND) 我必須有積極的形式來註冊熱鍵嗎?

public class HotkeyController { 

    public HotkeyController() { 
     KeyboardHook k = new KeyboardHook(); 
     k.RegisterHotKey(0, Keys.Subtract); 
     k.KeyPressed += new EventHandler<KeyPressedEventArgs>(k_KeyPressed); 
    } 

    void k_KeyPressed(object sender, KeyPressedEventArgs e) { 
     Console.WriteLine("HOTKEY"); 
    } 
} 

public sealed class KeyboardHook : IDisposable { 
    // Registers a hot key with Windows. 
    [DllImport("user32.dll")] 
    private static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk); 
    // Unregisters the hot key with Windows. 
    [DllImport("user32.dll")] 
    private static extern bool UnregisterHotKey(IntPtr hWnd, int id); 
    /// <summary> 
    /// Represents the window that is used internally to get the messages. 
    /// </summary> 
    private class Window : NativeWindow, IDisposable { 
     private static int WM_HOTKEY = 0x0312; 

     public Window() { 
      // create the handle for the window. 
      this.CreateHandle(new CreateParams()); 
     } 

     /// <summary> 
     /// Overridden to get the notifications. 
     /// </summary> 
     /// <param name="m"></param> 
     protected override void WndProc(ref Message m) { 
      base.WndProc(ref m); 

      // check if we got a hot key pressed. 
      if (m.Msg == WM_HOTKEY) { 
       // get the keys. 
       Keys key = (Keys)(((int)m.LParam >> 16) & 0xFFFF); 
       ModifierKeys modifier = (ModifierKeys)((int)m.LParam & 0xFFFF); 

       // invoke the event to notify the parent. 
       if (KeyPressed != null) 
        KeyPressed(this, new KeyPressedEventArgs(modifier, key)); 
      } 
     } 

     public event EventHandler<KeyPressedEventArgs> KeyPressed; 

     #region IDisposable Members 

     public void Dispose() { 
      this.DestroyHandle(); 
     } 

     #endregion 
    } 

    private Window _window = new Window(); 
    private int _currentId; 

    public KeyboardHook() { 
     // register the event of the inner native window. 
     _window.KeyPressed += delegate(object sender, KeyPressedEventArgs args) { 
      if (KeyPressed != null) 
       KeyPressed(this, args); 
     }; 
    } 

    /// <summary> 
    /// Registers a hot key in the system. 
    /// </summary> 
    /// <param name="modifier">The modifiers that are associated with the hot key.</param> 
    /// <param name="key">The key itself that is associated with the hot key.</param> 
    public void RegisterHotKey(ModifierKeys modifier, Keys key) { 
     // increment the counter. 
     _currentId = _currentId + 1; 

     // register the hot key. 
     if (!RegisterHotKey(_window.Handle, _currentId, (uint)modifier, (uint)key)) 
      throw new InvalidOperationException("Couldn’t register the hot key."); 
    } 

    /// <summary> 
    /// A hot key has been pressed. 
    /// </summary> 
    public event EventHandler<KeyPressedEventArgs> KeyPressed; 

    #region IDisposable Members 

    public void Dispose() { 
     // unregister all the registered hot keys. 
     for (int i = _currentId; i > 0; i--) { 
      UnregisterHotKey(_window.Handle, i); 
     } 

     // dispose the inner native window. 
     _window.Dispose(); 
    } 

    #endregion 
} 

/// <summary> 
/// Event Args for the event that is fired after the hot key has been pressed. 
/// </summary> 
public class KeyPressedEventArgs : EventArgs { 
    private ModifierKeys _modifier; 
    private Keys _key; 

    internal KeyPressedEventArgs(ModifierKeys modifier, Keys key) { 
     _modifier = modifier; 
     _key = key; 
    } 

    public ModifierKeys Modifier { 
     get { return _modifier; } 
    } 

    public Keys Key { 
     get { return _key; } 
    } 
} 

/// <summary> 
/// The enumeration of possible modifiers. 
/// </summary> 
[Flags] 
public enum ModifierKeys : uint { 
    Alt = 1, 
    Control = 2, 
    Shift = 4, 
    Win = 8 
} 
+0

你能發佈您的代碼嗎?從你所說的話來看,你的實施聽起來很糟糕。 –

+0

感謝您的回覆,我添加了代碼。它來自這個網站:http://www.liensberger.it/web/blog/?p=207 – Rhett

回答

0

感謝亞歷克斯,你給了我一個想法,嘗試使用一種形式(正如我以前使用的),現在它的工作正常。

在我發佈的代碼

,這讓像這樣的窗口下(這是什麼以及它是如何從一種形式有什麼不同?) private Window _window = new Window();

也許Process.GetProcesses發現這個「窗口」,並殺死它?從而阻止熱鍵工作? 誰知道?我不是大師......

無論如何,我可以做一個看不見的形式,這是夠好的。

這是在「熱鍵形式」的代碼我使用:

public partial class HotkeyForm : Form { 
    public HotkeyForm() { 
     InitializeComponent(); 

     RegisterHotKey(this.Handle, 0, 0, (int)Keys.Subtract); 


    } 


    protected override void WndProc(ref Message m) { 
     if (m.Msg == 0x0312) { 
      switch (m.WParam.ToInt32()) { 
       case 0: //numpad minus. 
        //Environment.Exit(0); 
        Console.WriteLine("FORM HOTKEY"); 
        break; 

      } 

     } 

     base.WndProc(ref m); 
    } 


}