Как проверить, запускается ли приложение из \program files\
Есть ли надежный способ проверить, запущено ли приложение из-под файлов программы?
Если пользователь устанавливает приложение для программирования файлов на локальном компьютере, нам нужно поместить записываемые файлы в другое место, чтобы избежать виртуализации в Vista и Win7. Однако при установке на сетевой диск мы хотим сохранить эти файлы вместе с установкой для общего доступа пользователей.
Сегодня мы делаем сравнение строк между путем запуска и CSIDL_PROGRAM_FILES
, но что-то говорит мне, что это очень ненадежный метод.
Любое умное решение там? Есть ли IsRunningFromProtectedFolder() -api, о котором я не знаю? Есть ли какие-либо другие папки, вызывающие те же проблемы, что и программные файлы?
3 ответа
Это не очень хорошая идея, поскольку пользователь может установить его там, где он хочет, и тогда проверка может завершиться неудачей. Вместо этого установите флажок, когда пользователь устанавливает приложение, решая, установлено ли оно локально или на сервере.
Мы разрешаем нашим пользователям устанавливать в любом месте...
Если пользователь выбрал значение по умолчанию и установлен в Program Files, мы предполагаем, что нам нужно писать в Documents and Settings/Users. В противном случае мы записываем наши данные в папку в каталоге, в котором находится программное обеспечение. Это, конечно, может по-прежнему вызывать проблемы, и установка действительно позволяет людям выбирать другое расположение данных, если они предпочитают не использовать значение по умолчанию.
Кроме того, это простое изменение ini-файла и копия для перемещения данных.
При запуске мы определяем, находимся ли мы в каталоге Program Files, сравнивая значение, которое мы получаем из SHGetFolderPath(CSIDL_PROGRAM_FILES), с началом пути, в котором находится исполняемый файл.
Как вы, я также обнаружил проблемы, связанные с виртуализацией папок UAC. Я предлагаю обходной путь, похоже, он должен работать.
Это исходит из предположения, что процессы с повышенными правами всегда используют оригинальные копии, а не виртуализированные (CMIIW). Также я предполагаю, что ваша установка была выполнена с повышенными правами.
Идея состоит в том, чтобы создать "общий" процесс (без повышенных прав, унаследованный), который должен запустить ваш основной установщик. Этот процесс создаст имя файла в выбранной пользователем папке с именем и содержимым, которые знают обе ваши программы (например, test73819704.bin). Если папка виртуализирована, этот файл должен появиться в пользовательском VirtualStore и НЕ ДОЛЖЕН в оригинальном (с точки зрения и привилегий установщика).
Таким образом, для выбранного C:\Program_Files_But_Not_Ne обязательно и Process-1 (повышенный)
- Процесс-1 гарантирует, что нет файла C:\Program_Files_But_Not_Necessually\test73819704.bin
- Запускает Процесс-2 без подъема
- Процесс-2 создает C:\Program_Files_But_Not_Necessually\test73819704.bin и проверяет, действительно ли он существует. Если он существует, он вернется с хорошим кодом возврата, в противном случае - с ошибкой.
- Процесс-1 ожидает Процесс-2 и анализирует результат. Если это хорошо, проверяет C:\Program_Files_But_Not_Necessually\test73819704.bin, если он существует, перейдите к "Бинго! Виртуализация не произошла", если не существует, "Плохо, давайте найдем другое место хранения". Если код из Process-2 является "неудачным", покажите пользователю сообщение об ошибке.
К сожалению, я не смог проверить это прямо сейчас, но я думаю, что это должно сработать, и в этом есть логика, с Process-2 вы просто эмулируете поведение своей основной программы)