CLR Dll UI 创建了太多表单

CLR Dll UI creating too many forms

所以我正在尝试用 C++ 创建一个 dll,它将在将表单注入进程时打开一个表单。

这是我的代码(与为表单生成的文件分开的文件):

#include "Main.h"
#include <Windows.h>

using namespace::System;
using namespace::System::Windows::Forms;

auto FormRender(void) -> void {
    Hyperscanner::Main lpMain;
    lpMain.ShowDialog();

    return;
}

HANDLE g_Thread = nullptr;

auto __stdcall DllMain(HMODULE hMod, DWORD dwReason, void* lpReserved) -> int {
    if (dwReason) {
        g_Thread = CreateThread(nullptr, 0, reinterpret_cast<LPTHREAD_START_ROUTINE>
            (FormRender), nullptr, 0, nullptr);
    }

    if (!dwReason) {
        TerminateThread(g_Thread, 0);
        CloseHandle(g_Thread);
        FreeLibraryAndExitThread(hMod, 0);
    }

    return true;
}

问题是,由于某种原因,当我将它注入到进程中时,它一直在创建表单,就像线程中有一个循环一样,但正如您所看到的,没有一个。当我尝试在没有线程的情况下正常调用它时,它根本不显示,这没有意义,因为从技术上讲,它与线程中的调用是一样的。

我想知道我做错了什么,需要帮助。谢谢!

解决方案(@hacksalot):

问题是有很多线程启动,这些线程将通过我的 DllMain 回调,因此它会启动一堆线程(由于某种原因没有考虑检查正在创建多少线程)。

为了解决这个问题,我添加了一个全局变量以确保它只执行一次。

#include "Main.h"
#include <Windows.h>

using namespace::System;
using namespace::System::Windows::Forms;

volatile int g_StartOnce = 0;

auto FormRender(void) -> void {
    Hyperscanner::Main lpMain;
    lpMain.ShowDialog();

    return;
}

auto StartRenderThread(HANDLE& ThreadHandle) -> bool {
    ThreadHandle = CreateThread(nullptr, 0, reinterpret_cast<LPTHREAD_START_ROUTINE>
        (FormRender), nullptr, 0, nullptr);

    if (ThreadHandle)
    {
        return true;
    }

    return false;
}

auto StopRenderThread(HANDLE& ThreadHandle) -> bool {
    if (ThreadHandle) {
        if (TerminateThread(ThreadHandle, 0)) {
            CloseHandle(ThreadHandle);
            return true;
        }
    }

    return false;
}

HANDLE g_Thread = nullptr;

auto __stdcall DllMain(HMODULE hMod, DWORD dwReason, void* lpReserved) -> int {
    if (dwReason && !g_StartOnce) {
        StartRenderThread(g_Thread);
        ++g_StartOnce;
    }

    if (!dwReason) {
        StopRenderThread(g_Thread);
        FreeLibraryAndExitThread(hMod, 0);
    }

    return true;
}

来自documentation

You should never perform the following tasks from within DllMain:

~ Call CreateThread.

而且 FormRenderThreadProc 回调签名不匹配,其调用会导致堆栈损坏。我什至不会提到 CLR 的东西...