【问题标题】:How to make the COM host process avoid inheriting the environment variables from the parent process如何让COM宿主进程避免继承父进程的环境变量
【发布时间】:2011-12-30 07:39:28
【问题描述】:

我的操作系统是 Win7 x64。我有两个名为 ComHost.exe 和 ClientApp.exe 的 exe。

ComHost.exe 是一个独立的 exe,也是进程外 COM 的 COM 主机。

ClientApp.exe 通过调用 CoCreateInstance(...) 创建 COM 实例。创建 COM 实例时,进程 ComHost.exe 启动。

在windows环境变量中,有一个变量“AppStatus=status1”。

ClientApp.exe的实现中,代码是这样的

int ret = putenv("AppStatus=status2"); // Change the environment variable.
// do something
CoCreateInstance(...); // Start ComHost.exe

在ComHost.exe的实现中,我用代码得到了可行的值

char * pStatus = getenv("AppStatus");

案例1:如果双击启动ComHost.exe,pStatus的值为“status1”。

情况2:如果在ClientApp.exe中启动ComHost.exe,pStatus的值为“status2”。它继承了进程ClientApp.exe的环境变量。

我的问题是:

我希望 ComHost.exe 始终读取操作系统定义的变量值,而不是从 父进程 继承的值。这意味着,在案例 2 中,我想获得值“status1”。有可能吗?

【问题讨论】:

  • 可能,当然。我认为你在这里使用环境变量来传达状态是错误的——首先,你正在用你的状态污染所有应用程序,其次,一旦主机进程运行,你就无法更新状态。跨度>
  • 我以变量 AppStatus 为例是为了让事情容易理解。
  • 我的观点仍然存在——很可能使用环境变量不是解决方案。很多时候,这里发布的问题被划分为容易和困难(或不可能)的部分,后者被问到,而查看整个问题会告诉我们解决方案的第一部分实际上是错误的方法。跨度>
  • 我明白了。您能以某种方式找到 DLL 的绝对路径(例如,通过查询注册表),因此您可以将完整路径传递给 LoadLibrary
  • 嗯,一个明显的解决方法是在您创建第一个对象之前将其更改back。然而,依靠 PATH 来查找 DLL 总是一个坏主意。考虑 SetDllDirectory() 或将 DLL 保存在与 EXE 相同的目录中。

标签: c++ winapi environment-variables


【解决方案1】:

如果您双击“ComHost.exe”进程,您可能是从 Explorer.EXE 执行此操作的。这意味着您没有得到“操作系统定义的变量值”。您只需从 Explorer.EXE 继承它(不可否认,它在登录期间以特殊方式启动。)

在幕后,我们总是使用CreateProcess 或其变体。它的默认行为是创建一个新进程,复制调用进程的环境变量。由于您不负责创建新进程(在情况 2 中,COM 负责),因此您无法更改此行为。

因此,在这两种情况下,getenv 都会为您获取继承的值,而在情况 2 中,您无法获取“您将从 Explorer.EXE 继承的值”。

【讨论】:

  • 从 Explorer.EXE 继承的值保存在注册表中。我想我可以尝试通过注册表中的值设置变量,然后调用 CoCreateInstance(...);启动 ComHost.exe。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-07
  • 1970-01-01
  • 2011-06-20
  • 2018-09-08
相关资源
最近更新 更多