Date: | October 15, 2007 / year-entry #378 |
Tags: | code |
Orig Link: | https://blogs.msdn.microsoft.com/oldnewthing/20071015-00/?p=24783 |
Comments: | 66 |
Summary: | Commenter dingo asks, "Why are shortcuts so hard to manipulate? Why can't they be as easy as unix links?" Well, if you want something like unix links, then you can just create a hard link. Creating them is about the same difficulty (CreateHardLink vs link) and manipulating them is the same since you don't actually... |
Commenter dingo asks, "Why are shortcuts so hard to manipulate? Why can't they be as easy as unix links?" Well, if you want something like unix links, then you can just create a hard link. Creating them is about the same difficulty ( If you want something like unix symbolic links, then you can create an NTFS junction, such as this one that mounts a drive into a directory. (I'm told that Windows Vista expands the repertoire of symbolic links as well.) But neither of these features is available on FAT (or CD-ROMs or Novell Netware or email), which meant that Windows 95 couldn't use them. Last year I discussed in some detail why shortcuts are files. Maybe that's what your question is really about. |
Comments (66)
Comments are closed. |
I suspect (though I’m not sure) that he was thinking of symlinks to files (which a junction point can’t do), and was wondering why you have to go through all the COM hoops to do anything with a shortcut (create a WshShell, call CreateShortcut and pass the .lnk filename, set the returned IWshShortcut’s TargetPath, Arguments, and Description, then Save() it — and it’s even worse in C/C++ than when I did it in VB6, because the shell interface was written for a scripting language).
That’s compared to Unix, where you just symlink("/path/to/target/file", "/path/to/link/name"); — one function call. And getting the path that a symlink points to is as simple as calling readlink() a couple times (to ensure your buffer is large enough) — where on Windows, you have to make another WshShell, get a namespace for the folder, get an item for the shortcut, call GetLink(), and then use the Path property.
Now, you could create a similar single function that did all the heavy shell lifting for you for each case (and in fact that’s what I did last time I had to make an installer that added its own shortcuts). OTOH, should every programmer have to reinvent the wheel?
On the third hand, though, shortcuts can certainly do a lot more than symlinks — change the current directory when they get invoked, for instance. So that’s probably part of the reason for the added complexity.
Hi, I’m reading some topics from the Suggestion box and I would like to provide two answers:
Commenter Mike Sax asks:
"How does the Task Manager determine that an application is "Not responding"?"
Hi, Mike, Task Manager determines this by using the IsHungAppWindow API (http://msdn2.microsoft.com/en-us/library/ms633526.aspx).
Commenter J-F asks:
"What reason was it made that only files name "setup.exe" brought up a Run as dialog, and isn’t there any code or API to do with without naming it "setup.exe"?"
Hi, J-F, In your HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionApp Paths registry key there are some subkeys called "Setup.exe", "Install.exe", "Winnt32.exe", etc. If the value "RunAsNonAdminInstall" is set to "1" then XP will ask you for admin privileges. Vista’s heuristic is completely different, but I assume you’re talking about XP.
Sorry if this is a bit off-topic, but I enjoy answering questions from the Suggestion box!
Have a nice day!
My understanding was that NTFS hardlinks and junction points had different semantics than the unix equivalents, that made them significantly less useful.
I’m going on rumor here, so feel free to tell me I’m completely wrong. But I’d heard that if you create a junction point to a folder, and then use windows explorer to delete the junction point (or one of its parent directories), you’ll end up deleting the target directory instead.
In Unix, creating a symlink to a file or directory has no significant downside – it’s a no-brainer. If my understanding of the NT semantics are correct, creating a junction point to a folder is effectively playing russian roulette with the contents of that folder.
I always missed the good old "Aliases" used by Apple. OS X doesn’t seem to handle them any better than Windows, but Mac Classic was great at always keeping them pointed to the right location, even when that location changed paths or drives.
On a related note – as NTFS and the NT kernel[0] support hard links, they presumably maintain a link count for filesystem objects. Given this, can you open a file in such a way that it can be deleted while held open? Perhaps with the FILE_SHARE_DELETE or FILE_FLAG_POSIX_SEMANTICS flags? The MSDN documentation for CreateFile() just got a bit confusing surrounding the FILE_SHARE_DELETE flag (opening a file /in order/ to delete it?). Can anyone else shed light?
Another reason is that the tools are not bundled with Windows, to be used anytime by administrators or end users. The alternative is to download unsupported tools, or code it yourself.
Junctions are used as one of the ways to provide application compatibility in Vista. Perhaps we’ll see more of them going forward.
Is it just me, or do the terms "reparse point" and "junction point" sound like really heavyweight constructs that you wouldn’t want to use very often? Compared to, say, "shortcut" or "link".
Yes, "reparse point" is a horrible name for a link to a file (or other object).
The name makes it sound complicated to use.
@Stuart Ballard:
I’ve just tried it, and no, creating a junction to a folder then deleting the junction in explorer doesn’t delete the target folder. Try it yourself (download a copy of junction.exe from sysinternals and use it in a cmd prompt)
The junction does work like symlinks, if you delete the target folder and try to access the junction, you get a ‘target inaccessible’ type error.
Or to put it another way, don’t believe the FUD those linux people put out :-)
Here’s a couple of decent shell extensions for creating/manipulating hard links:
http://sourceforge.net/projects/ntfslinkext
http://schinagl.priv.at/nt/hardlinkshellext/hardlinkshellext.html
The first app is a bit more user-friendly, while the second one has a bit more functionality (like the ability to clone an entire directory tree).
There is a danger in creating a hard link to a directory – if you ask Explorer to delete it, it will naturally delete the contents, instead of unlinking the folder. NTFS Link has a pretty nice feature which allows you to unlink a folder using the context-menu. NTFS Link also creates an icon overlay which indicates whether a file or folder has multiple hard links associated with it.
“There is a danger in creating a hard link to a directory – if you ask Explorer to delete it, it will naturally delete the contents, instead of unlinking the folder.”
So deleting and unlinking are two distinct operations on Win32 ? On Unix the file is deleted when the link count becomes 0.
So is a hard link a special construction in NTFS or is it a ‘real’ hard link as in that is is indistinguishable from the original link ? And does a delete find look for al the hardlinks to the file or does it just leave them dangling ?
One thing worth mentioning is that LNK files don’t technically work in filesystem-space, but in Explorer’s IDLIST space. Explorer keeps an object-system around rooted at "Desktop" that lets you also create shortcuts to Control Panels, Printers, My Computer, and other things that have no filesystem equivalents.
Just something to throw out there.
@David Walker
"Yes, "reparse point" is a horrible name for a link to a file (or other object)."
There is a reason for this (though not a particularly good one for it to propagate up to the user’s view), which has to do with Windows file system implementation.
The FS driver (FSD) entry point for NtCreateFile can return a couple things, including STATUS_SUCCESS or FILE_NOT_FOUND (or something like this), but also one called STATUS_REPARSE. In this case conceptually the FSD also returns a new file name. When this happens, the I/O subsystem tries to open it again, this time with the new file name. I haven’t actually tried to verify this, but I would bet any money things like junction points are implemented through this STATUS_REPARSE.
@Aaargh!
"Making a hard link to a directory is a really, really bad idea, you have the chance that suddenly your directory tree is no longer a tree but graph. With cycles."
To be honest, I was always surprised that the Unix-folk have issues with this danger. It seems to me more in the Unix philosophy more to give the user the power to make such links and let them beware of the consequences of doing so. ;-)
Besides, the two ideas aren’t necessarily incompatible. For instance, you could check for cycles either at link creation time (I don’t know how efficiently, but I bet you could do something with topological numbering) or traversal time.
No, I almost certain even NTFS can’t have hard links to directories. You’d need to use a junction point and those behave more like symlinks.
Explorer’s problem is that it doesn’t understand junction points (or didn’t, Vista apparently now does) UNIX, from day one, has symlinks and hard links in their filesystem, and all the utilities were written with that in mind. A symlink is not a directory and rm knows the difference. But Explorer has a simplified view that junctions to directories are the same as a real directory, and therefore recurses and deletes the contents of the target. (As others have pointed out, Vista has learned the difference)
In a sense, Apple also designed a lot of metadata stuff into their filesystem and Finder since the beginning.
Microsoft tried to add these features on top of a filesystem and UI that wasn’t designed for any of this.
It’s about time. :=)
[It seems to me more in the Unix philosophy more to give the user the power to make such links and let them beware of the consequences of doing so.]
Consequences be damned… there are some UNIX that lets root create links to directories and even unlink (rm) non-empty directories.
Just to clear up a bit of confusion, NTFS works just like UFS in how it handles links. Each file is just an entry in the database, and its names are just directory entries (and attributes on that file). Creating a hard link just gives the file an additional filename. As far as I know, it is not possible to create multiple filenames on a directory. Deleting a file will remove filename and its corresponding directory entry. Once a file has no more filenames, it is actually deleted.
Instead of Unix’s unlink() operation, you delete a file (i.e. remove its filename) by opening the file with DELETE_ACCESS, then setting its disposition to deleting, and closing the file handle. You can delete a file that is already open if it was opened with FILE_SHARE_DELETE access.
DriverDude, UNIX has NOT had symlinks from day 1. If you believe the man page, symlinks were first available in 4.2BSD, which puts it somewhere between 1983 and 1986. First Edition UNIX came out in 1971, so it was over 10 years from when UNIX was first released until some version had symlinks. It wasn’t until some years later that AT&T UNIX actually had that feature, though. And in reality, MULTICS had that feature in the mid-60s, so it was over 15 years before it appeared in UNIX.
"No, I almost certain even NTFS can’t have hard links to directories."
I just gave it a try, and no, apparently you can’t. It gives access denied. That’s somewhat of a pity.
Junction.exe from SysInternals: http://www.microsoft.com/technet/sysinternals/FileAndDisk/Junction.mspx
My gripe with junctions is Explorer does not have a different graphic for them (I haven’t checked this under Vista), which means you have to drop to CMD.exe to check — rather than "<DIR>" they’re listed as (IIRC) "<JUNCTION>".
Under XP, junctions are for most purposes just another directory.
I think it depends on which version of Explorer we’re talking about.
In XP, Explorer didn’t know a junction (or whatever) from a real directory and would recursively delete its contents before deleting the junction itself. The original directory might have been left but the *contents* of it would be gone, which wasn’t good.
However, in Vista, Explorer now knows about junctions (and symlinks) and won’t recursively delete their contents. (Or will warn/ask you. I can’t remember exactly.)
steveg: On Vista, junctions have the little "shortcut" icon, though unlike regular shortcuts, they’re sorted with the folders… it’s rather confusing if you ask me :-)
@Karallen, David Walker: "Reparse points" are a lot more than just links — you can effectively stick any information in those that you want. I’ve seen reparse points used for everything from folder junctions to eliminating redundant files to storing data offline to making automatic backups. Lord only knows what additional weird stuff third-party developers have used them for. In effect, if you’re coming from a Un*x world, don’t think of reparse points as equivalent to symbolic links: Think of them closer to block/character special files.
That said, Vista now uses reparse points "under the hood" to implement Un*x-like symbolic links. Of course, if you’re not on Vista, these aren’t available to you.
*sigh* How many different link-like constructs are there now in Windows, anyway? Junctions, mount points, SIS, Shortcuts, NTFS links, offline storage, and symbolic links are the ones I can think of offhand. It’s a real shame Microsoft can’t deprecate a few of those and simplify the design of the OS a little.
I guess I didn’t read it properly before, but a hard link to a *directory* ? And that’s actually a legal operation in Win32 ?
Making a hard link to a directory is a really, really bad idea, you have the chance that suddenly your directory tree is no longer a tree but graph. With cycles.
I like sorting shortcuts-to-folders amoung folders, and also being able to see the type and — most useful of all — target of shortcuts, symlinks and junctions:
http://www.pretentiousname.com/temp/ShortcutTypesAndTargets.png
I doubt that most users know or care much about these things, especially when most of the junctions are hidden by default in Explorer and it isn’t easy (or recommended) to go around making new ones. If you’re one of the few who do care about such details then Explorer probably isn’t the best tool to be using in the first place.
"To be honest, I was always surprised that the Unix-folk have issues with this danger. It seems to me more in the Unix philosophy more to give the user the power to make such links and let them beware of the consequences of doing so. ;-)"
Sure, but this is not a case of giving more control to a user, this is a case of bad FS design.
These comments are all really interesting, it boils down to "Vista has symlinks". We only need a decent API to make it easy to create/unlink and you are laughing.
Oh, and for MSI files to handle setting up symlinks as part of the declarative part of the install, something you dont need to write script for and to use some third party installer. Why? Because checking symlinks point to files that exist is a way of verifying the state of an install. Later at uninstall time, the uninstaller should only remove the link if it points to the original destination.
Certainly the RPM packages I’ve done in linux tend to do the ln -sf and link rm operations in bits of script; its always the hardest part to get right (especially during package upgrades)
Anyway, we, the Linux users, welcome Vista to the 1990’s :)
Quote: [No, I almost certain even NTFS can’t have hard links to directories. You’d need to use a junction point and those behave more like symlinks.]
Sorry, when I wrote "hard link to directory", I really should’ve written "junction point". The utilities I linked to create *hard links to files* and *junction points to directories*.
I believe one of the differences is that a hard link is indistinguishable from the file itself, whereas a junction point is NOT exactly the same as the directory itself. So when I said there’s an issue with "unlinking a hard link to a directory", I really should’ve said "unlinking a junction point".
steveg: If you want junctions to look different in Explorer (XP), get NTFS Link (Ext) (URL is in my above post). It will create icon overlays for junction points, and for files with more than 1 hard link. It will also attempt to update junction points for directories that have been moved, renamed, or deleted (which is something Windows doesn’t do, AFAIK).
Just to clarify my above posts: The issue with junction points is that, as someone mentioned, they *mostly* behave like symlinks, *until* you try to delete them in Explorer. When you do that, the contents of the target directory are deleted (at least under 2K and XP).
But NTFS Link will intercept delete operations so that the junction point will be deleted, and not the target directory. And again, it also provides a handy right-click option to manually unlink junction points.
What is stupid is simply that for links (and many many others things) you have to call cryptic COM interfaces instead of just a plain good-old C procedure. This would be not too bad (maybe even a good thing) if COM was just usable; however COM is full of traps, error-prone and just hard to use, shifting the programmer’s focus from object management to its crappy syntax.
"Those who do not understand Unix are condemned to reinvent it, poorly."
–Henry Spencer
Maybe in a few decades, Windows will finally be a Unix.
Junctions are rather more like Linux’s bind-mounts than symbolic links.
In my understanding, shortcuts and (sym)links serve completely different purposes. Shortcuts are intended to launch programs (optionally supplying them with parameters), while links are just different pointers to the same file (or directory).
Also, the symlinks on Vista don’t look like junctions to me – I played with them a little, and also created some symlinks on a share served by Windows XP x64, and from XP the symlinks looked like 0-byte inaccessible files (however I’ve heard there’s a driver that makes the Vista symlinks work in XP). Another interesting thing is, that Vista distinguishes between file and directory symlinks – something that Unix doesn’t do.
PingBack from http://www.universityupdate.com/Technology/Windows-Vista/5242874.aspx
For everyone: the Windows NT line has always supported hardlinks in the kernel; symlink support came in Windows 2000 ("reparse" logic in the object manager). NTFS has always supported hardlinks, as well, but Win32 didn’t have a convenient API until Windows 2000; NTFS started supporting mount points (which could be abused as directory symlinks with absolute destination paths) in Windows 2000, and finally got full support for symlinks in Windows Vista. The outstanding difference with UNIX is that symlinks in Windows can be, in turn, either directories or files, because Win32 cares about that (you can choose whether you care or not when you open a file, though)
Aaargh!: Windows has been a part-time UNIX since about Windows 2000. In my experience, you can run NetBSD wonderfully on Windows, just download the bootstrapper and you’re go: http://www.netbsd.org/docs/pkgsrc/platforms.html#interix
Correction: actually, the kernel always supported symbolic links, just not when opening/creating files (the parse routines for device objects didn’t know what to do with a return code of STATUS_REPARSE from an IRP_MJ_CREATE I/O request)
Almost forgot: Windows doesn’t have an equivalent of unlink: you can mark a file as pending deletion, but that won’t free up the directory entry. An unlink would be the equivalent of renaming a file to an empty name, but NTFS doesn’t like that. The closest you can go is move the file to a temporary directory, and mark it as pending removal. You’ll see Interix creates a weird directory at the root of some drives: that’s where files unlinked while they were in use stay until they are closed.
Services for Unix (Applications) is similar to cygwin when it comes to symlinks – from normal Win32, they appear as files (with the system attribute set). The Linux cifs driver also supports symlinks (and devices, pipes) on Windows shares in the same way as SFU.
Interix can’t always unlink files that are in use. Although something like
rm ~/foo > ~/foo
works, you can’t do
cp /bin/rm ~/rm; ln ~/rm ~/foo; ~/rm -f ~/foo
Neil: executables used as the main executable of a process are specifically locked down by the kernel so they cannot be deleted or otherwise moved/renamed. Nothing Interix can do about that…
I think you may be able to flip a bit in the header of an exe telling the OS to copy it to swap before running. That’s the problem you see -the OS wants to page bits in on demand. Linux deals with by allowing you to unlink the program from the filesystem, while retaining a link the executable from the process: the running code runs the old executable.
I dont know which is better architecturally; Windows does at least guarantee that all programs loading the same COM DLL are going to get the same version. What linux does let you do is update swathes of the system while the apps are running, which is good for sysadmin.
@Steve:
I’m not sure leaving apps running while updating them is a great idea, because then you can’t be sure that the updates have been consistently applied. I think the UNIX approach works for a certain set of sysadmins who are willing to futz around with their box to check the updates were actually consistently applied. If two programs are interacting and have different versions of a link-library because they were started at different times, you have a potentially hard to figure out reliability problem.
Rebooting/restarting for an update is not such a tragedy… it ensures that your system updates correctly in a less error-prone way.
@Aaargh!
"Maybe in a few decades, Windows will finally be a Unix."
Geez, I hope not. Unix is almost as bad as Windows, just in entirely different ways. ;-)
@nksingh:
Or, instead of rebooting/restarting the system, you could just restart all the services.
One way to do this is to restart each service individually by calling its init.d script with the "restart" parameter. If you’ve got some extra dependencies (such as web stuff that depends on a database and can’t deal with it dropping out) you could do something like the following:
/etc/init.d # ./apache2 stop && ./postgresql restart && ./apache2 start
Another way would be to drop to runlevel S/1 which will stop all services in the normal shutdown order, and then go back to your normal runlevel (probably 3 or 5) which will start them all up again in the correct order.
Both of these will produce a lot less downtime than a reboot due to not needing to unmount filesystems, stop hardware, go through BIOS POST, run bootloader, load kernel, mount filesystems, maybe get network lease, etc…
Suraj Barkale — I doubt it. I suspect there’s no reason to document the format anyway, since you can ask the shell for a COM interface that gives you access to everything in the file already.
Documenting the format means it can never change in the future (e.g. when a new feature is added to shortcuts (like the "run as another user" flag) and an IWshShortcut2 interface is created, or whatever other interface(s) people use).
There is documentation for the WshShell.CreateShortcut function (which I’ve just found out doesn’t overwrite the LNK file if a shortcut already exists; wish I’d have seen that earlier), and its returned IWshShortcut interface, though. (Also for the classes that implement that interface: both WshShortcut and WshURLShortcut.)
Raymond,
Bull.
If shell links were designed by an Unix programmer then they would be text files that programmers could learn to create simply by taking a look at a few of them.
(Or if this was done today these would be XML files.)
But what did you do instead? You created a freakin COM API that saves into a binary format. Creating shortcuts now requires browsing through MSDN and then copying & pasting code from there.
Don’t XP and Vista claim to be POSIX compliant? Given that the ln command (and ln -s) are part of the POSIX standard, it seems that both hard and soft links would be requisite.
I just skimmed the comments to this point, but from my perspective, the real problem is not about the relative merits of different link types or when using a link is shooting yourself in the foot, but whether a POSIX-compliant script can run on a POSIX-compliant OS. That’s the whole point of having a standard…
@B
"Don’t XP and Vista claim to be POSIX compliant? Given that the ln command (and ln -s) are part of the POSIX standard, it seems that both hard and soft links would be requisite."
NT is only POSIX-compliant from within the POSIX Subsystem/Interix/SUA/whatever you want to call it.
It’s possible to create links with ln and ln -s that behave correctly from within SUA even in Windows 2000, and very possibly before then. However, to programs running in the Windows subsystem, links created by SUA’s ln appear as files.
There are other differences too; for instance SUA presents [can present] a case-sensitive view of NTFS file systems, which means you can create c:test and c:TEST, and only one of them will be accessible to any program that uses the Windows subsystem (and doesn’t "cheat" and make native system calls directly).
Steve: it only applies to modules loaded implicitely by CreateProcess; DLLs can, as a rule, be renamed while in use
Dejan: the UNIX equivalents are, in fact, INI files: http://standards.freedesktop.org/desktop-entry-spec/latest/
B: "compliant" doesn’t mean "usable". You have to jump through a few hoops to get an UNIX environment on Windows. I found NetBSD’s pkgsrc tree to help immensely, though
"UNIX, from day one, has symlinks and hard links in their filesystem, and all the utilities were written with that in mind."
IMO, "Hacked to sort-of-work with them" is a better description. From the man page for cp on my Mac (10.4):
"Note that cp copies hard linked files as separate files. If you need to preserve hard links, consider using tar(1), cpio(1), or pax(1) instead."
Yes, even today, the Unix copy tool can not reliably copy a directory tree. I have no reason to believe that other Unices are better in this respect.
From a Linux page describing cp:
"Symbolic and hard links are copied as files. That can be good because, at the destination, a symbolic link might point to the wrong place. It can be bad if the link pointed to a really big file; the copy can take a lot of disk space."
> But neither of these features is available on FAT (or CD-ROMs or Novell Netware or email), which meant that Windows 95 couldn’t use them.
Yeah suuuuuure. Long names werent available on FAT either but somehow Windows 95 was able to use them, y’know. A tiny little backwards compatible extension to the directory structure, and viola! Please please don’t tell me symlinks couldn’t have been done the same way!
Out of curiosity, is there any *official* documentation of shortcut file format? A quick google search got me to http://mediasrv.ns.ac.yu/extra/fileformat/windows/lnk/shortcut.pdf
Windows come up with all this strange names (reparse point & junction point) because naming them link or shortcut would indicate unix was right all the time.
Re: First commenter’s "on the third hand"
That would be the *gripping* hand.
I have encountered a problem with junctions on XP, in that they don’t work properly with the recycle bin. If you attempt to delete a file under a junction through explorer, it complains that it cannot find the file. Shift-delete to permanently delete without hitting the recycle bin works fine.
@Timbojones
If you research a little about the recycle bin, you will find out it has a lot of "by design" problems with hard resolution. The most annoying for me is that it can get corrupted in a hardly recoverable state and that the underlying filesystem object can’t be deleted (to resolve corruption with a brand new recycle bin).
BUT you can format your FAT32 partition and, instead of using a backup disk, you can move your stuff there and recover afterwards because of its static-priviledged i-node status in the filesystem. No need to buy discs, cheap backups when reinstalling.
I believe recycle bin deserves a topic and some explanations somewhere.
I think the question being answered isn’t necessarily the one that was supposed to be asked (it’s somewhat ambiguous).
Probably a better way of putting it might be “given that shortcuts are very much like symlinks with metadata, did nobody at Microsoft think that conceptually this was very powerful and would best serve the development community by being wrapped up into a very straightforward Win32 API instead of forcing people to jump through the shell’s COM interface hoops to manipulate them?”.
In short, you do it like UNIX, but with additional metadata capabilities and emulated with .lnk files on filesystems that don’t support them. You bump the CIFS/SMB version number and pay attention to the version information resources in executables (which things do anyway). Older clients (local or remote) see the links as ordinary files; newer clients see them as a new type of entity (siblings to files, directories, and so forth).
It’s worth noting that Cygwin creates its symlinks *as* .lnk files (and presents shortcuts as symlinks, handily), and that *most* UNIX applications don’t need to be remotely “symlink-aware”. There are some additional APIs for performing operations on the links themselves instead of the targets (lchown, lchmod, lstat), and rename() and unlink() always operate on the links, but any attempts to *traverse* the links behave as though you’d attempted to access the target (and you get the usual errors if it doesn’t exist/can’t be read/is the wrong type of object).
It’s difficult to believe that in the time between Windows 95 and the present, nobody thought that treating the shortcut files, junction points, hard links and so forth as a filesystem-dependent implementation detail of “links with possible metadata” would be a good idea, and if they did that they hadn’t figured out how to make it work long before now. It’s not something people haven’t been talking about since August 1995, either.
As an aside (because several commenters brought it up): UNIX lets you “delete” a file that’s in use because it has an internal link count as well as an on-disk link count. The file isn’t actually removed from disk until both hit zero. When a file is opened, the internal count is bumped, and when it’s closed it’s decremented again. Even though sections of libraries and such aren’t necessarily mapped or loaded when an executable is first launched, they will be opened, and you’ll note that any packaging tools will always either rename or unlink files before replacing them (rather than just opening the files for write access, which would be disasterous). Basically, on UNIX, save for I/O errors and exceptional circumstances “if you have a valid file handle, the file exists, even if you can never open it again [you can duplicate the handle and pass it to child and—on some systems, via local sockets—other processes].
The fact that Windows hasn’t (I don’t recall if Vista does) worked this way for as long as it’s existed is a bone of contention for a great many users and developers alike, and the “but things might get corrupted” argument only applies if either your loader or your packaging tools are really _really_ stupid. Given that the loader is part of Windows, and that most packaging tools—even on Windows—aren’t remotely that stupid, the biggest barrier seems to be the semantics of NTOS and the filesystem layer/drivers itself. I don’t know if there’s some major complicating factor here that I’m missing—or even if it’s already been quietly resolved—but part of the reason it’s so frustrating is because it SEEMS like another of those issues that could have been resolved a very long time ago with a little thought and research into the competition.
Man, I miss assignments in AmigaOS. Just assign foo: to any location you want, then use foo: to access said location.
I guess you can kinda fake it with environment variables, but %foo% is a lot harder to type.
On the other hand, I really don’t miss the .info files all over the place.
I think it’s funny that people complain about how Explorer mis-handles junctions, when just as many seem to complain that shortcuts should be handled transparently by the OS. What most don’t realize is that once you have transparent directory links, all of your old file management programs break because they don’t know that there can be cycles in the graph. In fact, any program that performs recursion on the filesystem (dir/s, findstr/s, xcopy/s, and so on) can end up handling directory links wrong.
"What most don’t realize is that once you have transparent directory links, all of your old file management programs break because they don’t know that there can be cycles in the graph. In fact, any program that performs recursion on the filesystem (dir/s, findstr/s, xcopy/s, and so on) can end up handling directory links wrong."
Then you fix those programs. Unixy systems get along mostly fine. ;-)
(This "too ideal for reality" message brought to you by the We Ignore Third Party Applications, Inc.)
[What should a downlevel client see when they encounter a FAT symlink? (FAT LFNs get a short file name for backward compability. But how should a FAT symlink appear to, say, your camera?) And even if you solve this, there are still all the other reasons that are still outstanding. (How do you email somebody a symlink?) -Raymond]
The same way pre-Vista Windows see symlinks (a zero-byte file that gives an error when you try to access it)? Or maybe not see them at all?
As for e-mailing a symlink, you don’t – you e-mail a file it’s pointing to (if you try to resolve a symlink from a system that doesn’t support symlinks, that’s dealt elsewhere; note that I’ve received shortcuts in e-mails and on floppy discs several times – what would be the difference with symlinks?).
Evan: I can email somebody a link to a printer or a directory on a file share. I can’t even create a symlink to a printer, and I can’t very well email somebody a whole directory on a fileserver.
As for emailing shortcuts to files, I hate when people send me huge attachments, particularly to files that are already available on the network. I much prefer that somebody send me a link to the file (or a shortcut if the file’s on a share rather than a web server).
Evan: Well, no. Not if you rely on version information in the apps. Old apps written to the old APIs with no knowledge of symlinks see files. New apps written to the new APIs see links. If you didn’t want to rely on version information, you change the API symbols (though that’s more fragile, as just recompiling against the new SDKs would imply—wrongly—that your app understood symlinks).
It’s really not as hard as some people are making out, though some of the comments I’ve read have convinced me that perhaps yes, nobody at Microsoft DID think it would be a good idea to do it.
If your e-mail program really really needs to be able to let you send links+metadata to other people (because, say, a textual representation [e.g., a URL or UNC path] isn’t sufficiently rich), then you’ve hit the rare case of where it might being beneficial to not be “symlink aware” (i.e., the e-mail program just sees a .lnk file which it attaches). It would probably be more sensible, though, for the e-mail client to be link-aware, but just give you the option of attaching the target or creating a hyperlink/inserting a URL/UNC path. The idea of e-mailling an attachment which is a shortcut file is a horrible one in the first place, and far from being a feature is more just a by-product of API situation.
I would just like to know why certain older setups took ages to create shortcuts in Start Menu (you could watch them appearing slowly one by one in an Explorer window they popped open).
That and why we can’t have shortcuts to the particular position in video and sound files.
Igor: because they used the Program Manager DDE API. DDE is based on message broadcasts to all top-level windows to locate the server of a conversation, and if a top-level window is owned by a thread that sleeps or spins without pumping messages, you’ll get slowdowns. Raymond already blogged about this, I think
Shortcuts to parts of files: OLE supports that in principle (<file path>!<part name> syntax), but I doubt the shell does, and if it does, I doubt any program (save for Excel) bothers to define document parts
640k: the name "symbolic link" was already taken, because Windows always supported symbolic links. Just not on filesystems. The I/O manager has always been a poor fit for an object manager subsystem