Board logo

标题: [其他] 批处理读取本机分辨率判断执行nconvert的困惑 [打印本页]

作者: kensami727    时间: 2020-10-1 00:39     标题: 批处理读取本机分辨率判断执行nconvert的困惑

本帖最后由 kensami727 于 2020-10-4 01:50 编辑

我需要nconvert合成图片,然后有几种分辨率,nconvert坐标不一样,所以我就想着比较机器号数字,或者抓取系统分辨率来goto。
set bz1="bz1\x.jpg"
set bz2="bz2\x.jpg"
for /f "delims=" %%i in ('wmic DesktopMonitor get ScreenWidth^,ScreenHeight /value ^| findstr "="') do set "%%i"
if %ScreenWidth% leq 1920 (goto pc1k) else (goto pc2k)
:pc1k
nconvert----------%bz1%
:pc2k
nconvert----------%bz2%
if exist xxx.jpg (goto wallpaper) else (goto err)


问题已经解决,我编辑了一下,方便以后有同样问题的朋友理解。我遇到两个问题。
问题一、分辨率没有获取到,造成后续的if leq之类比较不成功,不知道是特殊字符还是win10的原因,后来换成Win32_VideoController在win10下是可以获取的,但Win32_VideoController获取的并不是当前设置的分辨率,如果2k当1080用,还是会出问题,而DesktopMonitor在win10获取的是空值。管理员提示我处理特殊字符,但我是新手始终搞不定。
问题二、总是依次执行:pc1k和:pc2k,本来if就不成功,现在更加废了。

使用了很多方法,我甚至是for set version来判断系统内核,再使用if DesktopMonitor和Win32_VideoController双条件来获取分辨率。但因为win32读的是显示器的分辨率,最终还是放弃。

关于重复执行的问题,按2楼大佬提醒,我没有成功,因为合成后后续还有其它命令需要执行,这时候goto :eof,合成完图片批处理就直接终止了。干脆把pc2k的nconvert 切到另外一个批处理解决,这时候又被管理员提醒了一次。
再次翻阅goto :eof,把goto换成了call,然后在pc1k和pc2k段下加goto :eof,让命令能够返回执行下一段powershell,最终解决代码如下:

for /f "tokens=1-2 delims= " %%a in ('mshta VBScript:Execute("CreateObject(""Scripting.Filesystemobject"").GetStandardStream(1).Write(screen.width&"" ""&screen.height)"^)(close^)') do (set fbl=%%a)
if %fbl% leq 1920 (call :pc1k) else (call :pc2k)
作者: yhcfsr    时间: 2020-10-1 10:11

本帖最后由 yhcfsr 于 2020-10-1 10:16 编辑

在pc1 和pc2 的段尾都加上
  1. goto :eof
复制代码

作者: kensami727    时间: 2020-10-1 13:57

本帖最后由 kensami727 于 2020-10-1 14:51 编辑

这样写会造成我后面无法设置壁纸的,而且问题依然存在,无论是机号大小判断还是分辨率判断都没用。都跑到pc2。EQU、NEQ、LSS、LEQ、GTR、GEQ我都来回换了个遍,虽然有些能够使pc1正常,但从整个IF来说,却是失败的。
这后面接的设置壁纸,为了便于测试,我把变量都改成固定值了。
if exist 100.jpg (goto wp) else (goto err)

现在问题应该在于我的批处理并没有读书正确的分辨率,所以GTR失败
作者: terse    时间: 2020-10-1 14:56

设个标签 然后跳转过去
作者: kensami727    时间: 2020-10-1 16:48

哎脑壳疼。
作者: Batcher    时间: 2020-10-2 08:43

回复 3# kensami727


初步判断是因为wmic命令结果里面的特殊字符导致%ScreenWidth%的值里面有特殊字符,所以if判断失败。

验证方式:
echo ===%ScreenWidth%===

解决方法:批处理调用WMIC时如何处理结果中的特殊字符?
http://bbs.bathome.net/thread-2862-1-1.html
http://bbs.bathome.net/thread-28534-1-1.html
http://bbs.bathome.net/thread-28535-1-1.html
http://bbs.bathome.net/thread-12033-1-1.html
作者: kensami727    时间: 2020-10-3 17:53

本帖最后由 kensami727 于 2020-10-3 17:54 编辑

echo 屏幕分辨率宽 %ScreenWidth%
楼上大佬,前天我这样试过,没有数据显示。
用你的表达会更直观清晰,输出显示:======
%computername%是可以的。
作者: kensami727    时间: 2020-10-3 19:01

除了大佬指定的特殊字符问题以外,我刚才测试了好久,哪怕我使用mshta VBScript:Execute("CreateOb方式
又或者wmic path Win32_VideoController
win32是能够echo出正确的分辨率的,但是.....没用。
你们猜我最终怎么解决的。。。。
虽然已经能够读取到正确的分辨率变量,但仔细观察,批处理还是会依次运行pc1和pc2,我搞不定,干脆直接把pc2给删除了。然后goto pc2改成start pc2.bat问题解决。
作者: Batcher    时间: 2020-10-3 20:56

回复 8# kensami727


你可能没有理解2楼的意思,他是说改成这样:
  1. :pc1
  2. nconvert -text_font 微软雅黑 30 -text_pos 675 845 -text_color 255 0 0 -text "!text!" -text_font 微软雅黑 36 -text_pos 860 40 -text_color 0 0 0 -text "%jqh%" -wmpos 2246 905 -wmfile %pic% -out jpeg -overwrite -o %jpg_output% %bz1%
  3. goto :eof
  4. :pc2
  5. nconvert -text_font 微软雅黑 30 -text_pos 675 845 -text_color 255 0 0 -text "!text!" -text_font 微软雅黑 36 -text_pos 860 40 -text_color 0 0 0 -text "%jqh%" -wmpos 1400 618 -wmfile %pic% -out jpeg -overwrite -o %jpg_output% %bz2%
  6. goto :eof
复制代码

作者: kensami727    时间: 2020-10-3 22:45

本帖最后由 kensami727 于 2020-10-3 23:00 编辑

是这样改的呢,因为我的分辨率获取到的是空值,所以即使加了goto :eof也是没有用的。GTR比较仍然是不成功。
而且在图片合成之后,还需要设置壁纸。加了goto :eof之后
后续的if exist 100.jpg (goto wp) else (goto err)就没法执行了。合成壁纸之后程序就直接退出。
我现在用的是下面这段获取的分辨率,在win10已经可以正常获取了。系统是win7和win10均有。win7暂未测试。然后测试将第二段nconvert剪切到第二个bat里面。暂时能用。当然还是需要摸索一下我的bat到底哪里有语法错误。
for /f "delims=" %%# in  ('"wmic path Win32_VideoController  get CurrentHorizontalResolution,CurrentVerticalResolution /format:value"') do (set "%%#">nul)

请教一下wmic DesktopMonitor支持win10吗?
作者: kensami727    时间: 2020-10-3 23:40

if %CurrentHorizontalResolution% GTR 1920 (goto pc1) else (goto pc2)
改成if %CurrentHorizontalResolution% GTR 1920 (call :pc1) else (call :pc2)
就可以从goto :eof返回执行if exist 100.jpg (goto wp) else (goto err)了。
作者: kensami727    时间: 2020-10-4 00:08

wmic Win32_VideoController
wmic DesktopMonitor
哪位大佬能否讲解一下上面两个wmic命令
Win32_VideoController并不是获取当前所使用的分辨率,还是有弊端的。比如2K显示器非要设置1080用,那不是GG了。可DesktopMonitor我在win10上面又死活无法输出正常的分辨率。
作者: kensami727    时间: 2020-10-4 01:32

for /f "tokens=1-2 delims= " %%a in ('mshta VBScript:Execute("CreateObject(""Scripting.Filesystemobject"").GetStandardStream(1).Write(screen.width&"" ""&screen.height)"^)(close^)') do (set fbl=%%a)
if %fbl% leq 1920 (call :pc1k) else (call :pc2k)
作者: xczxczxcz    时间: 2020-10-4 09:43

抓机器分辨率:
  1. [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms");
  2. $width=[System.Windows.Forms.SystemInformation]::PrimaryMonitorSize.Width;
  3. $height=[System.Windows.Forms.SystemInformation]::PrimaryMonitorSize.Height;
复制代码

作者: Batcher    时间: 2020-10-4 12:20

回复 13# kensami727


调用 mshta 可能会被某些杀软拦截,也可以考虑 reg query 读取注册表:
http://bbs.bathome.net/thread-40744-1-1.html#pid186742

1.bat
  1. @echo off
  2. for /f "tokens=1,3" %%i in ('reg query "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\UnitedVideo" /s') do (
  3.     if "%%i" equ "DefaultSettings.XResolution" (
  4.         set /a ScreenWidth=%%j
  5.     ) else (
  6.         if "%%i" equ "DefaultSettings.YResolution" (
  7.             set /a ScreenHeight=%%j
  8.         )
  9.     )
  10. )
  11. echo ScreenWidth=%ScreenWidth%
  12. echo ScreenHeight=%ScreenHeight%
  13. pause
复制代码
2.bat
  1. @echo off
  2. for /f "tokens=1-2" %%a in ('mshta VBScript:Execute("CreateObject(""Scripting.Filesystemobject"").GetStandardStream(1).Write(screen.width&"" ""&screen.height)"^)(close^)') do (
  3.     set "ScreenWidth=%%a"
  4.     set "ScreenHeight=%%b"
  5. )
  6. echo ScreenWidth=%ScreenWidth%
  7. echo ScreenHeight=%ScreenHeight%
  8. pause
复制代码

作者: Batcher    时间: 2020-10-4 12:27

回复 14# xczxczxcz


    我的Win10测试结果是1280*720,实际设置是2560*1440
作者: xczxczxcz    时间: 2020-10-4 16:36

回复 16# Batcher


    这个? 分屏了?偶的1920*1080是没问题。

看这个在2K下正常么,或者偶得去2K下试试,看有什么玄机。
  1. [System.Reflection.Assembly]::LoadWithPartialName("system.windows.forms")|out-null;
  2. $w=[System.Windows.Forms.Screen]::PrimaryScreen.Bounds.Width;
  3. $h=[System.Windows.Forms.Screen]::PrimaryScreen.Bounds.Height;
复制代码

作者: xczxczxcz    时间: 2020-10-4 16:39

  1. [System.Reflection.Assembly]::LoadWithPartialName("system.windows.forms")|out-null;
  2. [System.Windows.Forms.Screen]::AllScreens;
复制代码
用这个命令看下显示结果中有2K的尺寸么?
作者: kensami727    时间: 2020-10-4 18:32

本帖最后由 kensami727 于 2020-10-4 18:35 编辑

捂脸,powershell都出来了。我这没有2k,1920正常。
另外管理员大佬,我使用的是无盘环境没有杀软需求,我1楼编辑的最终版是测试通过的。
BitsPerPixel : 32
Bounds       : {X=0,Y=0,Width=1920,Height=1080}
DeviceName   : \\.\DISPLAY1
Primary      : True
WorkingArea  : {X=0,Y=0,Width=1920,Height=1040}
作者: Batcher    时间: 2020-10-5 16:03

回复 18# xczxczxcz


我用另外一台笔记本电脑,也是Win10,实际分辨率1920x1080,测试结果如下:

PS C:\> [System.Reflection.Assembly]:oadWithPartialName("system.windows.forms")|out-null;
PS C:\> [System.Windows.Forms.Screen]::AllScreens;


BitsPerPixel : 32
Bounds       : {X=0,Y=0,Width=1280,Height=720}
DeviceName   : \\.\DISPLAY1
Primary      : True
WorkingArea  : {X=0,Y=0,Width=1280,Height=680}
作者: xczxczxcz    时间: 2020-10-5 19:28

回复 20# Batcher

你的显示缩放值应该是 150%,
1280 * 1.5 = 1920;  720 * 1.5 = 1080

2k 的显示缩放值应该是 200%
1280* 200% = 2560;  720 * 200% = 1440




欢迎光临 批处理之家 (http://bathome.net./) Powered by Discuz! 7.2