I thought that symbolic links in Windows 10 behave similarly to Linux symlinks, i.e., they are transparent to the apps. However, I'm confused by the actual behavior.
As an example, I've both softlinked and hardlinked the same CSS file:
$ mklink softlinked.css Default.css
symbolic link created for softlinked.css <<===>> Default.css
$ mklink /H hardlinked.css Default.css
Hardlink created for hardlinked.css <<===>> Default.css
The hardlink behaves predictably (is indistinguishable from the original file) but I don't understand the soft linked one. See for example this:
Also, when the CSS is consumed by the Caret editor, the hardlinked stylesheet works fine:
while the softlinked is broken:
The questions are:
How do the symbolic links actually behave on Windows?
Can soft links be made transparent to the apps? By transparent, I mean the app would always see the file as being on the symlinked path (...\symlinked.css) and never resolve to the original path (...\Default.css). Is there some Windows registry settings or something?
Symlinks are transparent to applications that are using the underlying file system, e.g., CreateFile() and friends, unless the application makes a specific effort to be aware of them.
However, they are not transparent to applications that are using the shell namespace (for example the standard Open File dialog) because the shell treats symlinks as if they were shortcuts, even to the point of modifying the displayed icon. Whether this was a sensible decision on Microsoft's part is a moot point at this stage, since it isn't about to change. So far as I'm aware, it is not configurable.
In practice this usually means that symlinks will behave transparently for non-GUI applications and for internal files (DLLs, built-in templates, configuration files, etc.) in GUI applications, but not for the user's documents.
So your first two examples (the way Explorer displays the files and the behaviour of Notepad++) are features rather than bugs; like it or not, this is the way Windows is designed to work.
Your last example does appear to be a bug (or at best an undesirable design limitation) in the application in question. It might be worth contacting the vendor.
You should also be aware that creating a symlink requires administrative privilege, and by default they don't work at all over network shares. Personally, given all these limitations, I've never found them very useful. For most user tasks I would use shortcuts instead, and for most system administration tasks junction points are more reliable.
They should be transparent to most apps but some apps are to clever for their own good.
They might pass FILE_FLAG_OPEN_REPARSE_POINT to CreateFile, or be too aggressive when "verifying" file attributes and choke on FILE_ATTRIBUTE_REPARSE_POINT.
In your specific case, I'm guessing the advanced editor should use FOS_NODEREFERENCELINKS in their open dialog. The CSS switcher might be using FILE_FLAG_OPEN_REPARSE_POINT and you should be able to verify that with Process monitor.
There is no magical registry entry you can use, you have to contact the application authors.
A file is a pointer to a certain node.
When you create a hard link you are just making a new file that points to the same node as the original file.
When you create a soft link you are not making a pointer to a node, but to a file. Because of that soft link resolves it's path to the file it points to.
Since symlink contains both it's own path and path it points to it really depends on application developers to choose which path they want to put in their UI.
Related
Ok i wrote and application that use Adobe ActiveX control for displaying PDF files.
Adobe ActiveX control load files only from file system. So i nead to feed a file path to this control.
Problem is that i don't want to store PDF files on file system. Event temporary! I wan't to store my PDF files only in memory, and i want to use Adobe ActiveX control.
So i nead:
1) A way to fake file on a file system. So this control would "think" that there is a file, but would load it from memory
2) A way to create file on file system that would be "visible" to only one application, so my PDF control could load it, and other users won't even see it..
3) Something else
PS: I'm not asking to "finish my home work", i'm just asking - is there a way to do this?
You can almost do it (means: no you can't, but you can do something that comes close).
Creating a file with FILE_ATTRIBUTE_TEMPORARY does in principle create a file, temporarily. However, as long as there is sufficient buffer cache (which is normally always the case unless your file is tens to hundreds of megabytes), the system will not write to disk. This is not just something that happens accidentially, but the actual specified behaviour of this flag.
Further, specifying 0 as share mode and FILE_FLAG_DELETE_ON_CLOSE will prevent any other process from opening your file for as long as you keep it open, even if someone knows it's there, and the file will "disappear" when you close it. Even if your application crashes, the OS will clean up behind you (if DRM is the reason). If you're in super paranoia mode and worried about the system bluescreening while your file exists, you can additionally schedule a pending move too. This will, in case of a system crash, remove the file during boot.
Lastly, given NTFS, you can create an alternate stream with a random, preferrably unique name (e.g. SHA1 of the document or a UUID) on any file or even directory. Alternate streams on directories are ... a kind of nasty hack, but entirely legal and they work just fine, and don't appear in Explorer. This will not really make your file invisible, but nearly so (in almost every practical aspect, anyway). If you're a good citizen, you will want to use the system temp folder for such a thing, not the program folder or some other place that you shouldn't write to.
Creating an alternate stream is dead easy too, just use the normal file or directory name and append a colon (:) and the name of the stream you want. No extra API needed.
Other than that, it gets kind of hard. You can of course always create something like a ramdisk (would be tough to hide it, though), or try to use one of the stream-from-memory functions to fool an application into reading from a memory buffer on the allegation of a file... but that's not trivial stuff.
If something needs to be on a file system to pass to another application, you can not hide it/limit it to certain processes. Anything your app can see, anything else at the same privilige level can also see/access. You may be able to lock it but how depends on why you want to protect against.
Remember that the user's PC is theirs, not yours so they have full access to everything on it.
You can create a virtual disk and limit access to it to only specific application. Do to this you would have to write a file system driver or a filesystem filter driver. Both work in kernel mode and are tricky to write and maintain. Our company offers components that let you avoid writing drivers yourself and write business logic in user-mode (we provide drivers in those products).
Your most obvious option is to get rid of Adobe Reader control and use some third-party component that displays PDFs and can load them from memory.
But in general a smart hacker would be able to capture your data unless you have (a) non-standard data format, and/or (b) stream the data from the server dynamically, not keeping the complete data on the computer. These are not bulletproof solutions either, but they make hacker's work much harder.
I want to allow the displayed name of my application's shortcut in the start menu to appear in the user's local language, if we have a string available for it.
I have found a question that deals with how the localized strings are referenced in storage, but while I could just muck around editing the desktop.ini file directly, I would highly prefer a fully programmatic interface for solving this issue, i.e. an API similar to the IShellLink and related interfaces already used to set up shortcuts. IShellFolder::SetNameOf initially sounded like it would be able to deal with this, but on my second read of that page, it seems it will always rename the physical file.
My application already uses indirect strings for having file associations localised in the shell, this wasn't a major issue setting up since it is well enough documented, but I can't seem to find much documentation on display names of shell links.
I am using InnoSetup for my installer.
That's almost embarrassing, right after posting the question I did another search on MSDN, and found this:
SHSetLocalizedName Sets the localized name of a file in a Shell folder.
For some time I've noticed how much the File Open and File save dialogs vary between Windows itself and Applications. In Delphi for example (which I use) you can use the built-in dialogs (which have a folder tree) and direct calls to the Windows API which produce variants of the Windows version, with or without large buttons for 'Desktop', 'My Computer' etc (At least on XP).
As an application developer I'm interested in providing the User with a clean, simple way of loading and saving files. Typically, this requires that I propose a preferred folder where my Application data files are stored but that I allow the User to access other folders - often the desktop and other local drives, and sometimes the network - without difficulty if required.
With the introduction of Vista, we seem to be favouring a 'bits missing' folder navigation tree for Windows dialogs and now, Windows 7 has another 'line-less tree' for navigation. I suspect that if one conforms to Microsofts assumptions and stores everything in ~/documents it's not a big problem. However, if one has to start at the root of a drives tree and there are many directories then it's a right pain - there is no horizontal scrolling so directory names get truncated.
My question is - what do other Application developers use? I wonder whether I should be following this Windows lead or simply sticking to a simple cut-down version of File dialogs over which I full control but risk falling into the past....?
Thanks
Brian
Always use the OS defaults - it'll be what your users are used to, and what they expect. Whatever you do, don't astonish the user. Whatever you do, please don't write your own file-open/file-save dialog.
FWIW, I'm not a great fan of Vista's file-open dialog (why do I have to work so hard to navigate my folders?), but I'd rather that than have to get to grips with something new. The less things your users have to learn, the easier your product is to use.
Since I am currently only coding for customers with Windows XP (in a corporate environment that isn't upgrading just yet) I use the standard dialog boxes.
When we do upgrade, I will most likely continue to use the standard old fashioned dialog boxes, until our customers are ready for a change.
In all honesty, I involve at least a few users in the development process, and I won't start new features unless I can bring one in to sit in front of my development PC to see how it works, and they sign off on it.
For those apps that we write for our web site, we tend to be conservative as well... Focus on clean, understandable design, and introduce fancy new features only when there is a compelling reason, and even then, we tend to involve focus groups.
So all that was a long way of saying "Ask your customers". Give them what they want.
Goal
Let me start with my final vision of what I'd like to be able to do first: In Windows, I'd like to be able to use a global keyboard shortcut that I define (say, Ctrl+Alt+C) to copy the full path and filename of the open document in the foreground application to the clipboard.
This would be useful to, for example, be able to subsequently paste the path & filename into an "Open File" dialog in an email client to attach that document to an email, without having to manually browse to the target document in the filesystem.
Specific Question
Now, the specific part of how to do this that I'm interested in how to implement is: How can I get the path and filename of the current "open document" of any arbitrary currently-running Windows application. (If this can't be done with any Windows application, then the next best thing would be for this to work with as many applications as possible.)
Obviously, this wouldn't apply to some applications that don't necessarily have the concept of a "currently open document" that corresponds to a file on the local filesystem, such as an email client, an IM client, or (usually) a web browser.
Application-Specific Solutions
I'm aware that it's possible to write application-specific solutions to do this. For example, the following MS Word VBA subroutine will copy the filename and path of the open document in Word to the clipboard:
Dim myDataObject As DataObject
Set myDataObject = New DataObject
myDataObject.SetText ActiveDocument.FullName
myDataObject.PutInClipboard
However, what I really want is something that will work for any of the applications on my system (or, again, for as many of them as reasonably possible) without having to try and write an application-specific solution for each one.
Idea: Recent Documents Folder
One idea: Could the Recent Documents folder (and/or its underlying Windows APIs) somehow be leveraged to help with this? It seems to have information about the same concept of "open documents" that I'm interested in here, that apparently applies across various application types. (Looking at the contents of the Recent Documents folder on my machine, I see entries in there that were apparently made for documents that I opened with various applications including MS Word, MS Excel, Eclipse, Adobe Acrobat Reader, Paint.NET, TOAD, and Notepad2.)
Preferred Solution Language
I'd prefer solutions in C# or C++ code, but I'm open to any suggestions for how to go about doing this, regardless of implementation language!
Windows 7?
Update 11/2009: Now that Windows 7 is widely available, I figured it might be worth coming back to this question and asking: Does Windows 7 provide any new APIs, or any other mechanism, that would help with what I'm trying to accomplish here?
The best you could probably do is look at the recent documentation registry keys, and get the list of most recent documents. Some sample code for working with this data is in this CodeProject article. This is saved in:
HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\RecentDocs
However, this isn't going to show you whether a document is currently open or not. You could potentially check the title of all open applications, since many applications put document names in their window titles, but this is not a requirement, and many applications do not do that.
There is no mandatory mechanism for an application to specify its open document, so this is not generically possible.
When you are designing an application (assumed in English), and you ask the user to provide a path to a directory/folder, do you use the term Directory or Folder?
Is one more understood than the other? Is one more "correct" than the other?
Please note that they are not synonyms. Directories and Folders behave differently. For example, if you want to remove a File from a Folder, you need access to the Folder and the File, because the File is stored inside the Folder.
If, however, you want to remove a File from a Directory, you need access only to the Directory, because a Directory itself is just a regular File that lists the locations of (but does not contain) other Files. So, you just need to strike out that entry from the Directory, no access to the File is required.
This distinction is pretty important, because false and thus misleading metaphors can be at least confusing and in the worst case pretty dangerous when talking about filesystems. (Confusion about filesystem behaviour often translates into accidental information disclosure, data loss or security holes.)
A great percentage of questions on Unix mailinglists, but also here, on ServerFault and on SuperUser, about what to the asker seems to be confusing filesystem behaviour, can be traced directly back to thinking about Folders, when Unix does in fact have Directories.
So, in other words: use "Folder" when dealing with folders and "Directory" when dealing with directories.
In my experience, these tend to be the norm:
on Windows or any Mac OS: "Folder"
on *nix: "Directory"
The correctness of the term is wrapped up in how much your application behaves and talks like other applications on the platform, so it is best to stick with convention as to not confuse your users.
On the other hand, if the term needs to be cross-platform:
We can always use the Folder term,
because even if we use the term Folder in Linux-based platforms,
anyone knowing the technical-difference
(mentioned)
between Folder and Directory would understand that Directory was meant.
For example, in MacOS we use Folder term, while they are technically-speaking directories.
'Directory' is older and usually used on Unix-ish systems. 'Folder' is usually used on Windows. Personally, I use 'folder' even for GUI apps on both Linux and Windows, it just sounds more "user friendly". (And I doubt anyone will really care that I didn't use the "correct" term.)
If you think your users (e.g. technical users) will be happier with 'directory', use that, but otherwise, I would go with 'folder'.
Use whatever the target OS/DE uses. This definitely means "folder" on Win32, not sure about other platforms (though I think it is also definitely "folder" on OS X, and uncertain on Unix-likes). What you want is for your application to use the same terminology as all other apps, and system dialogs.
It also depends on the type of the application. For command-line applications, "directory" rather than "folder" seems to be the norm everywhere (including Win32).
The term Folder has been primary used by windows systems to make a better association to document-organization and is, as others said just another term. If you won't serve different terms for different systems, use the term Directory.