1

我有一个端口监视器 dll,我通过调用 spooler 的 AddMonitor 函数来安装它。但是当我想卸载此监视器时,DeleteMonitor 函数返回错误代码 3008 -“指定的打印监视器当前正在使用中”。如何释放我的监视器 dll?



    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    private class MONITOR_INFO_2
    {
        [MarshalAs(UnmanagedType.LPStr)]
        public string pName;
        [MarshalAs(UnmanagedType.LPStr)]
        public string pEnvironment;
        [MarshalAs(UnmanagedType.LPStr)]
        public string pDLLName;
    }

    [DllImport("winspool.Drv", EntryPoint = "AddMonitorA", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
    private static extern bool AddMonitor(
    [MarshalAs(UnmanagedType.LPStr)] string Name,
    Int32 Level,
    [In, MarshalAs(UnmanagedType.LPStruct)] MONITOR_INFO_2 mi2);

    [DllImport("winspool.Drv", EntryPoint = "DeleteMonitorA", SetLastError = true,  ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
    private static extern bool DeleteMonitor(
    [MarshalAs(UnmanagedType.LPStr)] string pNullServerName,
    [MarshalAs(UnmanagedType.LPStr)] string pNullEnvironment,
    [MarshalAs(UnmanagedType.LPStr)] string MonitorName);

    private unsafe void InstallMonitor(string monitorName, string dllName)
    {
        MONITOR_INFO_2 mi2 = new MONITOR_INFO_2();
        mi2.pName = monitorName;
        mi2.pEnvironment = null;
        mi2.pDLLName = dllName;

        try
        {
            bool bRet = AddMonitor(null, 2, mi2);
            if (!bRet)
                throw new Win32Exception(Marshal.GetLastWin32Error());
        }
        catch (Exception e)
        {
            if (!DeleteMonitor(null, null, monitorName))
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }
            bRet = AddMonitor(null, 2, mi2);
            if (!bRet)
                throw new Win32Exception(Marshal.GetLastWin32Error());
        }
    }

4

1 回答 1

0

如果有一个或多个打印机对象当前使用该类型的端口,您将无法通过 DeleteMonitor 调用删除端口监视器。

这为您提供了多种选择:

  • 将所有受影响的打印机的端口交换到另一个端口。(最好使用 LPT1 之类的东西:因为它总是在那里)。
  • 删除所有使用该端口的打印机。
  • 停止后台处理程序服务并从注册表中删除相应的条目 (HKLM\SYSTEM\CurrentControlSet\Control\Print\Monitors),然后重新启动后台处理程序。这会将受影响的打印机留在那里,但它们将无法使用。
于 2012-04-02T22:42:55.097 回答