虚拟打印机端口监视器安装

时间:2012-02-22 00:23:55

标签: printing virtual monitor spooler

我有一个端口监视器dll,我通过调用假脱机程序的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());
        }
    }

1 个答案:

答案 0 :(得分:0)

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

这为您提供了几个选项:

  • 将所有受影响的打印机的端口交换到另一个端口。 (最好使用像LPT1这样的东西:因为它总是在那里)。
  • 使用端口删除所有打印机。
  • 停止假脱机程序服务并从注册表中删除相应的条目(HKLM \ SYSTEM \ CurrentControlSet \ Control \ Print \ Monitors),然后重新启动假脱机程序。这将使受影响的打印机停留在那里,但它们将无法使用。