【问题标题】:Pass environment variable through Windows Explorer通过 Windows 资源管理器传递环境变量
【发布时间】:2015-05-06 20:00:05
【问题描述】:

我想设置一个环境变量,然后生成一个 Windows 资源管理器窗口,让从这个新资源管理器窗口启动的进程继承该环境变量。我想这样做,以便我与 TortoiseSVN shell 扩展集成的差异工具可以访问项目启动脚本中设置的项目特定环境变量。但是这样做的明显方法似乎在某处丢失了环境变量:

  1. 启动 cmd.exe
  2. set MYVAR="foo"
  3. set | findstr MYVAR
  4. 结果包含 MYVAR="foo"
  5. explorer .
  6. 在出现的资源管理器窗口中,Shift+右键单击文件夹并选择“在此处打开命令窗口”
  7. set | findstr MYVAR
  8. 结果不包含 MYVAR

我已将 Windows 资源管理器设置为 spawn a new process for each Explorer window,希望这会有所帮助,但似乎没有任何效果。

我可以使用setx 而不是set 来全局存储变量,但是如果我希望多个窗口具有不同版本的 MYVAR(例如,如果我同时处理多个项目),这将不起作用.

有没有办法设置一个特定于 Windows 资源管理器窗口的环境变量,它会被它的所有子进程继承?

【问题讨论】:

  • 据我所知,Explorer 进程从运行开始菜单的进程继承其环境。您可以通过注销并重新打开或关闭进程并使用任务管理器重新启动它来重置该环境,但我不知道有什么方法可以在保持不同环境的同时用不同的环境实例化一个新的explorer.exe 进程变量集(除了使用不同的用户)。如果 Microsoft 专门检查以确保这不会发生,我不会感到惊讶。
  • 老实说,这听起来像是一个 XY 问题。您实际上想要完成什么?为什么不使用批处理脚本或带有命令行 svn 客户端的命令行,它通常与 TortoiseSVN 一起安装到C:\Program Files\TortoiseSVN\bin
  • TortoiseSVN 被配置为为某些二进制文件启动一个特殊的 diff 工具,并且这个 diff 工具需要知道在哪里可以找到一个项目特定的目录,以便在处理 diff 之前进行一些额外的配置。我环境中的其他工具已经使用项目启动脚本设置的环境变量来查找此目录。所以我的目标是在 diff 工具中使用该环境变量(每个项目都会更改)。由于 TortoiseSVN 通过 Windows 资源管理器启动,我想让 Windows 资源管理器将该环境变量传递给 TortoiseSVN(然后传递给 diff 工具)。
  • 你可能是对的,因为如果解决方案涉及大量脚本和调用特殊命令来启动资源管理器窗口......它可能更容易编写工具来直接调用 TortoiseSVN 对话框,具有适当的环境变量。

标签: windows batch-file windows-explorer


【解决方案1】:
  1. 打开 CMD

    setx foo bar

  2. 启动浏览器

    开始。

  3. 打开一个新的命令窗口(Shift+右键单击文件夹)

  4. 类型

    设置 foo

  5. 输出

    foo=bar

  6. 现在如果你回到 2 中打开的 cmd 并输入

    setx foo bar2

3中打开的CMD还是会显示

>set foo
foo=bar

但是如果你从 6 中打开的 CMD 的资源管理器中打开一个新的 CMD.EXE,你会得到 ​​p>

>set foo
foo=bar2

这是可行的,因为 SETX 将创建或修改的变量传递到 未来 命令窗口,但不在当前或已创建的 CMD.exe 中。

【讨论】:

  • 之所以有效,是因为 setx.exe 会更新注册表中的环境变量值,然后将 WM_SETTINGCHANGE 消息广播到顶级窗口。 Explorer 收到环境设置已修改的消息,因此它从注册表中重新加载自己的环境。随后,从资源管理器启动的新 cmd.exe 实例获得更新环境的副本。
  • 问题在于它不断地修改环境。最后一个值将在会话中被记住。如果这是一个问题,则必须最后一次调用 setx i 来删除该变量。
  • 这是一个合理的解决方法,只要我一次只处理一个项目。但由于 所有 从资源管理器创建的新进程将继承 setx 的最后一个变量,因此同时处理多个项目的选项是有限的。
【解决方案2】:

一个程序得到一份它正在启动的进程环境变量的副本。因此,如果您生成一个新进程(文件夹选项 - 视图中的设置),这将起作用。

Set a=fred
explorer.exe

set a=cat
explorer.exe

请记住,您必须指定/n 命令行参数才能将两个窗口强制放在一个文件夹中。

【讨论】:

  • 这正是我认为它的工作方式,但请参阅我的示例。由于某种原因从资源管理器窗口启动的 cmd.exe 没有获得我在启动 explorer.exe 之前设置的变量的副本。
  • 请记住,这是一个新过程,而不是一个新窗口。我正在看任务管理器,每次我创建一个新进程时,它都会切换到现有进程。为什么你仍然需要资源管理器。这段代码给你一个资源管理器类型的东西(<html> <body> <iframe src="file:///c:/" width="100%" height="99%"> </body> </html>(命名为something.hta)
  • 是的,我设置了为每个窗口创建一个新进程的选项,我还尝试使用显式explorer /separate 方法来启动一个新的资源管理器进程。两者都有相同的结果,即您的示例中的任何一个资源管理器窗口都不能使用您正在设置的 a 变量的 any 值启动新进程。我需要资源管理器窗口来启动 shell 扩展工具,例如 TortoiseSVN,并且我需要这些工具设置环境变量。
  • 试试hta。它是在资源管理器中显示文件的同一个对象,只是在不同的主机中。
  • 嗯,.hta 有效,但确实有限。例如,如果我浏览到一个子目录,我不能“返回”或“上一级”,至少不能以任何我能看到的方式。所以看起来这个解决方案需要大量的代码来创建一个真正的资源管理器窗口的替代品。
猜你喜欢
  • 2012-08-24
  • 1970-01-01
  • 2020-03-08
  • 1970-01-01
  • 2016-12-23
  • 2018-12-02
  • 1970-01-01
  • 2020-03-05
  • 1970-01-01
相关资源
最近更新 更多