重新启动Windows进程,保留进程ID和句柄

我创建了一个Windows可执行文件,作为某些嵌入式设备的模拟器(所有业务逻辑与原始设备完全相同,只有硬件相关的东西是存根的)。

此模拟需要不时重置,在“正常”用例中,它会执行以下操作:

//some global environment ... int main(int argc, char* argv[]) { __debugbreak(); //... do some stuff //if( restart needed ){ printf("before _execv"); _execv(argv[0], argv); //"reset" simulated device //} //... do some other testing stuff return 0; } 

注意:上面的代码仅用于说明主要思想,在实际应用中, execv调用实际上位于HW_Reset()存根中,即从原始代码中的多个位置调用。

问题是Windows上的_execv在Linux上的行为与execv完全不同:当我在Visual Studio中调试此应用程序时, _execv不会用“重新启动”的图像替换当前的过程映像。 相反,它只是创建一个带有新ID的新进程并终止当前进程,导致将其从Visual Studio中分离出来,因此,要保留我需要一次又一次地重新连接到该新进程的所有断点(在单个调试会话中有几十次重新启动) )。

目前我使用__debugbreak()作为解决方法。 其他选项是通过重新初始化全局环境并使用setjmp / longjmp的某种组合来重置模拟 – 但是全局环境和相应的初始化程序通过原始文件的thousends传播,并且大多数是静态的,因此无法手动处理此类重置(我也不允许编辑原始文件)。

所以问题是:是否有一些Windows API /通用解决方法通过重置所有全局(和静态)变量导致当前进程“就地”重新启动,例如,如果可以在同一地址内重新加载相同的进程映像空间,保留向外可观察的进程ID,进程句柄和与visual studio调试器的连接?

我担心简单的答案是Windows上没有这样的function。

Windows不支持您的要求。 您将不得不重新构造main()代码以在循环中运行,例如:

 //some global environment ... int main(int argc, char* argv[]) { __debugbreak(); do { //... (re)initialize simulated device //... do some stuff } while (restart needed); //... do some other testing stuff return 0; }