Get the start and end times of the Focused Window from powershell - windows

I want to get the start time and end time of the Focused Window that is focused through Powershell. The Script used to get the Focused Window is as follows.
Add-Type #"
using System;
using System.Runtime.InteropServices;
public class Tricks {
[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();
}
"#
$a = [tricks]::GetForegroundWindow()
get-process | ? { $_.mainwindowhandle -eq $a }
Now I want the start time when the window is focused and when the control is lost(End time). Thanks in Advance.

Related

How can I get the foreground Window using batch?

I tried to get the foreground Window and write it in a file.
After a few tries, I've only got the task list.
Now I discovered this Code, but it won't work for me:
Add-Type #"
using System;
using System.Runtime.InteropServices;
public class Tricks {
[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();
}
"#
$a = [tricks]::GetForegroundWindow()
get-process | ? { $_.mainwindowhandle -eq $a }
Thanks :)
The code you have is a Powershell snippet. Save that file as something.ps1 or run it from cmd.exe with this:
powershell something.ps1

Powershell - Close Out-GridView after specific time

I want that a Out-GridView closes after a specific time, e.g after 10 seconds.
Not used to the windows powershell.
Any answer helps.
Unfortunately, PowerShell doesn't natively offer finding and closing arbitrary GUI windows, but you can use the Add-Type cmdlet with ad hoc-compiled C# code that in turn uses P/Invoke declarations to access the Windows API.
The following is a working example:
It defines a distinct window title to use for the Out-GridView call so that the window can be (hopefully) unambiguously located by its title later; also the assumption is that only one window by that title exists.
To make this more robust by limiting the window search to the same process, ... would require quite a bit of extra work.
It creates a background job that uses Add-Member to define a static helper class with a method for closing a window by its title, and calls it after a specifiable timeout.
It invokes Out-GridView synchronously (blocking) with -Wait, using the specified window title. If the window is left open for the specified timeout period, the background job will automatically close it.
It removes the background job after the window has closed.
Note: If you don't need the Out-GridView call to be synchronous, you wouldn't necessarily need a background job.
# Define a distinct window title that you expect no other window to have.
$title = 'Close Me'
# Start a background job that closes the window after a specified timeout.
$job = Start-Job {
param($timeout, $title)
# Define a helper class that uses the Windows API to find and close windows.
Add-Type -Namespace same2u.net -Name WinUtil -MemberDefinition #'
// P/Invoke declarations for access to the Windows API.
  [DllImport("user32.dll", SetLastError=true)]
  private static extern IntPtr FindWindow(string lpszClass, string lpszWindow);
[DllImport("user32.dll", SetLastError=true)]
private static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
const UInt32 WM_CLOSE = 0x0010;
// Returns the hWnd (window handle) of the first window that matches the
// specified title and, optionally, window class.
// If none is found, IntPtr.Zero is returned, which can you test for with -eq 0
public static IntPtr GetWindowHandle(string title, string className = null) {
// As a courtesy, we interpet '' as null, because passing null from
// PowerShell requires the non-obvious [nullstring]::value.
if (className == "") { className = null; }
return FindWindow(className, title);
}
// Closes the first window that matches the specified title and, optionally,
// window class. Returns true if a windows found and succesfully closed.
public static bool CloseWindow(string title, string className = null) {
bool ok = false;
// As a courtesy, we interpet '' as null, because passing null from
// PowerShell requires the non-obvious [nullstring]::value.
if (className == "") { className = null; }
IntPtr hwnd = FindWindow(className, title);
if (hwnd != IntPtr.Zero) {
SendMessage(hwnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
// !! SendMessage seemingly always returns 0. To determine success,
// !! we simply test if the window still exists.
ok = IntPtr.Zero == FindWindow(className, title);
}
return ok;
}
'#
Start-Sleep $timeout
$null = [same2u.net.WinUtil]::CloseWindow($title)
} -ArgumentList 3, $title
# Open an Out-GridView window synchronously.
# If you leave it open, the background job will close it after 3 seconds.
1..10 | Out-GridView -Title $title -Wait
# Remove the background job; -Force is needed in case the job hasn't finished yet
# (if you've closed the window manually before the timeout).
Remove-Job -Force $job

How to reference WinRT components in Powershell

I'm trying to use the Windows.System namespace, part of WinRT, in PowerShell.
Instead of a dll, the assembly comes as a winmd. The two ways of loading assemblies into PowerShell don't seem to work
#[System.Reflection.Assembly]::LoadFile("C:\Program Files (x86)\Windows Kits\8.0\References\CommonConfiguration\Neutral\Windows.winmd")
#Add-Type -Path "C:\Program Files (x86)\Windows Kits\8.0\References\CommonConfiguration\Neutral\Windows.winmd"
I am aware that using Windows API's is a bit trickier than loading my .NET code. I have pinched code for using parts of the win32, would a WinRT solution be similar?
$script:nativeMethods = #();
function Register-NativeMethod([string]$dll, [string]$methodSignature)
{
$script:nativeMethods += [PSCustomObject]#{ Dll = $dll; Signature = $methodSignature; }
}
function Add-NativeMethods()
{
$nativeMethodsCode = $script:nativeMethods | % { "
[DllImport(`"$($_.Dll)`")]
public static extern $($_.Signature);
" }
Add-Type #"
using System;
using System.Runtime.InteropServices;
public static class NativeMethods {
$nativeMethodsCode
}
"#
}
Register-NativeMethod "user32.dll" "int MessageBox (IntPtr hWnd, string text, string caption,int type)"
Add-NativeMethods
[NativeMethods]::MessageBox(0, "Please do not press this again.", "Attention", 0)| Out-Null
My goal is to run Windows.System.Launcher.LaunchFileAsync("C:\file"); in PowerShell. How can I load the WinRT components I need?
To load WinRT binaries into PowerShell use this example:
> [Windows.Data.Json.JsonValue,Windows.Web,ContentType=WindowsRuntime]
> $value = new-object Windows.Data.Json.JsonObject
> $value.Stringify()
{}
I think you will need a StorageFile:
> [Windows.System.Launcher,Windows.Web,ContentType=WindowsRuntime]
> [Windows.System.Launcher]::LaunchFileAsync
OverloadDefinitions
-------------------
static Windows.Foundation.IAsyncOperation[bool] LaunchFileAsync(Windows.Storage.IStorageFile file)
static Windows.Foundation.IAsyncOperation[bool] LaunchFileAsync(Windows.Storage.IStorageFile file, Windows.System.LauncherOptions options)
To create one, you may do something like this:
> [Windows.Management.Core.ApplicationDataManager,Windows.Web,ContentType=WindowsRuntime]
> $value = [Windows.Management.Core.ApplicationDataManager]::CreateForPackageFamily("BackgroundTaskApp_mxmz85hp10cp4")
> $asyncInfo = $value.LocalFolder.CreateFileAsync("foo.txt")
To await *Async() methods, you will need to do something like to create a wrapper.

How to know if it is the Windows console?

Is there any safe way to know whether the actual window is the windows console?
GetConsoleTitle does not works since the title can be changed.
When you run CMD (or any console based programs) from your program via CreateProcess or ShellExecuteEx functions, you'll get its process ID. Use it with EnumWindows and GetWindowThreadProcessId to find its console window.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Process[] processes = Process.GetProcessesByName("cmd");
foreach (Process p in processes)
{
var window = p.MainWindowHandle;
// Do something
}
}
}
}

Using WM_SHOWWINDOW to Show a Window instead of ShowWindow()

I’m trying to use the SendMessage function of a hotkey utility (or NirCMD, etc.) to get a hidden window to pop up. I can for example get windows to close by sending 0x0010 (WM_CLOSE), but when I try sending 0x0018 (WM_SHOWWINDOW) with a wParam of 1 and an lParam of 0, nothing happens.
I’ve looked around, and the few places where someone complained that WM_SHOWWINDOW did not work, they happily took the suggestion to use ShowWindow() instead.
However I don’t have ShowWindow() available; I can only send Windows messages. But ShowWindow() is not magic, surely it works by SendMessage-ing a WM_SHOWWINDOW or something under the covers.
How can I get a window to display itself by sending it a message?
Thanks.
Try these two messages:
SendMessage(h,WM_SYSCOMMAND,SC_MINIMIZE,0);
SendMessage(h,WM_SYSCOMMAND,SC_RESTORE,0);
Or if using 3rd party apps is ok, try cmdow
WM_SHOWWINDOW is a notification, not a command. From MSDN:
The WM_SHOWWINDOW message is sent to a window when the window is about to be hidden or shown.
I don't believe there is any message that you can use to make a window show itself. Actually, the very idea seems a little strange to me. The window manager is the system component responsible for showing and hiding windows. To show a window, you must use one of the window manager APIs.
I think there is no way to achieve that with SendMessage (WM_SYSCOMMAND didn't work for me). I tried actually in C#. You click the button, the window will be minimized via ShowWindow() and then you can see what messages are sent:
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public class Form1: Form
{
[DllImport("user32.dll", SetLastError = true)]
public static extern bool ShowWindow(IntPtr window, int showCommand);
private const int SW_MINIMIZE = 6;
private bool print = false;
public Form1()
{
Button button = new Button();
button.Click += onButtonsClick;
Controls.Add(button);
}
private void onButtonsClick(object sender, EventArgs e)
{
print = true;
ShowWindow(Handle, SW_MINIMIZE);
print = false;
}
protected override void WndProc(ref Message m)
{
if (print)
Console.WriteLine(m.Msg.ToString() + "\t0x" + m.Msg.ToString("x4") + "\t" + m.WParam + "\t" + m.LParam);
base.WndProc(ref m);
}
}
}

Resources