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;
}
You should never perform the following tasks from within DllMain
:
~ Call CreateThread
.
而且 FormRender
与 ThreadProc
回调签名不匹配,其调用会导致堆栈损坏。我什至不会提到 CLR 的东西...
所以我正在尝试用 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;
}
You should never perform the following tasks from within
DllMain
:~ Call
CreateThread
.
而且 FormRender
与 ThreadProc
回调签名不匹配,其调用会导致堆栈损坏。我什至不会提到 CLR 的东西...