2

I'm currently making a very basic script that takes a screenshot of the computer every 10 minutes. However, I've now been asked to also add in the option to click a hotkey to activate it manually.

I found this, which essentially helps me some of the way:

Add-Type -TypeDefinition '
using System;
using System.IO;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace KeyLogger {
  public static class Program {
    private const int WH_KEYBOARD_LL = 13;
    private const int WM_KEYDOWN = 0x0100;

    private static HookProc hookProc = HookCallback;
    private static IntPtr hookId = IntPtr.Zero;
    private static int keyCode = 0;

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

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

    [DllImport("user32.dll")]
    private static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, uint dwThreadId);

    [DllImport("kernel32.dll")]
    private static extern IntPtr GetModuleHandle(string lpModuleName);

    public static int WaitForKey() {

        hookId = SetHook(hookProc);
        Application.Run();
        UnhookWindowsHookEx(hookId);
        return keyCode;

    }

    private static IntPtr SetHook(HookProc hookProc) {
          IntPtr moduleHandle = GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName);
          return SetWindowsHookEx(WH_KEYBOARD_LL, hookProc, moduleHandle, 0);
    }

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

    private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) {
          if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN) {
            keyCode = Marshal.ReadInt32(lParam);
            Application.Exit();
      }
      return CallNextHookEx(hookId, nCode, wParam, lParam);
    }
  }
}
' -ReferencedAssemblies System.Windows.Forms

DO
{
    $IsTrue = $true
    while ($IsTrue -eq $true) {        
        $key = [System.Windows.Forms.Keys][KeyLogger.Program]::WaitForKey()
        if ($key -eq "F2") {
            
            #Do something
            
            $IsTrue = $false
        }
    }

} Until ($SomeValue -eq $true)

Problem is, how do I have this work, so that if the key hasn't been pressed in 10 minutes, the script will then execute the remainder of the script? Because as it is right now, it waits until a key has pressed, before going any further.

Thanks in advance!

wads
  • 123
  • 11

1 Answers1

0

you are going to need the following in the while loop. The counter will break out at 10 min

DO
{
#$i makes a timer / counter
    $i = 0
    $IsTrue = $true
    while ($IsTrue -eq $true) {        
        $key = [System.Windows.Forms.Keys][KeyLogger.Program]::WaitForKey()
#at 600 seconds or 10 mins the $i counter will break this loop.
        if ($key -eq "F2" -or $i -eq 600) {
            
            #Do something
            
            $IsTrue = $false
        }

#Sleep waits a second
        Start-Sleep -Seconds 1
#Counter $i adds 1
        $I++
    }

} Until ($SomeValue -eq $true)

The following works for time and F2

#$i makes a timer / counter
$i = 0
$IsTrue = $true
while ($IsTrue -eq $true) {  
    If ([Console]::KeyAvailable -or $i -eq 30) {
        [Console]::ReadKey('F2') | Out-Null
        $IsTrue = $false
    }
    Start-Sleep -Seconds 1
    #Counter $i adds 1
    $I++
}
dcaz
  • 847
  • 6
  • 15
  • Thanks for the comment. The problem is that it doesn't go further from $key = [System.Windows.Forms.Keys][KeyLogger.Program]::WaitForKey(), so I have a sneaking suspicion that I have to implement a timer of some sort in the WaitForKey() method. I am just not sure how to honestly – wads Feb 18 '22 at 06:59
  • @MadsBrockmannJuhl My code above is a timer and it is waiting for your key press code. Try it and change that ```600``` to ```30``` and in 30 seconds your code will continue. That is why I added the ```-or``` and the ```sleep``` with a counter. – dcaz Feb 18 '22 at 14:14
  • I did change the timer to 10 seconds, but even after 10 seconds surpassed, it didn’t do anything until I pressed a key – wads Feb 18 '22 at 14:43
  • @MadsBrockmannJuhl try my new code at the bottom above. Don't forget to change the 30 to 600 when you are ready. – dcaz Feb 18 '22 at 14:54
  • My bad! I was reading it on my phone and didn't see you had edited you post! I tried you new code and it doesn't do anything. If I press F2, nothing happens – wads Feb 18 '22 at 18:41
  • Sorry then. It works for me. Try hitting F2 more then once ? Does it have to be F2 ? From my tests your original script has a problem and didn't reach the while loop to start the time waiting. I don't know why however and you will have to wait for someone else. – dcaz Feb 18 '22 at 19:19
  • No worries! Thanks though for the attempt :) Much appreciated! – wads Feb 18 '22 at 20:45