Задать вопрос
  • Слетает принтер по умолчанию при отключении RDP-сеанса Win Server 2019. Как исправить?

    @EgorL
    Сделал как написано в решении. Вручную работает, но
    почему-то задания запускаются от имени пользователя, чей профиль был создан последним.

    UPD: Нашёл решение основной темы

    Добавить следующий ключ на RD-Сервера:
    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Providers\Client Side Rendering Print Provider
    REG_DWORD: RemovePrintersAtLogoff
    VALUE: 0
    Это предотвратит удаление пользовательских принтеров при логоффе/отключении и не даст забыть принтер по-умолчанию.
    После, для скорейшего эффекта, необходимо корректно завершить сеанс пользователя хотя бы один раз.

    Проблема мне видится в рассинхроне задач восстановления пользовательских принтеров и восстановлении принтера по-умолчанию.
    Ответ написан
    4 комментария
  • Слетает принтер по умолчанию при отключении RDP-сеанса Win Server 2019. Как исправить?

    @ZardoZAntony
    программист, сис. админ
    Такая же проблема.
    Похоже Win Server 2019 не умеет запоминать поставленными по умолчнию расшаренные удаленные принтеры. Хотя с сетевыми у него проблем нет, т.к. он их видит как локальные.

    Думал поможет старое доброе подключение через создание LocalPort. Но у меня принтер так не печатает, выдает ошибку при печати. "Ошибка 87. Неверный параметр."

    В общем костылями сделал то, что нужно:

    1. В планировщике делаем задачу на экспорт ключа реестра с настройками принтера по умолчанию. Сделано так, чтобы не дергались тригеры смены принтера по умолчнию.
    reg export "HKCU\Software\Microsoft\Windows NT\CurrentVersion\Windows" %USERPROFILE%\defprinter.reg /y


    Фильтр событий ручной. Тут я цепляюсь к событию журнала смены принтера по умолчанию. Смена принтера при отключении от сеанса происходит так, как будто ранее ны было выбрано принтеров по умолчанию. За это я и зацепился. OldDefaultPrinter становится равным прочерку, поэтому его исключим, а остальные смены принтеров будем ловить.
    <QueryList>
      <Query Id="0" Path="Microsoft-Windows-PrintService/Admin">
        <Select Path="Microsoft-Windows-PrintService/Admin">*[System[(Level=4 or Level=0) and (EventID=823)] ]
    </Select>
        <Suppress Path="Microsoft-Windows-PrintService/Admin">
    *[UserData[ChangingDefaultPrinter[(OldDefaultPrinter='-')]]]
    </Suppress>
      </Query>
    </QueryList>


    Теперь при смене принтера в домашней папке пользователя лежит reg файл с текущим принтером по умолчанию.

    2. Создаем второю задачу в планировщике для импорта этого файла в реестр при подключении и переподключении пользователя
    reg import %USERPROFILE%\defprinter.reg
    Тригеры 2 штуки. Это событие логина пользователя и событие переподключения к сеансу.
    Журнал
    Microsoft-Windows-TerminalServices-LocalSessionManager/Operational
    События 21 и 25

    Задачи в планировщике от имени группы Пользователи
    Ответ написан
    Комментировать
  • Как указать тайпхинт для возврата наследников?

    petushok55
    @petushok55
    Обучаюсь на практике.
    1) Чтобы исправить проблему с автодополнением, можно указать тип переменной `cls` как `Type[AbstractCls]`, чтобы IDE знала, что она является экземпляром класса `AbstractCls`. Это можно сделать следующим образом:

    cls: Type[AbstractCls] = AbstractCls.get_cls()

    Теперь IDE будет корректно подсказывать методы и атрибуты класса `AbstractCls`.

    2) К сожалению, автоматические подсказки для методов класса `A` не будут появляться без переопределения `get_cls()` в самом классе `A`. Это связано с тем, что статические методы и методы класса не наследуются от родительского класса, и IDE не сможет автоматически определить, какие методы доступны для экземпляров класса `A`. Поэтому, чтобы иметь автодополнение для методов класса `A`, необходимо переопределить `get_cls()` в классе `A`, как вы уже указали в комментарии в коде.

    @classmethod
    def get_cls(cls) -> Type['A']:
        return super().get_cls()


    Теперь IDE будет предоставлять автодополнение для методов класса `A` при использовании переменной `o`.
    Ответ написан
    Комментировать