首页 > 解决方案 > 过早访问 MainModule 的问题.. (C#)

问题描述

好的,这就是它的长短,这是一个困扰我一段时间的问题。我写了一些启动游戏进程的东西,然后为了继续应用程序所做的事情(它用于修改目的),它需要暂停进程并访问 MainModule 以检索进程的 BaseAddress - 不幸的是,这似乎“有时”,但并不总是导致 Win32 异常,可能是因为 MainModule 访问得太早了。(但是,出于我正在编写的工具的目的,我需要尽早访问它以在启动太远之前应用游戏修复..)

Process game = Process.Start(installPath + "game.exe", launchCommands);

            while (true) { if (game.MainModule != null) { game.Suspend(); break; } }

            int processId = game.Id;
            IntPtr baseAddress = game.MainModule.BaseAddress;

这是我正在使用的当前代码,我最初认为检查 MainModule 是否为 null 可以避免整个问题(事实上,自从我写这篇文章以来我还没有亲自遇到过)但是我的一个测试人员有时会遇到if 语句上的 Win32Exception ..

如果没有 if 语句和 while 循环,如果我只是完全暂停进程,那么当它到达 baseAddress 时,无论如何都会发生相同的异常,就像我能说的一样。在我的代码的更早的迭代中,我这样做了:

public static IntPtr BaseAddrScan(int processId, ProcessLauncher process)
    {
        try 
        {
            IntPtr baseAddress = Process.GetProcessById(processId).MainModule.BaseAddress;
            return baseAddress;
        }
        catch
        {
            Process.GetProcessById(processId).Resume();
            System.Threading.Thread.Sleep(1);
            Process.GetProcessById(processId).Suspend();
            return BaseAddrScan(processId, process);
        }
    }

实际上,它会尝试扫描 BaseAddress,如果遇到异常,它会进入 catch 块,恢复(先前)暂停的进程,等待一个滴答声,然后再次暂停它并循环回到自身并尝试再次执行所有操作,希望最终接近它可以访问 MainModule 并且一切都很好的点.. 我的意思是.. 是的,这有效,但这似乎是解决这个问题的可怕“解决方案”,感觉就像是对 try\catch 的令人讨厌的滥用而且只是笨拙的编码。在 MainModule 准备好之前肯定有某种方法可以循环,而不会导致异常..?

来自事件查看器的异常

标签: c#exceptionbase-address

解决方案


推荐阅读