Obter pasta especial para diferentes usuários sem credenciais

Estou escrevendo um desinstalador e, como parte do processo, quero limpar caches, arquivos temporários etc. para todos os usuários locais. O aplicativo será executado elevado para que isso funcione.

Os arquivos que estou procurando são encontrados em pastas especiais, comoAppData\Local, então eu preciso dos caminhos. Para o usuário conectado no momento, isso é trivial a ver comEnvironment.GetFolderPath. No entanto, isso não funcionará para um usuário diferente.

De acordo com o sourcesource.microsoft.com,GetFolderPath finalmente chamaSHGetFolderPath, que por sua vez envolveSHGetKnownFolderPath. Ambas as APIs do Win32 têm um opcionalhToken parâmetro que me permite especificar um token de conta.

E, de fato, isso funcionará:

private static string GetFolderPath(Guid knownfolderid, string user, string domain, string password)
{
    const int LOGON32_PROVIDER_DEFAULT = 0;
    const int LOGON32_LOGON_INTERACTIVE = 2;

    SafeTokenHandle safeTokenHandle;

    if (!LogonUser(user, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, out safeTokenHandle))
        throw new System.Security.Authentication.InvalidCredentialException();

    IntPtr pPath;
    SHGetKnownFolderPath(knownfolderid,
                         0,
                         safeTokenHandle.DangerousGetHandle(),
                         out pPath);
    string result = System.Runtime.InteropServices.Marshal.PtrToStringUni(pPath);
    System.Runtime.InteropServices.Marshal.FreeCoTaskMem(pPath);

    return result;
}

… Mas é impraticável para meus usos, é claro - não quero que o administrador que desinstala algo precise saber e fornecer cada nome de usuário e senha.

Assim:

existe uma maneira de obter um token de acesso apropriadosem precisando conhecer as credenciais do usuário?na falta disso, existe uma maneira diferente de realizar meu objetivo? Lendo as informações do registroparece inseguro, assim como codificar os nomes das pastas, é claro.

questionAnswers(1)

yourAnswerToTheQuestion