问题描述
下面的 .bat 文件只是打开两个覆盖它们的文本文件,但我想知道是否可以定义特定的显示源,或者是否有人可以帮助提供正确的参数.
The following .bat file below simply opens two text files overlaying them, but I'm wondering if it's possible to define a specific display source, or if anyone can assist in providing the correct parameters.
@echo off
START /max /wait NOTEPAD.EXE C: estscreen1.txt
START /max /wait NOTEPAD.EXE C: estscreen2.txt
我想得到的:
@echo off
START /max /wait NOTEPAD.EXE C: estscreen1.txt "monitor1"
START /max /wait NOTEPAD.EXE C: estscreen2.txt "monitor2"
所以我试图收到的结果是 screen1.txt 在 monitor1 上打开,screen2.txt 在 monitor2 上打开.
So the results I am trying to receive is that screen1.txt opens on monitor1, and screen2.txt on monitor2.
推荐答案
除非您启动的应用程序有一个命令行开关,否则没有简单的方法来指定在哪个监视器上显示窗口.据我所知,start
和 notepad
都不支持这样的开关.我找到的最接近的解决方案是在窗口已经打开后移动它.
Unless the application you're launching has a command-line switch for it, there's no easy way to specify on which monitor to display a window. As far as I'm aware, neither start
nor notepad
supports such a switch. The closest solution I've found is to move a window after it's already open.
这是一个混合批处理 + PowerShell 脚本,用于启动程序并将其移动到特定监视器.使用 .bat 扩展名保存它.
Here's a hybrid batch + PowerShell script to launch a program and move it to a specific monitor. Save it with a .bat extension.
<# : batch portion
@echo off & setlocal disabledelayedexpansion
set args=%*
call set args=%%args:%1 %2=%%
set "exe=%~2"
set "monitor=%~1"
set "scriptname=%~nx0"
powershell -noprofile "iex (${%~f0} | out-string)"
exit /b %ERRORLEVEL%
: end batch / begin powershell #>
function usage() {
write-host -nonewline "Usage: "
write-host -f white "$env:scriptname monitor# filename [arguments]`n"
write-host -nonewline "* "
write-host -f white -nonewline "monitor# "
write-host "is a 1-indexed integer. Monitor 1 = 1, monitor 2 = 2, etc."
write-host -nonewline "* "
write-host -f white -nonewline "filename "
write-host "is an executable or a document or media file.`n"
write-host -nonewline "$env:scriptname mimics "
write-host -f white -nonewline "start"
write-host ", searching for filename both in %PATH% and"
write-host "in Windows' app paths (web browsers, media players, etc).`n"
write-host "Examples:"
write-host "To display YouTube in Firefox on your second monitor, do"
write-host -f white " $env:scriptname 2 firefox `"www.youtube.com`"`n"
write-host "To play an mp3 file using the default player on monitor 1:"
write-host -f white " $env:scriptname 1 mp3file.mp3"
exit 1
}
add-type user32_dll @'
[DllImport("user32.dll")]
public static extern void SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter,
int x, int y, int cx, int cy, uint uFlags);
'@ -namespace System
add-type -as System.Windows.Forms
if ($env:monitor -gt [windows.forms.systeminformation]::MonitorCount) {
[int]$monitor = [windows.forms.systeminformation]::MonitorCount
} else {
[int]$monitor = $env:monitor
}
try {
if ($env:args) {
$p = start $env:exe $env:args -passthru
} else {
$p = start $env:exe -passthru
}
}
catch { usage }
$shell = new-object -COM Wscript.Shell
while (-not $shell.AppActivate($p.Id) -and ++$i -lt 100) { sleep -m 50 }
try {
$x = [Windows.Forms.Screen]::AllScreens[--$monitor].Bounds.X
$hwnd = (Get-Process -id $p.Id)[0].MainWindowHandle
[user32_dll]::SetWindowPos($hwnd, [intptr]::Zero, $x, 0, 0, 0, 0x41);
}
finally { exit 0 }
原答案:编译并链接 c# 可执行文件
移动窗口也不是一件容易的事.有关其他一些选项,请参阅这篇文章.但这里有一个批处理脚本,它将动态组合和链接 C# 应用程序以处理窗口移动.
Original answer: compile and link c# executable
And moving a window is no easy task, either. See this post for some other options. But here's a batch script that will compose and link a C# app on the fly to handle window moves.
@echo off
setlocal
:: // generate c.cs
call :heredoc movewind >"%temp%c.cs" && goto compile_and_link
// syntax: movewind.exe [pid | "window title"] x y
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
class movewind {
[DllImport("user32.dll", SetLastError = true)]
private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, uint uFlags);
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
static void Main(string[] args) {
int pid;
string title;
bool res = Int32.TryParse(args[0], out pid);
if (res) {title = Process.GetProcessById(pid).MainWindowTitle;} else {title = args[0];}
IntPtr handle = FindWindow(null, title);
try {
SetWindowPos(handle, IntPtr.Zero, Convert.ToInt32(args[1]), Convert.ToInt32(args[2]), 0, 0, 0x41);
}
catch (Exception e) {
Console.WriteLine("Exception caught while attempting to move window with handle " + handle);
Console.WriteLine(e);
}
}
}
:compile_and_link
set "movewind=%temp%movewind.exe"
for /f "delims=" %%I in ('dir /b /s "%windir%microsoft.net*csc.exe"') do (
if not exist "%movewind%" "%%I" /nologo /out:"%movewind%" "%temp%c.cs" 2>NUL
)
del "%temp%c.cs"
if not exist "%movewind%" (
echo Error: Please install .NET 2.0 or newer.
goto :EOF
)
:: // get left monitor width
for /f "tokens=2 delims==" %%I in ('wmic desktopmonitor get screenwidth /format:list') do set "x=%%I"
:: // make sure test environment is in place
if not exist "c: est" mkdir "c: est"
if not exist "c: estscreen1.txt" >"c: estscreen1.txt" echo This should be on the left.
if not exist "c: estscreen2.txt" >"c: estscreen2.txt" echo This should be on the right.
:: // syntax: movewind.exe [pid | "window title"] x y
start /max notepad.exe "c: estscreen1.txt"
call :movewind "screen1.txt - Notepad" 0 0
start /max notepad.exe "c: estscreen2.txt"
call :movewind "screen2.txt - Notepad" %x% 0
del "%movewind%"
:: // end main runtime
goto :EOF
:: // SCRIPT FUNCTIONS
:movewind <title> <x> <y>
tasklist /v | find /i "%~1" && (
"%movewind%" "%~1" %~2 %~3
goto :EOF
) || (
ping -n 1 -w 500 169.254.1.1 >NUL
goto movewind
)
:heredoc <uniqueIDX>
:: // https://stackoverflow.com/a/15032476/1683264
setlocal enabledelayedexpansion
set go=
for /f "delims=" %%A in ('findstr /n "^" "%~f0"') do (
set "line=%%A" && set "line=!line:*:=!"
if defined go (if #!line:~1!==#!go::=! (goto :EOF) else echo(!line!)
if "!line:~0,13!"=="call :heredoc" (
for /f "tokens=3 delims=>^ " %%i in ("!line!") do (
if #%%i==#%1 (
for /f "tokens=2 delims=&" %%I in ("!line!") do (
for /f "tokens=2" %%x in ("%%I") do set "go=%%x"
)
)
)
)
)
goto :EOF
这篇关于打开文件时指定监视器.(.蝙蝠)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!