Small library file? no
Library method? yes
use Win32::API;
my $GetShortPath = new Win32::API ( "kernel32", "GetShortPathName", ['
+P','P','N'], 'N' );
my $len = 100;
my $short = (' ' x $len);
my $long = 'c:\\program files\\microsoft office\\';
my $size = $GetShortPath->Call($long, $short, $len);
print substr($short,0,$size) . "\n";
That is probably the safest method if all versions of
windows use the same function name for it, I've only got
Win98 to test it on so I'm not sure what the NTs do.
Update: Okay so it is avalible in one module. I
thought it might be, it just didn't jump out at me. | [reply] [d/l] |
This functionality is built into the Win32 module which is packaged in the ActiveState dist of perl. All you need to do is this:
use Win32;
my $long = 'c:\\program files\\microsoft office\\';
my $short = Win32::GetShortPathName($long);
print $short;
There is also a Win32::GetLongPathName(PATHNAME) function which does the reverse.
Also worth looking at is Jenda's Pages. He has a bunch of other Win32 "File Related" modules which are quite useful, one of which is Win32::AbsPath, another is Win32::FileOp.
$code or die
Using perl at
The Spiders Web | [reply] [d/l] |
On Windows NT, the option to create short <acronym title="Demented Operating System">DOS</acronym>
names for files can be turned off (in fact it's considered a security issue: on a web server you can request
"mylong~1.asp" instead of "mylongfilename.asp" and, if certain hotfixes or service packs are not installed,
get the raw source code or bypass restrictions).
| [reply] |
I think I'll take a look at Win32::API anyway, because there are probably lots of things you can do with it that aren't covered by any Win32 modules. How do you find out what API calls you can use and what format they require? I suppose we have to trudge round the MS site to find clues?
$code or die
Using perl at
The Spiders Web
| [reply] |
Please check out FFI and C::Dynalib as well. They are not restricted to working on just Win32 and seem to have cleaner designs (though the APIs could use the addition of some helper functions to make things simpler).
Documentation of many APIs in Microsoft DLLs can be found by downloading the SDK (Software Developers' Kit) from Microsoft or buying a compiler. You might be surprised how many APIs are already available from Perl via modules.
-
tye
(but my friends call me "Tye")
| [reply] |
my $path = "C:\\Program Files\\Internet Explorer\\";
my @tokens = split(/\\/, $path);
foreach(@tokens) {
next unless length $_ > 8;
s/\s//g; # remove whitespace
$_ = substr($_, 0, 6) . '~1';
}
$path = join("\\", @tokens);
Although the following problems immediately become apparent:
- If there's more than one file with the same first six
characters it will need to determine whether to append ~1 or
~2 or ~3, etc.
- It will totally annihilate directories (and files, if the
path is direct) with an extension. For example, the Win32 naming schema allows you define files and directories like "My Stuff For School.January-2001" etc. I forget exactly what the new X.Y limit is (as opposed to 8.3) but it's there. If you have an extension that is greater than 3 characters, that somehow affects the appended number to the root filename. So the above might become "MYSTUF~2.JAN" if you already had a "My Stuff For School.January-2000" defined. Pain in the rear, no?
I think that in order to answer your question better, we need to know what you're doing with the Win9x LFNs. If you
don't need to do it on the fly, you're probably best off
looking up the 8.3 directory name and entering it by hand. If
you're running Perl in a Win9x environment, you should be
able to use quotes when opening files and pipes to take advantage of Win9x's CLI. For example:
open(OUTFILE, ">\"C:\\Temp\\Jane's Addiction.CHOPRO\"");
So tell us, what exactly are you trying to do? =) | [reply] [d/l] [select] |