伙计们,我被困在我的应用程序的功能性桌带实现的最后一部分,
就上下文而言,我目前正在运行一个包含 2 个项目的 Visual Studio 解决方案,一个是 c++deskband dll,另一个是一个简单的 c# 控制台程序。DeskBand 代码是Microsoft 的 DeskBand 示例
目前,我可以在控制台应用程序运行时通过使用 GetProcAddress() 调用“DllRegisterServer”来注册 dll。在此之后,我只需右键单击任务栏并启用已注册的桌带。我的问题来自这里,
注册后,假设 Deskband 实现中的 OnPaint 事件绘制了一个名为“Hello world”的文本变量,我要做的只是将一个字符串从 c# 发送到正在运行的 dll 并使其绘制为“从 c# 发送”。
寄存器类:
public class Registrar
{
private IntPtr hLib;
[DllImport("kernel32.dll", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
internal static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
[DllImport("kernel32.dll", SetLastError = true)]
internal static extern IntPtr LoadLibrary(string lpFileName);
[DllImport("kernel32.dll", SetLastError = true)]
internal static extern bool FreeLibrary(IntPtr hModule);
internal delegate int PointerToMethodInvoker();
public Registrar(string filePath)
{
hLib = LoadLibrary(filePath);
if (IntPtr.Zero == hLib)
{
int errno = Marshal.GetLastWin32Error();
throw new Win32Exception(errno, "Failed to load library.");
}
}
public void RegisterComDLL()
{
CallPointerMethod("DllRegisterServer");
}
public void UnRegisterComDLL()
{
CallPointerMethod("DllUnregisterServer");
}
private void CallPointerMethod(string methodName)
{
IntPtr dllEntryPoint = GetProcAddress(hLib, methodName);
if (IntPtr.Zero == dllEntryPoint)
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
PointerToMethodInvoker drs =
(PointerToMethodInvoker)Marshal.GetDelegateForFunctionPointer(dllEntryPoint,
typeof(PointerToMethodInvoker));
drs();
}
public void FreeLib()
{
if (IntPtr.Zero != hLib)
{
FreeLibrary(hLib);
hLib = IntPtr.Zero;
}
}
}
简单的控制台程序:
static void Main(string[] args)
{
Console.WriteLine("Start");
Registrar reg = new Registrar("DeskBandDLL.dll");
if (reg != null)
{
reg.RegisterComDLL();
//send data to the registered dll to start painting new text
Console.ReadLine();
reg.UnRegisterComDLL();
reg.FreeLib();
}
}
顺便说一句,我知道微软在 win11 中停止了桌带,但我真的想只为 win10 平台实现这个功能,我觉得我快完成这个了。
如果您需要完整的代码进行说明,我可以将其托管在 GitHub 上。