我試圖用Powershell做一些技巧。我想編寫一個腳本,該腳本可以監聽PowerShell控制檯中的鼠標事件(點擊,移動等)。Powershell - 在PowerShell控制檯中捕獲鼠標點擊事件
例如,當我的腳本處於活動狀態時,當我在powershell控制檯中單擊鼠標時,控制檯可以輸出光標的位置。
這可能嗎?如果可能的話,如何?
在此先感謝。
我試圖用Powershell做一些技巧。我想編寫一個腳本,該腳本可以監聽PowerShell控制檯中的鼠標事件(點擊,移動等)。Powershell - 在PowerShell控制檯中捕獲鼠標點擊事件
例如,當我的腳本處於活動狀態時,當我在powershell控制檯中單擊鼠標時,控制檯可以輸出光標的位置。
這可能嗎?如果可能的話,如何?
在此先感謝。
不知道它是如何拼湊在一起的。 也許這會有所幫助。
<# Gets the Mouse Position #>
[System.Windows.Forms.Cursor]::Position
感謝您的回答。但是,這不能捕獲點擊事件。我希望PS有類似ReadKey的鼠標,像ReadClick – Fentoyal
我發現,這是可以做到這一點使用如下:
[System.Windows.Forms.UserControl]::MouseButtons
它返回當前按下鼠標按鈕的字符串。我們根據WorWin對此進行了輪詢並輸入[System.Windows.Forms.Cursor]::Position
以跟蹤鼠標的位置以及按下哪些按鈕。
不過,跟蹤鼠標在控制檯窗口內的位置有點棘手。我個人使用這個自定義類。
Add-Type -ReferencedAssemblies System.Drawing @"
using System;
using System.Drawing;
using System.Runtime.InteropServices;
public class Window
{
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();
public RECT bounds;
public bool isForeground;
private IntPtr hWnd;
public int Width;
public int Height;
public Window(IntPtr handle)
{
hWnd = handle;
Update();
}
public void Update()
{
if(GetWindowRect(hWnd, out bounds))
{
Width = bounds.Right - bounds.Left;
Height = bounds.Bottom - bounds.Top;
if(GetForegroundWindow() == hWnd){isForeground = true;}
else{isForeground = false;}
}
}
public bool Contains(Point pt)
{
return bounds.Contains(pt);
}
}
public struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
public Boolean Contains(Point pt)
{
if((pt.X >= Left) && (pt.X < Right) && (pt.Y >= Top) && (pt.Y < Bottom)){ return true;}
return false;
}
}
public struct POINT
{
public int X;
public int Y;
public static implicit operator Point(POINT point)
{
return new Point(point.X, point.Y);
}
}
"@
要得到PowerShell控制檯窗口:
$ourID = (get-process -id (Get-WmiObject -class win32_process -Filter ("ProcessID = $pid")).parentprocessid).mainwindowhandle;
$win = New-Object Window($ourID);
現在,$win.bounds
給我們的控制檯窗口的外部邊界,所以如果我們想找到這buffercell光標在我們要去必須在我們的界限上做一些工作。
$innerOffsets = new-object RECT;
$innerOffsets.Top = [Windows.Forms.SystemInformation]::CaptionHeight + [Windows.Forms.SystemInformation]::HorizontalResizeBorderThickness + [Windows.Forms.SystemInformation]::Border3DSize.Height;
$innerOffsets.Bottom = -([Windows.Forms.SystemInformation]::HorizontalResizeBorderThickness + [Windows.Forms.SystemInformation]::Border3DSize.Height);
$inneroffsets.Left = [Windows.Forms.SystemInformation]::VerticalResizeBorderThickness + [Windows.Forms.SystemInformation]::Border3DSize.Width;
$inneroffsets.Right = -([Windows.Forms.SystemInformation]::VerticalResizeBorderThickness + [Windows.Forms.SystemInformation]::Border3DSize.Width);
if([console]::bufferheight -gt [console]::windowheight)
{
$inneroffsets.right -= [Windows.Forms.SystemInformation]::HorizontalScrollBarThumbWidth;
}
if([console]::bufferwidth -gt [console]::windowwidth)
{
$inneroffsets.bottom -= [Windows.Forms.SystemInformation]::VerticalScrollBarThumbHeight;
}
這給了我們需要獲得窗口內邊界的偏移量。從這裏我們可以得到我們在窗口上的相對位置。
$mp = [Windows.Forms.Cursor]::Position;
$mp.x -= ($win.bounds.left + $inneroffsets.left);
$mp.y -= ($win.bounds.top + $inneroffsets.top);
現在我們可以將鼠標位置轉換爲緩衝單元位置。
$innerWidth = ($win.bounds.right + $inneroffsets.right) - ($win.bounds.left + $inneroffsets.left);
$innerheight = ($win.bounds.bottom + $inneroffsets.bottom) - ($win.bounds.top + $inneroffsets.top);
$mp.x = [Math]::Floor($mp.x/($innerwidth/[console]::windowWidth));
$mp.y = [Math]::Floor($mp.y/($innerheight/[console]::windowheight));
您每次檢查時都必須使用$win.update()
。您還可以使用和[Windows.Forms.UserControl]::MouseButtons -match "Left"
僅檢查控制檯窗口是否被單擊。
感謝您的詳細解答!我還沒有機會測試您的解決方案,但我非常感謝您的詳細解釋! – Fentoyal
爲什麼有些人低估了這篇文章?在這裏問這是不是一個正確的問題? – Fentoyal
嗨,SO上的一個*好問題*至少包含了一些代碼,這可能會導致downvote。 – sodawillow
對不起,我還沒有任何代碼,因爲像我的問題所述,我甚至不知道這是否可行。我檢查了$ host對象,但它似乎沒有事件處理程序。而當我在網上搜索時,大部分結果都是關於「發送活動」而不是「聽事件」。所以我來這裏尋求幫助。 – Fentoyal