0

伙计们,我被困在我的应用程序的功能性桌带实现的最后一部分,

就上下文而言,我目前正在运行一个包含 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 上。

4

0 回答 0