Запуск приложения win32 с длинного пути

#windows #manifest #long-path

#Windows #манифест #длинный путь

Вопрос:

Включение поддержки длинного пути для моего приложения Я сделал следующее:

  1. Встроил longPathAware манифест в мое приложение с помощью mt.exe
  2. Убедитесь, что для LongPathsEnabled раздела реестра установлено значение 1

Мое приложение фактически начало работать с файлами, расположенными в папках с длинными путями, превышающими 260 предел, однако существует проблема.

Я не нашел способа запустить свое приложение, где папка с длинным путем является моим текущим рабочим каталогом. Я пытался использовать cmd , MSYS2 , CygWin , explorer

  1. cmd выдает следующую ошибку:

     The current directory is invalid.
      
  2. MSYS2 и CygWin оба выдают следующую ошибку:

      Error: Current working directory has a path longer than allowed for a Win32 working directory.
     Can't start native Windows application from here.
     bash: /c/myapp: File name too long
      
  3. explorer выполняет следующее:

    • Значок приложения становится пустым, как значок для файлов неизвестных типов или файлов без расширений
    • Двойной щелчок по приложению вообще ничего не делает

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

Итак, мой вопрос: есть ли способ преодолеть эту проблему / ограничение?

Я чувствую, что без работы с этим случаем поддержка всех длинных путей не имеет никакого смысла.

Комментарии:

1. SetCurrentDirectoryW работает с длинными путями, но длинный путь не может быть унаследован или установлен в качестве начального рабочего каталога процесса. CreateProcessW не поддерживает это для lpCurrentDirectory . Кроме того, необходимо передать длинный путь к исполняемому файлу lpApplicationName , который может быть относительным путем. Это не может быть передано только в, lpCommandLine потому что без lpApplicationName API всегда вызывает SearchPathW с MAX_PATH буфером (260), даже если в командной строке указан абсолютный путь.

2. Даже если CreateProcessW все пройдет успешно, инициализация процесса может завершиться ошибкой в некоторых сценариях (например, IPC контекста активации SxS между процессом и сервером сеансов, csrss.exe ). И программа должна быть внимательна, чтобы избежать попыток создать дочерний процесс с рабочим каталогом в качестве длинного пути, включая неявное наследование рабочего каталога (т. Е. lpCurrentDirectory передается как NULL ).

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

4. @ErykSun Спасибо за ваши комментарии. У меня есть вопрос. Что именно использует CreateProcessW ? Что именно запускает мой процесс в случае, если я вызываю свой .exe непосредственно из командной строки?

5. В случае cmd.exe он вызывает CreateProcessW непосредственно при запуске исполняемого файла, с или без start . Он реализует свой собственный поиск исполняемого файла на основе PATH и PATHEXT , и, таким образом, он всегда передает путь к исполняемому файлу lpApplicationName вместо того, чтобы полагаться на CreateProcessW для его поиска. Но он также пытается наследовать текущий каталог в lpCurrentDirectory , который не будет работать для длинного пути. start Команда может переопределить это с помощью явного каталога через /D или просто запустить исполняемый файл с относительным путем из другого рабочего каталога.