Pergunta

Eu tenho uma dll de monitor de porta, que instalo chamando a função AddMonitor do spooler.Mas quando desejo desinstalar este monitor, a função DeleteMonitor retorna o código de erro 3008 - "O monitor de impressão especificado está em uso no momento".Como posso liberar a dll do meu monitor?



    [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());
        }
    }

Foi útil?

Solução

Você não poderá excluir um monitor de porta por meio da chamada DeleteMonitor se houver um ou mais objetos de impressora usando atualmente uma porta desse tipo.

Isso deixa você com várias opções:

  • Troque a porta de todas as impressoras afetadas por outra porta.(Melhor usar algo como LPT1:já que está sempre lá).
  • Exclua todas as impressoras usando a porta.
  • Pare o serviço de spooler e remova as entradas apropriadas do registro (HKLM\SYSTEM\CurrentControlSet\Control\Print\Monitors) e reinicie o spooler.Isso deixará as impressoras afetadas lá, mas ficarão inutilizáveis.
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top