【问题标题】:Using extern functions depending on kernel32.dll with Mono使用依赖于 kernel32.dll 的外部函数和 Mono
【发布时间】:2020-04-24 09:19:52
【问题描述】:

我正在 GNU/Linux 上移植一个 C# 应用程序 (.NET Framework 4.6.1)。我已经使用Mono 来构建和运行它。该应用程序运行良好,除了某些部分。也就是说,当需要一些 DLL 导入时(user32.dllkernel32.dll),因为显然这些是 Windows 特定的,而 Mono 不包括它们。例如,在代码中,我有以下 extern 函数引用 kernel32.dll

[DllImport("kernel32.dll")]
static extern IntPtr OpenThread(ThreadAccess dwDesiredAccess,
  bool bInheritHandle, uint dwThreadId);

[DllImport("kernel32.dll")]
static extern uint SuspendThread(IntPtr hThread);

[DllImport("kernel32.dll")]
static extern int ResumeThread(IntPtr hThread);

[DllImport("kernel32.dll")]
static extern bool CloseHandle(IntPtr hObject);

[DllImport("kernel32.dll")]
static extern IntPtr OpenProcess(ProcessAccess dwDesiredAccess,
  bool bInheritHandle, int dwProcessId);

[DllImport("kernel32.dll")]
static extern bool ReadProcessMemory(IntPtr hProcess,
  UIntPtr lpBaseAddress, byte[] lpBuffer, IntPtr dwSize, ref int lpNumberOfBytesRead);

[DllImport("kernel32.dll", SetLastError = true)]
static extern bool WriteProcessMemory(IntPtr hProcess, UIntPtr lpBaseAddress,
  byte[] lpBuffer, IntPtr dwSize, ref int lpNumberOfBytesWritten);

[DllImport("kernel32.dll")]
static extern IntPtr VirtualQueryEx(IntPtr hProcess, IntPtr lpAddress,
  out MemoryBasicInformation lpBuffer, IntPtr dwLength);

当使用 Mono 调用这些方法之一时,我收到这样的错误(CloseHandle 的示例):

[ERROR] FATAL UNHANDLED EXCEPTION:
System.EntryPointNotFoundException: CloseHandle assembly:<unknown assembly> type:<unknown type> member:(null)
  at (wrapper managed-to-native) MyProject.Utilities.Kernel32NativeMethods.CloseHandle(intptr)
  at MyProject.Utilities.Kernel32NativeMethods.CloseProcess (System.IntPtr processHandle) [0x00001] in <38a03fe220d245f3b3d5e7486135e053>:0 
  at MyProject.Utilities.WindowsProcessRamIO.Dispose (System.Boolean disposing) [0x0003f] in <38a03fe220d245f3b3d5e7486135e053>:0 
  at MyProject.Utilities.WindowsProcessRamIO.Finalize () [0x00002] in <38a03fe220d245f3b3d5e7486135e053>:0

我了解错误(在 Mono 下无法调用本机方法),但我想知道是否有办法转换这些方法以避免依赖于外部 DLL,例如 kernel32.dll

我查看了PInvoke,但不幸的是,这些方法没有非托管替代品。

有没有办法重写这段代码以与 Mono 兼容?或者可能包含一些东西来重现丢失的 DLL 的行为?

【问题讨论】:

    标签: c# .net dll mono


    【解决方案1】:

    kernel32.dll 专用于 Windows,在其他平台上不可用。这些 API 仅限于 Windows。

    您需要重写代码以避免使用这些函数。查看课程System.Threading.ThreadDiagnostics.Process,也许他们有你需要的一切。

    【讨论】:

    • 感谢您的回答。但是因为这是extern 函数,我找不到这些函数是如何实现的,因为没有kernel32.dll 的源代码。你有什么主意吗? (我已经尝试过pinvoke.net)。
    • 在文档中查找它们。他们有很好的记录。
    • 我已经检查了 OpenProcess 的文档,例如 (docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/…),但我找不到如何在纯 C# 中执行此操作。我已将其定义为:return System.Diagnostics.Process.GetProcessById(dwProcessId).Handle;,但我很确定它不正确,否则我不知道如何使用其他参数(dwDesiredAccessbInheritHandle)。
    • 好吧,您可能需要其他平台上根本没有的东西。您需要提供更多详细信息。
    • 谢谢,我已经发布了另一个问题,其中包含我想要实现的最小完整示例:stackoverflow.com/questions/61438447/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-18
    • 2012-07-21
    • 1970-01-01
    • 2015-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多