Почему Windows не позволяет WinSock быть запущенным при исполнении роли другого пользователя

Проблема в том, что если никто не подписывается на событие, оно является нулевым. И вы не можете ссылаться на ноль. На ум приходят три подхода:

  • проверка на ноль (см. Ниже)
  • добавить обработчик «ничего не делать»: public event EventHandler MyEvent = delegate {};
  • использовать метод расширения ( см. ниже)

При проверке на нулевое значение, чтобы быть потокобезопасным, вы должны в теории сначала захватить ссылку на делегат (в случае, если она изменяется между проверкой и вызовом) :

protected virtual void OnMyEvent() {
    EventHandler handler = MyEvent;
    if(handler != null) handler(this, EventArgs.Empty);
}

Методы расширения имеют необычное свойство - они могут вызываться в нулевых экземплярах ...

    public static void SafeInvoke(this EventHandler handler, object sender)
    {
        if (handler != null) handler(sender, EventArgs.Empty);
    }
    public static void SafeInvoke<T>(this EventHandler<T> handler,
        object sender, T args) where T : EventArgs
    {
        if (handler != null) handler(sender, args);
    }

, затем вы можете позвонить:

MyEvent.SafeInvoke(this);

, и он является как нулевым (через проверку), так и поточным (прочитав ссылку только один раз).

6
задан MD XF 22 March 2017 в 18:25
поделиться

5 ответов

У вас должен быть статус "Действовать как рабочий"

3
ответ дан 9 December 2019 в 20:45
поделиться

Возможно, пользователю, с которым вы выполняли процесс, не разрешено использовать стек TCP / IP?

Попробуйте запустить приложение от имени администратора, который не является вашей учетной записью.

3
ответ дан 9 December 2019 в 20:45
поделиться

Запустите на нем Process Monitor и посмотрите, не удается ли ему найти файл или раздел реестра. Возможно, профиль олицетворенного пользователя не загружен и Winsock (или поставщик услуг, который он пытается загрузить) что-то там ищет.

0
ответ дан 9 December 2019 в 20:45
поделиться

Возможно, у вас нет необходимых прав для запуска процесса от имени другого пользователя. Попробуйте получить дескриптор токена доступа с помощью вызова OpenProcessToken и добавьте SE_IMPERSONATE_NAME с помощью вызова AdjustTokenPrivileges, а затем вызовите CreateProcessAsUserW. Я сам не пробовал.
Фрагмент кода на Python для выполнения чего-то подобного с вызовами win32

1
ответ дан 9 December 2019 в 20:45
поделиться

Всегда запускайте WinSock в верхней части основного и оставляйте его включенным. Необходимость запустить WinSock является архитектурной случайностью и больше не имеет отношения к какой-либо проблемной области.

0
ответ дан 9 December 2019 в 20:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: