windows 10, 如何使用 batch , vbs 將桌面上的視窗移至特定位置?
這些腳本語言缺乏直接控制 Windows GUI 視窗 API(如 MoveWindow)的能力。
powershell 腳本過於複雜,有其它方法嗎?
舉世皆芭樂.....
windows 10, 如何使用 batch , vbs 將桌面上的視窗移至特定位置?
MoveWindow)的能力。user32.dll) 來移動視窗。move_window.vbs 的檔案,並寫入以下程式碼:' 設定目標視窗標題與位置
Dim windowTitle, x, y, width, height
windowTitle = "記事本" ' 改為您的目標視窗標題(支援部分比對)
x = 100 ' 畫面 X 座標
y = 100 ' 畫面 Y 座標
width = 800 ' 視窗寬度
height = 600 ' 視窗高度
' 組合 PowerShell 指令
Dim psCmd
psCmd = "powershell -NoProfile -Command """ & _
"[[void]][System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms'); " & _
"$code = @' " & vbCrLf & _
"[DllImport(\""user32.dll\"")] " & vbCrLf & _
"public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint); " & vbCrLf & _
"[DllImport(\""user32.dll\"")] " & vbCrLf & _
"public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); " & vbCrLf & _
"'@; " & _
"$type = Add-Type -MemberDefinition $code -Name Win32 -PassThru; " & _
"$ws = New-Object -ComObject Shell.Application; " & _
"$win = $ws.Windows() | Where-Object { $_.LocationName -like '*" & windowTitle & "*' -or $_.Name -like '*" & windowTitle & "*' }; " & _
"if (!$win) { $processes = Get-Process | Where-Object { $_.MainWindowTitle -like '*" & windowTitle & "*' }; " & _
"foreach ($p in $processes) { $type::MoveWindow($p.MainWindowHandle, " & x & ", " & y & ", " & width & ", " & height & ", $true) } }" & _
""""
' 執行指令(隱藏視窗背景執行)
CreateObject("Wscript.Shell").Run psCmd, 0, True
.vbs 或 .bat 副檔名,直接寫成 .ps1 檔案是 Windows 10 系統下最標準的做法。MoveWindow.ps1 檔案:# 定義 Windows API
$API = @'
[DllImport("user32.dll")]
public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
'@
Add-Type -MemberDefinition $API -Name WindowModifier -Namespace Win32
# 設定目標與參數
$ProcessName = "notepad" # 執行緒名稱(例如記事本為 notepad)
$X = 200
$Y = 200
$Width = 1024
$Height = 768
# 取得視窗控制代碼並移動
$Target = Get-Process -Name $ProcessName -ErrorAction SilentlyContinue
if ($Target) {
[Win32.WindowModifier]::MoveWindow($Target.MainWindowHandle, $X, $Y, $Width, $Height, $true)
}
.bat 檔案來啟動它:powershell -ExecutionPolicy Bypass -File "C:\路徑\MoveWindow.ps1"
Win + 方向鍵)。snap_window.vbs:Set WshShell = CreateObject("WScript.Shell")
' 1. 先將目標視窗帶到最前端(以記事本為例)
WshShell.AppActivate "記事本"
WScript.Sleep 500 ' 等待視窗反應
' 2. 模擬按下 Win + 左方向鍵 (將視窗靠左側拼貼)
' 註:VBScript 無法直接模擬 Win 鍵,但可以透過組合鍵或複製特定行為。
' 這裡改用通用組合鍵:Alt + Space,再按 M (移動),再用方向鍵移動
WshShell.SendKeys "% "
WScript.Sleep 100
WshShell.SendKeys "M"
WScript.Sleep 100
WshShell.SendKeys "{LEFT 50}" ' 往左移動 50 次
WshShell.SendKeys "{ENTER}" ' 確認位置
cmd for commad, for /r "dir" %i (*) 中,若 dir 要使用另外一個 loop 變數 "%~j" 或者 "!F!" 為何不能使用?
FOR /R 的設計有一個核心限制:它的搜尋路徑必須在指令「解析(Parse)階段」就確定,而不能在「執行(Execute)階段」動態改變。%~j(巢狀迴圈變數)失敗原因:FOR /R 語法規定,路徑參數必須是一個靜態字串或環境變數。當它嵌套在另一個迴圈內時,FOR /R 會在外部迴圈開始執行「前」就先被解析,此時 %~j 還沒有被賦值,導致語法錯誤。!F!(延遲環境變數)失敗原因:FOR /R 不支援延遲變數擴展(Delayed Expansion)作為其路徑。即使開啟了 setlocal enabledelayedexpansion,FOR /R 仍會在處理 !F! 之前就完成路徑解析,導致它把 !F! 當成一個名為 !F! 的字面字串路徑。FOR /R 的搜尋路徑,請使用以下兩種標準替代方案:PUSHD 切換目錄(最推薦)/R,而是先用 PUSHD 切換到該動態路徑,然後直接執行 FOR /R(不指定路徑,預設為當前目錄)。@echo off
setlocal enabledelayedexpansion
:: 假設 %~j 或 !F! 的路徑存在變數 dirPath 中
set "dirPath=C:\Your\Dynamic\Path"
pushd "!dirPath!"
for /r %%i in (*) do (
echo %%i
)
popd
CALL 呼叫子程序FOR /R 移到一個獨立的子程序(Label)中,並透過參數將動態路徑傳遞過去。此時參數會變成靜態的 %1,FOR /R 就能正常解析。@echo off
:: 外部迴圈範例,假設從某處取得了變數 %%j
for /d %%j in (C:\Test\*) do (
call :SubLoop "%%~j"
)
goto :eof
:SubLoop
:: 此時 %1 是從外部傳進來的靜態路徑
for /r "%~1" %%i in (*) do (
echo %%i
)
goto :eof
%~j 是如何取得路徑的?(例如:讀取文字檔、遍歷資料夾?)
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\DOS Devices]
"R:"="\\??\\d:\\ramdisk"
"H:"="\\??\\E:\\H"
"Z:"="\\??\\d:\\home"
若要透過登錄檔(Registry)強制讓所有資料夾預設使用「詳細資料」(Details)檢視模式,這涉及修改資料夾的 「檢視狀態」(View States) 邏輯。
windows cmd 如何使用 dir 顯示一個目錄是否為 junction 與其來源? 而不是用 dir 其所在目錄之後再 parsing 的方式?
在 VBScript 中,內建的 Trim 函數只能移除空白字元 (Space, ASCII 32)。若要移除字串前後的換行符號(如 vbLF、vbCr 或 vbCrLf),你需要使用正規表達式 (RegExp) 或手動循環檢查。
操作文件前先做:
Application.ScreenUpdating
= False
Application.DisplayStatusBar
= True
Application.Options.Pagination
= False
…
Set doc =
Documents.Add