Project

General

Profile

Bug #14406

File.expand_path doesn't expand tilde inside Windows home directory

Added by abotalov (Andrei Botalov) over 1 year ago. Updated over 1 year ago.

Status:
Rejected
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-core:85132]

Description

TMP environment variable on Windows is set to a name that contains a tilde. File.expand_path doesn't currently return an expanded name. I would expect it to do so as its documentation says:
"Converts a pathname to an absolute pathname."
"The given pathname may start with a “~”, which expands to the process owner's home directory"

Example on my system:

irb(main):085:0> File.expand_path(Dir.tmpdir)
=> "C:/Users/ANDREI~1/AppData/Local/Temp"
irb(main):086:0> File.absolute_path(Dir.tmpdir)
=> "C:/Users/ANDREI~1/AppData/Local/Temp"

History

Updated by Hanmac (Hans Mackowiak) over 1 year ago

you are wrong it means something different:

File.expand_path("~") #=> "C:/Users/h.mackowiak"

you thing are FAT paths which got that shortage because of "8.3 filename"
https://en.wikipedia.org/wiki/8.3_filename

ruby might not be able to do much about that

Updated by nobu (Nobuyoshi Nakada) over 1 year ago

  • Status changed from Open to Rejected
  • Description updated (diff)

abotalov (Andrei Botalov) wrote:

TMP environment variable on Windows is set to a name that contains a tilde.

"Containing" doesn't mean "starting with".

irb(main):085:0> File.expand_path(Dir.tmpdir)
=> "C:/Users/ANDREI~1/AppData/Local/Temp"
irb(main):086:0> File.absolute_path(Dir.tmpdir)
=> "C:/Users/ANDREI~1/AppData/Local/Temp"

These contain a tilde, but do not start with.

Updated by Hanmac (Hans Mackowiak) over 1 year ago

abotalov (Andrei Botalov):
you need to call GetLongPathName https://msdn.microsoft.com/en-us/library/windows/desktop/aa364980(v=vs.85).aspx
using win32api or fiddle

the win32api would look like that:

require "tmpdir"
def get_long_win32_filename(short_name)
    require 'win32api'
    win_func = Win32API.new("kernel32","GetLongPathName","PPL","L")
    buf = 0.chr * 256
    buf[0..short_name.length-1] = short_name
    win_func.call(short_name, buf, buf.length)
    return buf.split(0.chr).first
end
p get_long_win32_filename(Dir.tmpdir)

don't know how much complicated it would be with fiddle

Updated by davispuh (Dāvis Mosāns) over 1 year ago

I wrote a patch for this with #12656

Also available in: Atom PDF