我有 C++ 库,可用于身份验证目的。它有一些通过客户软件调用的导出方法。我的目标是创建可以在独立于应用程序的单独进程中显示对话框的函数。
我这样做的目的是,当检测到某些篡改时,我想立即终止应用程序,但给用户留下某种通知。我还有远程会话终止等功能,当应用程序所有者可以终止客户端会话时,许可证过期的情况也是如此。我不想只是终止应用程序,我想给用户留下消息
我读到了一些解决方案,但我发现每个解决方案都存在问题:
创建单独的应用程序,它将生成 DialogBox 并作为新进程运行: 我不想发送额外的 exe 文件,它必须是单个本机库
使用powershell和ShellExecute 我担心 powershell 可能在某些计算机上被阻止或需要管理员权限。我有有效的代码
Add-Type @"
using System;
using System.Runtime.InteropServices;
public class NativeMethods {
[DllImport("user32.dll", CharSet=CharSet.Unicode)]
public static extern int MessageBox(IntPtr hWnd, string text, string caption, int options);
}
"@
[NativeMethods]::MessageBox([IntPtr]::Zero, "Wykryto naruszenie", "Ał", (0x10 -bor 0x1000))
我应该使用什么解决方案来确保兼容性?或者也许有比这些更好的解决方案?
从 C++ DLL 中,我将导出一个函数来显示对话框(您可以为此使用 Win32 API
MessageBox
),并通过使用适当的参数调用 rundll32.exe
来执行它。该实用程序通常始终存在,并且永远不应该被禁用。Rundll32.exe shell32.dll,ShellAbout
您的函数将如下所示(请随意根据您的需要进行调整):
extern "C" __declspec(dllexport) void CALLBACK ShowMessage(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) {
MessageBox(
nullptr, // No parent window
"This is a message box!",
"Dialog from DLL",
MB_OK | MB_ICONINFORMATION
);
}
这里的关键部分是
CALLBACK
调用约定和“C”外部链接。 不要忘记它们。
然后,您可以从代码中的任何位置调用此函数来生成一个显示消息框的新进程:
void ExecuteRundll32(const std::string& functionName) {
char dllPath[MAX_PATH] = {0};
// Get the full path of the current DLL
if (!GetModuleFileNameA((HINSTANCE)&__ImageBase, dllPath, MAX_PATH)) {
std::cerr << "Failed to get DLL path. Error: " << GetLastError() << std::endl;
return;
}
// Construct the rundll32 command
std::string command = "rundll32.exe \"";
command += dllPath;
command += "\",";
command += functionName;
// Execute the command using CreateProcessA
STARTUPINFOA si = { sizeof(STARTUPINFOA) };
PROCESS_INFORMATION pi = { 0 };
if (!CreateProcessA(nullptr, command.data(), nullptr, nullptr, FALSE, 0, nullptr, nullptr, &si, &pi)) {
std::cerr << "Failed to execute rundll32. Error: " << GetLastError() << std::endl;
} else {
// Close unused handles to prevent resource leaks
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
}
您可以使用提供的合适函数来调用它:
ExecuteRundll32(ShowMessage);
这应该可以解决问题。