【问题标题】:CreateProcess for the current executable in presence of renames存在重命名的当前可执行文件的 CreateProcess
【发布时间】:2021-08-23 06:03:32
【问题描述】:

是否可以在 Windows 10 中调用 CreateProcess() 并确保它启动与当前进程完全相同的可执行文件,即使当前可执行文件可以随时重命名?例如,如果当前进程的可执行文件最初名为name.exe,但随后在进程运行时将其重命名为name_old.exe,那么子进程应该使用name_old.exe

我可以使用QueryFullProcessImageName() 检测当前进程的名称更改。问题是这不是原子的,因为重命名可能恰好发生在该调用和CreateProcess之间。

这样做的背景是我们正在为我们的应用程序实施实时更新。更新过程在检测到应用程序可执行文件正在使用时,将可执行文件重命名为name_old.exe,然后将新版本复制为name.exe。然后,当用户使用name_old.exe 关闭应用程序的最后一个实例时,旧版本将被删除。

这几乎可行。问题是应用程序启动了子工作进程。那些应该使用与主应用程序完全相同的可执行文件,因为更新可以改变父子交互的协议。所以我们必须防止子进程使用新的可执行文件,而父进程使用旧的可执行文件。

【问题讨论】:

  • 如果您的通信协议允许中断更改,为什么没有实施版本控制方案?这似乎是您要解决的真正问题。
  • 为严格的本地 IPC 对协议进行版本控制比确保实时更新正常工作要复杂得多。在最坏的情况下,如果我们没有找到解决问题的方法,我们可能会在更新过程和主应用程序之间添加一些通信。
  • 奇数。您不知道如何解决特定问题,但确信其解决方案比已解决问题的解决方案简单。
  • 我们确实知道如何创建解决方法。例如,更新过程可以向应用程序发送一个即将重命名可执行文件的事件,并等待应用程序确认,然后重命名可执行文件。收到信号后,应用程序会等待直到可执行文件被重命名,然后再创建新的子进程。但这需要更新程序和应用程序之间的合作,这使得更新过程不那么健壮。

标签: winapi createprocess


【解决方案1】:

使用在我们将单个可能重命名为已知名称的情况下有效的解决方案来回答自己的问题。诀窍是将CreateProcess()CREATE_SUSPENDED 标志一起使用。然后检查name_old.exe 的存在。如果文件不存在,我们知道没有重命名,我们可以恢复刚刚创建的进程。如果有这个名字,我们就直接杀掉创建的进程,然后使用 CreateProcess 和 ``name_old.exe` 作为可执行文件。

最初我认为上述的变体也可以用于任意重命名。想法是首先使用QueryFullProcessImageName() 查找父可执行文件的当前名称,然后使用该名称创建如上所示的挂起子进程,然后使用QueryFullProcessImageName() 再次查找父进程的路径。如果它与原来的匹配,那么应该在调用之间没有重命名,并且可以恢复孩子。在不匹配时杀死孩子并重复。

但如果允许真正任意重命名,这将不起作用。例如,可以重命名父级,在旧名称下创建临时可执行文件,然后将临时文件重命名为另一个名称,然后将父级重命名回原始名称。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-28
    • 1970-01-01
    • 2011-07-08
    • 2010-11-15
    • 2012-05-09
    • 1970-01-01
    • 1970-01-01
    • 2022-01-25
    相关资源
    最近更新 更多