[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

【练习-032】让批处理自行判断是否被双击运行

出题目的:了解批处理运行机制。

加分规则:
        思路新颖8分
        无临时文件3分
        代码简洁3分
        完美代码15分

题目内容:
让批处理自行判断是否被双击运行还是在CMD中手动输入运行。
如同tasklist.exe、net.exe、ping.exe,当我们双击这些文件时,会一闪而过,看不到这些命令的帮助信息。只有在CMD中手动输入之后才能看到。现在的题目是编写一个批处理文件,当我们双击运行时(不带任何参数),显示“双击运行”并暂停,如果是在CMD中手动输入运行(同样不带任何参数),显示“CMD中手动输入运行”之后不暂停,直接返回到命令提示符。
心绪平和,眼藏静谧。

本帖最后由 lincc0519 于 2012-12-16 22:52 编辑

我也发一个,这个代码能解决start命令调用的情况,但在start /b这种情况下会出现2个进程共用一个窗口,本来想结束一个进程,但这样就失去了start /b命令的原意,同时新窗口下要求pause的情况,所以也就没用处理,要真处理还真是个麻烦事!代码只在windows xp下测试过!
  1. @echo off&setlocal enabledelayedexpansion
  2. doskey /history|findstr .>nul
  3. if !errorlevel! equ 0 echo cmd命令调用执行&exit/b
  4. set str=
  5. for /l %%a in (1,1,10) do set str=!str!!random!
  6. if [%1]==[] (
  7.     start /b "" "%~nx0" !str!>nul
  8.     set com=echo.
  9. ) else (
  10.     set com=pause
  11. )
  12. !com!>nul
  13. for /f "skip=1 tokens=1,2" %%a in ('wmic process where "commandline='c:\\windows\\system32\\cmd.exe  /k "%~nx0"  !str!'" get processid^,parentprocessid') do (
  14.     set /a pid=%%b,ppid=%%a
  15. )
  16. taskkill /pid !pid! /t /f 1>nul 2>nul
  17. set pid=!ppid!
  18. for /f "skip=1" %%a in ('wmic process where "processid=!pid!" get parentprocessid') do set ppid=%%a
  19. for /f "skip=1" %%a in ('wmic process where "processid=!ppid!" get caption') do set name=%%a
  20. if /i !name!==explorer.exe echo windows操作界面执行&pause>nul&exit/b
  21. if /i !name!==cmd.exe echo cmd命令调用执行&exit/b
  22. echo !name!程序执行&exit/b
复制代码

TOP

回复 25# yzlsc


感觉你的测试方法不对头

TOP

新手迷糊,测试后怎么感觉没一个正确答案?

TOP

回复 5楼 的帖子

嘿嘿 这个不是太难的东西,反倒是我觉得其做他题目 有些吃力不讨好了
学了点vbs后觉得很多东西用vbs解只需要一个函数就可以了。
所以啊还是学习它的优点好了。

不过。楼主这样的题目可以做什么呢?很 有用的
可以利用这个原理防止用户双击批处理运行,只有经过调用才能运行批处理
这不是很有用么

还有其他用处的吧  我们只是缺少发现美的眼睛

TOP

勉为其难调用下吧,嘿嘿

TOP

。。。

VBS方便……

但是貌似题目是P处理哦

TOP

要得到切实可靠的PID理论上是可行的,但为了让批处理执行是更人性化一点添加过多代码有顾此失彼的歉疑

以cscript.exe执行这个脚本即可得到cmd的PID
  1. Dim Wsh,Wmi
  2. Set Wsh=CreateObject("WScript.Shell")
  3. Set Wmi=GetObject("winmgmts:\\.\root\cimv2")
  4. Set Hta=Wsh.Exec("mshta 1")
  5. For Each i In Wmq(Hta.ProcessID)
  6.     WScript.Echo "脚本PID       :" & i.ParentProcessID
  7.     For Each j In Wmq(i.ParentProcessID)
  8.         WScript.Echo "脚本命令行    :" & j.CommandLine & vbCrLf &_
  9.                      "脚本父进程PID :" & j.ParentProcessID
  10.         For Each k In Wmq(j.ParentProcessID)
  11.             WScript.Echo "脚本父进程名称:" & k.Name & vbCrLf &_
  12.                          "脚本父进程命令:" & k.CommandLine
  13.         Next
  14.     Next
  15. Next
  16. Hta.Terminate
  17. Function Wmq(Pid)
  18. Set Wmq=Wmi.ExecQuery("Select * From Win32_Process Where ProcessID='" & Pid & "'")
  19. End Function
复制代码
1

评分人数

TOP

原帖由 everest79 于 2008-11-15 05:00 发表


根据你要求改了下

@ECHO OFF&Set /A _wt=%random%/2
title 标题%_wt%
For /f "tokens=2" %%i in ('tasklist /fi "windowtitle eq 标题%_wt%" /nh') Do set handle=%%i
wmic process where handle='%handle ...


……

加随机标题只是……
我可以取一个文件夹名为标题XXX
不一定是那个BAT……

所以要搞一个不重复的标题……

当然加了随机或者起很奇怪的名字,99%也许都可以通过……

但是从原理上分析就只要这样是不行的,总能找出不匹配的。

TOP

原帖由 shqf 于 2008-11-14 22:39 发表
各位试试行吗?我在本机上试符合要求了
@echo off
if "%0"=="%~0" (echo CMD中手动输入运行) else (echo 双击运行)
pause
exit


"%0"有一半的可能会出现两重引号,这在IF里会被识别为非法并且中断命令行

例如你的批处理文件名为:bath title.cmd
那么你的判断就不能成立

TOP

原帖由 slore 于 2008-11-14 12:01 发表
不管是路径,标题的都是有空钻的……多开的话,检测就有问题。

如何能得到当前cmd的pid是关键。

Microsoft Windows XP [版本 5.1.2600]
(C) 版权所有 1985-2001 Microsoft Corp.

C:\Documents and Setting ...


根据你要求改了下
  1. @ECHO OFF&Set /A _wt=%random%/2
  2. title 标题%_wt%
  3. For /f "tokens=2" %%i in ('tasklist /fi "windowtitle eq 标题%_wt%" /nh') Do set handle=%%i
  4. wmic process where handle='%handle%' get commandline|findstr /i /c:"cmd \/c"&&set HH=PAUSE
  5. %HH%
复制代码

TOP

原帖由 qingfengzhixia 于 2008-11-14 20:52 发表




有没有人能解释一下。
两处不懂
1。“'tasklist /fi "windowtitle eq 标题" /nh'
2。wmic


tasklist中的/fi参数是一个筛选器,随后的 "windowtitle eq 标题"是这个筛选器的条件,指窗口标题为‘标题’的即符合要求,/nh参数去掉了表头,方便在for中提取数据

wmic 是windows wmi标准的一个简化工具,在这里使用wmic查询了当前PID为%handle%的进程的启动命令行

TOP

回复 16楼 的帖子

如果路径中有空格时会出错,因为%0会自动在路径首尾加上引号。
心绪平和,眼藏静谧。

TOP

各位试试行吗?我在本机上试符合要求了
  1. @echo off
  2. if "%0"=="%~0" (echo CMD中手动输入运行) else (echo 双击运行)
  3. pause
  4. exit
复制代码

[ 本帖最后由 shqf 于 2008-11-14 22:41 编辑 ]
1

评分人数

TOP

有没有人能解释一下。
两处不懂
1。“'tasklist /fi "windowtitle eq 标题" /nh'
2。wmic

1.请运行下面的代码
  1. @echo off
  2. title 标题
  3. echo 以下是加上/nh的结果:
  4. tasklist /fi "windowtitle eq 标题" /nh
  5. echo.&echo 以下是不加/nh的结果:
  6. tasklist /fi "windowtitle eq 标题"
  7. echo.&pause
复制代码
2.wmic不懂?==>看教程

TOP

返回列表