У меня есть ситуация, когда я создаю временные файлы из Ruby в папке пользователя. Я использую Dir.mktmpdir()
для создания временной папки, в которую я помещаю свои файлы.
По какой-то причине эта функция дает мне короткое имя папки Windows, поэтому вместо, например. C:\Users\very long username\AppData\Local\Temp\20181018-5548
Я получаю что-то вроде C:\Users\VERYLO~1\AppData\Local\Temp\20181018-5548
. Это первопричина моей проблемы, но у меня сложилось впечатление, что я не могу это исправить, потому что мне приходится работать в среде, над которой у меня нет большого контроля (Ruby 2.0 и 2.2, встроенные в SketchUp). если быть точным). Это также ограничивает количество внешних библиотек Ruby, которые я могу разумно использовать.
Чтобы получить фактическое длинное имя папки, я вызывал функцию Win32 GetLongPathName()
через класс WIN32API
, и это было в значительной степени успешным.
Однако у меня возникают проблемы со специальными символами. Похоже, что буферы, которые я отправляю в Win32 API (а также возвращаемые буферы), должны иметь определенную кодировку, а строки Ruby - UTF-8 (или предполагают, что возвращаемые значения будут UTF-8). Я бы с радостью способствовал любым изменениям в кодировке, но я несколько запутался в том, какую кодировку выбрать. Я даже не уверен, используется ли расширенная версия Win32 API.
Есть кое-что, что добавляет странности и заставляет меня задуматься, может быть, я лаю не по тому дереву: используя международную и/или английскую версию Windows, я могу без проблем отправлять и получать все виды специальных символов в вызове Win32 API. . Однако, как только я использую другой языковой выпуск Windows (я пробовал бразильский португальский, но у нас были люди с ивритом, и некоторые восточноевропейские выпуски Windows также сообщают об этой проблеме), он перестает работать.
def self.get_long_win32_filename(short_name)
require 'Win32API'
max_path = 1024
long_name = " " * max_path
lfn_size = Win32API.new("kernel32", "GetLongPathName", ['P','P','L'],'L').call(short_name, long_name, max_path)
return (1..max_path).include?(lfn_size) ? long_name[0..lfn_size-1] : short_name
end
Вот код, который я использую:
Любая помощь в выяснении того, как подойти к проблеме кодирования при передаче строк в Win32 API и из него, очень ценится!
short_name = short_name.encode(Encoding::UTF_16)
, и это не помогло. - person Timm Dapper   schedule 18.10.2018