Установка монитора порта виртуального принтера - PullRequest
1 голос
/ 22 февраля 2012

У меня есть 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 голосов
/ 03 апреля 2012

Вы не сможете удалить монитор порта с помощью вызова DeleteMonitor, если в данный момент один или несколько объектов принтера используют порт этого типа.

Это оставляет вам несколько вариантов:

  • Поменять порт всех задействованных принтеров на другой порт. (Лучше всего использовать что-то вроде LPT1: так как оно всегда там).
  • Удалить все принтеры, используя порт.
  • Остановите службу спулера и удалите соответствующие записи из реестра (HKLM \ SYSTEM \ CurrentControlSet \ Control \ Print \ Monitors), затем перезапустите спулер. Это оставит затронутые принтеры там, но они будут непригодны для использования.
...