Как получить фактический путь к файлу в Vista с UAC?

Я вызываю CreateFile (), чтобы создать файл в каталоге Program Data. Я использую SHGetSpecialFolderPath (), чтобы получить имя каталога.

У меня есть пользователь Vista, для которого CreateFile () возвращает ошибку 5 (доступ запрещен). Было бы полезно, если бы я знал, где CreateFile () на самом деле пытается создать файл, чтобы мы могли проверить его права доступа к папке. Проблема с Vista (UAC) в том, что она не пытается создать файл в каталоге, который я передал. Он также может находиться в каталоге VirtualStore. Дополнительным источником путаницы является то, что этот пользователь - немец, и хотя SHGetSpecialFolderPath () возвращает в качестве пути «C: \ Program Data \ blah blah», я не думаю, что на самом деле путь находится именно там. Я думаю, что в немецкой Vista для обозначения программных данных используется немецкое слово. Я хотел бы сообщить пользователю: «Это точный путь, по которому мы пытаемся создать файл. Проверьте свои права доступа к этой папке».

Я знаю, что вы можете получить путь из дескриптора открытого файла, но в этом случае CreateFile () не работает, поэтому у меня нет открытого дескриптора. Как я могу заставить Vista сообщать мне фактический путь, по которому она пытается создать файл?


person mhenry1384    schedule 05.01.2009    source источник
comment
Что произойдет, если пользователь работает в Windows XP и является стандартным пользователем? Тогда CSIDL_COMMON_APPDATA указывал на C:\Documents & Settings\All Users, и ваш CreateFile тоже потерпит неудачу. (другими словами, сбой характерен не только для Vista, а для вашего приложения. Вы не должны писать в места, где вы тоже не должны писать)   -  person Ian Boyd    schedule 24.05.2011
comment
к сведению: SHGetSpecialFolderPath устарел с Windows 2000; используйте вместо этого SHGetFolderPath. Новые приложения могут использовать SHGetKnownFolderPath.   -  person Ian Boyd    schedule 24.05.2011


Ответы (3)


Запустите Process Monitor и посмотрите, что он делает: http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx

person nobody    schedule 05.01.2009
comment
Это круто, я об этом не подумал. Монитор процессов показывает реальный каталог. К сожалению, запуск Process Monitor - это, вероятно, больше, чем может справиться обычный пользователь. Тем не менее, хорошая идея. - person mhenry1384; 05.01.2009
comment
Я надеялся найти способ сделать это из моей программы, но, поскольку никто не знает лучшего ответа, я думаю, что это победитель. - person mhenry1384; 06.01.2009

Если с UAC используемые пути не те, которые вы хотите, то действует перенаправление. Чтобы убедиться, что перенаправление не происходит, добавьте манифест для вашего приложения, который указывает Vista, что ваше приложение правильно закодировано и осведомлено об ограничениях доступа (т. Е. Вы не пишете, например, в HKLM или в папку программ, если вашему приложению не требуются права администратора для запуска).

Но ваше приложение должно иметь возможность писать в папку APPDATA (если это то, что вы действительно используете).

Убедитесь, что вы используете CSIDL_APPDATA, а не CSIDL_COMMON_APPDATA (последний доступен только с правами администратора).

Чтобы найти реальный путь (тот, который вы ожидаете), попросите пользователя ввести% APPDATA% в панели проводника (или нажмите Windows + R, затем введите% APPDATA%, введите). Это откроет проводник в этой папке.

person Stefan    schedule 05.01.2009
comment
Мне действительно нужно использовать CSIDL_COMMON_APPDATA, потому что этот конкретный файл должен быть доступен всем пользователям. Но CSIDL_COMMON_APPDATA не требует прав администратора. Любой пользователь может писать в него, хотя любой файл, который вы создаете, не может быть прочитан другим пользователем, если он не создан с разрешением всем доступ. - person mhenry1384; 05.01.2009
comment
Нет, CSIDL_COMMON_APPDATA требует прав администратора. Это место обычно указывается установщиками, а не самими приложениями. Было бы угрозой безопасности, если бы один пользователь мог установить параметры или, что еще хуже, заменить двоичные файлы, которые затем должен будет использовать другой пользователь. - person Stefan; 05.01.2009
comment
Из msdn.microsoft.com/en-us/library/ms995853.aspx: CSIDL_COMMON_APPDATA Эта папка должна использоваться для данных приложения, не зависящих от пользователя. [...]. По умолчанию это место доступно только для чтения для обычных (не администраторов, не обладающих полномочиями) пользователей. - person Stefan; 05.01.2009
comment
Вместо этого вы можете попробовать использовать CSIDL_COMMON_DOCUMENTS. - person Stefan; 05.01.2009
comment
MSDN: если приложение требует, чтобы обычные пользователи имели доступ на запись в подкаталог приложения CSIDL_COMMON_APPDATA, тогда приложение должно явно изменить безопасность этого подкаталога во время установки приложения. Я не писал установщик, должно быть, мы этим и занимаемся. - person mhenry1384; 06.01.2009
comment
Я считаю, что мы не используем CSIDL_COMMON_DOCUMENTS, потому что это файлы, с которыми пользователь не должен связываться или удалять, и было определено, что общая папка документов была слишком простой для доступа пользователей. - person mhenry1384; 06.01.2009
comment
Документация Microsoft неверна. Я только что протестировал его с помощью Vista SP1, и даже пользователи без прав администратора могут создавать и записывать папки и каталоги в папку c: \ ProgramData (CSIDL_COMMON_APPDATA). Я не знаю, почему в документации утверждается иное. - person mhenry1384; 12.01.2009
comment
CSIDL_COMMON_APPDATA указывает на все пользователи \ данные приложения, а не на c: \ programdata. - person Stefan; 12.01.2009

Насколько я понимаю, Vista использует ProgramData для записи файлов, которые пытались записать в C: \ Program Files, но потерпели неудачу, поскольку, если вы не запускаете приложение от имени администратора, вы не можете писать внутри программных файлов. Возможно, вам стоит попробовать сохранить файлы в папке AppData под текущим пользователем.

person Alex    schedule 05.01.2009
comment
Не совсем так, папка Program Data возвращает папку, к которой имеют доступ все пользователи (CSIDL_COMMON_APPDATA). И этот конкретный файл должен быть доступен всем пользователям. Я бы хотел, чтобы это было не так. - person mhenry1384; 05.01.2009