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

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

[复制链接]
 楼主| 发表于 2008-11-15 04:44:13 | 显示全部楼层

回复 16楼 的帖子

如果路径中有空格时会出错,因为%0会自动在路径首尾加上引号。
发表于 2008-11-15 04:56:48 | 显示全部楼层
原帖由 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%的进程的启动命令行
发表于 2008-11-15 05:00:32 | 显示全部楼层
原帖由 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%



复制代码
发表于 2008-11-15 05:02:43 | 显示全部楼层
原帖由 shqf 于 2008-11-14 22:39 发表
各位试试行吗?我在本机上试符合要求了
@echo off
if "%0"=="%~0" (echo CMD中手动输入运行) else (echo 双击运行)
pause
exit


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

例如你的批处理文件名为:bath title.cmd
那么你的判断就不能成立
发表于 2008-11-15 20:42:01 | 显示全部楼层
原帖由 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%也许都可以通过……

但是从原理上分析就只要这样是不行的,总能找出不匹配的。
发表于 2008-11-16 00:36:16 | 显示全部楼层
要得到切实可靠的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
复制代码

评分

参与人数 1PB +4 收起 理由
pusofalse + 4 一题多解

查看全部评分

发表于 2008-11-16 18:27:43 | 显示全部楼层
。。。

VBS方便……

但是貌似题目是P处理哦
发表于 2008-11-16 18:52:17 | 显示全部楼层
勉为其难调用下吧,嘿嘿
发表于 2008-11-23 09:24:03 | 显示全部楼层

回复 5楼 的帖子

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

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

还有其他用处的吧  我们只是缺少发现美的眼睛
发表于 2012-3-17 14:41:48 | 显示全部楼层
新手迷糊,测试后怎么感觉没一个正确答案?
发表于 2012-3-17 17:06:46 | 显示全部楼层
回复 25# yzlsc


感觉你的测试方法不对头
发表于 2012-12-16 22:49:39 | 显示全部楼层
本帖最后由 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
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|批处理之家 ( 渝ICP备10000708号 )

GMT+8, 2026-3-16 23:30 , Processed in 0.021105 second(s), 8 queries , File On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表