Michael Haephrati Ответов: 2

Как найти общий путь из службы windows


Настольные приложения могут вызывать SHGetKnownFolderPath[^] чтобы найти путь к общим папкам, таким как "документы" и "загрузки".

Когда речь заходит о службе Windows, поскольку службы выполняются изолированно в сеансе 0, вызов функции SHGetKnownFolderPath() завершится ошибкой.

Как я могу найти общий путь текущего пользователя, вошедшего в систему, или как я могу вызвать SHGetKnownFolderPath() из службы Windows?

Что я уже пробовал:

LPWSTR wszPath = NULL;
HRESULT hr;

hr = SHGetKnownFolderPath(FOLDERID_Documents, KF_FLAG_CREATE, NULL, &wszPath);

2 Ответов

Рейтинг:
2

Dave Kreskowiak

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

Кроме того, вы предполагаете, что Windows позволяет только одному пользователю войти в консоль. Но это не так. Вы можете иметь несколько пользователей, вошедших в систему одновременно. Черт возьми, вы не можете позволить пользователям войти в машину!

Как ваш код должен знать, для какого пользователя получить путь?

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

Похоже, вы написали приложение как неправильный тип приложения. То, что вы должны были сделать, это написать обычное приложение и запустить его из реестра Run key int he. Таким образом, приложение запускается только тогда, когда пользователь входит в систему, и будет работать от имени пользователя, который вошел в систему. Затем приложение будет иметь доступ к папкам профилей пользователей, как и любое другое...


Michael Haephrati

Прямо сейчас, из-за сценариев, которые вы перечисляете здесь, SHGetKnownFolderPath() потерпит неудачу и даже вызовет сбой в приложениях, используемых как для настольных приложений, так и для службы Windows (например, статическая библиотека, используемая обоими типами). Моим идеальным ответом была бы функция wraparound, которая вызовет SHGetKnownFolderPath() и, если возможно, вернет правильный путь, скажем, когда служба Windows запущена, и есть один пользователь, вошедший в систему), а если нет, то вернет nullptr или что-то подобное...

Dave Kreskowiak

Эта функция будет работать для вас только в том случае, если вы получите копию маркера безопасности пользователя, который вошел в систему. Учитывая, что ваша служба не сможет запросить у пользователя его учетные данные, чтобы он мог создать токен и выдать себя за пользователя, вам будет очень трудно получить этот токен.

Удачи тебе с этим.

Я уже говорил вам, что если вы взаимодействуете с пользователем или его профилем вообще, вам не следует писать приложение-службу для этого.

Michael Haephrati

Спасибо, Дэйв.

Рейтинг:
0

KarstenK

Это запрещено из соображений безопасности. Возможные обходные пути-это доступ к какой-то общей папке.

Еще одно не столь замечательное решение состоит в том, чтобы использовать LogonAsUser api для получения некоторых прав доступа. Вам нужно запустить другой процесс/поток, который делает необходимые вещи. Проблема заключается в том, как учетные данные поступают в службу, например, какая-то запись в реестре (во время установки) или каким-то другим способом.