析命令提示符的原理

析命令提示符的原理

前言

启动命令提示符后,是否有这些疑问:

为什么执行ipconfig,可以直接查询到IP信息

为什么执行ping ip,可以查询到对应的主机状态。响应、未响应。

为什么执行notepad,可以启动记事本。

为什么执行explorer,可以启动文件管理器。

这些背后的原理会是什么?运作的机制又是什么?为什么输入几个简单的几个字母就能启动外部程序?

主题

本次分享围绕这以下五个问题开展:

1、在命令提示符里输入 notepad,是哪个位置的记事本被启动了?跟什么有关?

2、如果同一个目录下有两个名为 Testtest的文件,一个是 Testtest.com, 一个是 Testtest.exe。在命令提示符中输入 Testtest会执行哪个?受什么影响?

3、你知道怎么让自己的程序可以直接在命令提示符中被启动吗?像执行 ipconfig 那样。

4、如果 PATH 环境变量是空的,会有什么问题?

5、如果 PATHEXT 变量是空的,会有什么问题?

验证方式

(1)PATH验证

例子1:进入指定的文件夹中,在命令提示符输入一条不存在的命令,观察其搜索过程。

首先确定,当前命令提示符的路径在哪?相关的PATH参数。避免找错了目标。

PATH有点多,可以选择将其导出文档中。

命令:echo %PATH% > ./env.txt

接下来,就通过process monitor捕获的事件,看看命令提示符的搜索路径是怎样的。

从上面图中可以看出,蓝色部分就是当前路径相关的事件,其他的都是与PATH环境变量相关的事件。

可以得出一个小结论:

在命令提示符中输入命令会先在当前路径下查找,再到 PATH 环境变量指定的路径依次查找。

例子2:添加一个不存在的路径到PATH环境变量中,再次观察整个过程。

更新PATH环境变量的命令:set PATH=%PATH%E:\NotFolder

可以看出,其他路径都没有改变,但PATH中多出一条E:\NotFolder。

在命令提示符中,再顺便输入一条命令,查看器搜索过程。

是否发现一个奇怪的点,为什么其他目录有3条记录,而最新添加的PATH却只有1条记录?

原因:

已存在的路径,普遍有3条记录。分别是:打开、查询、关闭。

不存在的路径,只有1条记录。只有:打开。因为不存在该路径,所以打开失败,不会再有查询操作了

也可以通过栈的调用过程来观察,如下:

结论:

本次的例子2进一步验证了,例子1的结论。 PATH 环境变量是依次查找的。

在开发过程中,某环境变量特别重要,尽可能提前到前几个。

回顾下第一个问题:在命令提示符里输入 notepad,是哪个位置的记事本被启动了?跟什么有关?

例子3:编写一个测试程序(Testtest.exe),放到当前的路径下,通过命令启动,观察正常的启动路径。

测试程序内容:简单打印出当前程序的路径。

从上图可知,启动的是 C:\Users\Luojialin\Desktop\Testtest\Testtest.exe,因为在当前路径下就找到了对应的程序,所以并没有到 PATH 环境变量指示的路径中查找。

例子4: 删除当前路径下测试程序(C:\Users\Luojialin\Desktop\Testtest\Testtest.exe),并将这个程序移动到C:\windows\下,同时添加环境变量(Testtest,Testtest.exe),再起启动测试程序。

注:如果不添加该环境变量,Testtest将会无法识别。

添加环境变量:set Testtest=Testtest.exe

查询某个环境变量:echo %Testtest%

从上图可知,启动的是 C:\Windows\Testtest.exe,在当前路径下没找到,然后依次到 PATH 环境变量指示的路径中查找,在c:\windows\ 下找到了对应的程序。

例子3+例子4的结论:

依次从PATH环境变量中查询,一旦查询到对应的名称且是可执行的,立马执行。不会继续往下查询。

此处应回顾下第3个问题:你知道怎么让自己的程序可以直接在命令提示符中被启动吗?像执行 ipconfig 那样。

例子5:清空 PATH 环境变量,在命令提示符中输入 ipconfig,看看是否能正常运行。

清空环境变量:set PATH=

清空环境变量后,结果发现:连ipconfig也无法被执行了,但是ipconfig.exe这个程序是存在的。

大结论:

命令提示符中执行一个命令时的查找顺序是:当前路径,PATH 环境变量中指定的路径(按出现顺序进行查找)。

命令提示符依次从PATH环境变量中查询,一旦查询到对应的名称且是可执行的,立马执行。不会继续往下查询。

环境变量可以被清除,命令启动依赖环境变量;一旦清除环境变量后,对应的命令无法被执行。

注:因为是在窗口中执行的清除操作,仅针对当前窗口有效,重启后%PATH%会重置为与system一致。如果清除system下的PATH,就会很严重。

此处应回顾下第4个问题:如果 PATH 环境变量是空的,会有什么问题?

(2)PATHEXT验证

在上面的例子3中,会先查找 Testtest.COM,没找到才继续查找的 Testtest.exe。为什么是这种行为呢?跟什么有关呢?

查看下PATHEXT环境变量的值,如下图:

提出疑问:.COM 出现在 .EXE 之前,是不是也是依次查询的呢?

例子6:调整PATHEXT的顺序,是否会影响到查询的结果。

调整PATHEXT顺序:set PATHEXT=.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.EXE;.COM

再次执行程序,通过Process monitor捕获的事件,观察。

从图中可以看出,PATHEXT的查询顺序被调整了。本来是.COM->.EXE;现在是:.BAT->CMD->.....->.EXE->.COM

小结论:

PATHEXT的查询顺序可以被调整,可以被修改。

例子7:清空PATHEXT,再次观察PATHEXT的行为。

清空PATHEXT:set PATHEXT=

通过Process monitor捕获相关的事件:

清空PATHEXT后,原以为会向PATH一样,无法执行成功;但Testtest被执行成功,.COM→.EXE。有点像一开始的设置。

会不会是默认的PATHEXT?如果是,那么默认的PATHEXT又是什么?

例子8:修改Testtest的扩展名,修改为Testtest.abcd,观察默认的PATHEXT。

注:修改扩展名为了能够通过"Testtest"直接进入搜索,同时又不会启动成功,引起中断。

再次通过Process monitor捕获相关的事件:

与开始的进行比较(例子6的前面截图),完全就是一模一样啊。这不就是默认的PATHEXT咯。

小结论:

当 PATHEXT 为空时,默认搜索的扩展名是 .COM;.EXE;.BAT;.CMD;.VBS;.JS;.WS;.MSC。

此处就可以回顾下第5个问题:如果 PATHEXT 变量是空的,会有什么问题?

例子9:当前目录下同时存在 Testtest.com 和 Testtest.exe 会执行哪个?

单独设置.com与.exe的顺序关系。

如:

set PATHEXT=.COM;.EXE

set PATHEXT=.EXE;.COM

结果如下:

procmon 捕获的两次查找过程对比图,PAHTEXT的顺序确实会影响到查询的结果。

小结论:

优先查找 PATHEXT 中先出现的后缀名。

此处就可以回顾下第2个问题:如果同一个目录下有两个名为 Testtest的文件,一个是 Testtest.com, 一个是 Testtest.exe。在命令提示符中输入 Testtest会执行哪个?受什么影响?

例子10:如果明确添加了扩展名,即选择绝对路径。

不通过程序名称,直接执行Testtest.exe,使用程序的绝对路径,结果又会是什么?查找路径又会是什么?

注:为了不干扰数据,可以重启机器。使用默认的PATHEXT。

从图中可以看出,根本就没有搜索.COM,而是直接找到了.EXE;同时,修改扩展名为Testtest.abc,如果Testtest.exe不存在,就会直接执行失败。

小结论:

如果命令中带后缀,那么查找的时候不会依赖 PATHEXT ,会直接执行给定的命令。

总结论

PATH决定了外部命令所在位置的查找顺序,PATHEXT 决定了外部命令的扩展名查找顺序。

当我们在命令提示符中输入一个命令时,会先到当前路径(Current Directory)中查找,如果找不到,才会到环境变量PATH 指示的路径中查找。

如果输入的命令不带后缀,那么会根据PATHEXT 指示的后缀顺序依次拼接成完整名称再查找。

如果输入的命令带后缀,不会根据PATHEXT 中的后缀查找。

如果我们想让自己的程序也能直接通过命令提示符启动,我们可以把程序所在路径添加到PATH 环境变量中,位置越靠前,越有可能被执行。

如果PATHEXT 为空,那么会使用默认的 PATHEXT,默认值是: .COM;.EXE;.BAT;.CMD;.VBS;.JS;.WS;.MSC;。(可能也会根据机器决定的,待验证)

测试程序DEMO

#include

#include

int main(int argc, char* argv[]) {

char exePath[MAX_PATH] = { 0 };

::GetModuleFileNameA(NULL, exePath, MAX_PATH);

printf("%s\n", exePath);

system("pause");

return 0;

}

相关推荐

– 《食戟之灵【全6季+OVA】粤日双语》夸克网盘下载
日博best365下拉飞机XLCOKK

– 《食戟之灵【全6季+OVA】粤日双语》夸克网盘下载

📅 07-09 👍 70
QQ浏览器视频导出 视频链接提取下载
日博best365下拉飞机XLCOKK

QQ浏览器视频导出 视频链接提取下载

📅 07-20 👍 44