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.
Related
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.
I want to do a very simple task, and yet somehow the hundreds of questions on SO surrounding the topic always manage to skirt answering this exact one (from what I can find).
The task is this: I want to view the source file that holds the Clipboard contents.
I know that older Windows OS had an option for Clipboard Viewers, and for newer OS you can use third-party viewers, but I want to view the actual source file itself. It has to be stored in some file somewhere, doesn't it? This answer gets close by at least letting me view the text natively without 3rd party software, but I still can't figure out where it's pulling its information from. I don't want the user-friendly version, I want to see whatever the computer is using (HTML, XML, UNICODE, C, or even binary, I have no idea).
There has to be some way to view the contents of that file in Command Prompt (or PowerShell), doesn't there? Why is this information so hard to find?
The short answer is through invoking the static method from the System.Windows.Form.Clipboard class in the .NET framework.
[System.Windows.Forms.Clipboard]::GetText()
This will work in powershell as-is, and will return to you whatever is currently stored in your clipboard.
Now, without going beyond the scope of our main topic being powershell/CLI, you can peruse through the class in User32.lib or User32.dll.
See: https://msdn.microsoft.com/en-us/library/windows/desktop/ms649014(v=vs.85).aspx
My original short answer should be sufficient for what I think you're looking to do, which is return the content of whatever is in clipboard back out to your powershell/cli host in plaintext.
This information was easily found by googling
powershell get clipboard contents
Also, if you want a more in-depth walkthrough:
http://powershell-tips.blogspot.com/2011/05/handling-clipboard-with-powershell.html
Windows is not a GNU/Linux OS. AFAIK there isn't really a clipboard daemon that stores content in a plaintext file somewhere on the filesystem. With .NET being natively available in powershell, you can just invoke these classes directly to get what you need.
I'm looking for a programmatic way to prompt the user for filenames using the explorer shell and I only want system shell extensions loaded.
The reason I'm looking for this feature is that I want to eliminate 3rd party shell extension as a possible cause for crashes and other nondeterministic behavior.
Ideally, there's a flag somewhere that I missed that I can pass in to a function that means something like a "safe mode" for an explorer instance where it only loads the system shell extensions. This seems like such an essential feature and I've spent a good amount of time poring over docs to find it to no avail.
I've looked through the API docs for CFileDialog, GetOpenFileName and IFileOpenDialog. It looks like the only way to prevent the loading of non system shell extensions is by doing some sort of global hackery via registry twiddling or by using software utilities. Neither of these are satisfactory for well-behaved apps.
I know that I can use the "old style" file dialogs that aren't explorer based, but my users would kill me if I forced that on them. :)
The only way I can think of around this is to (ugh) reinvent the wheel and write an explorer-like file open dialog.
I am desperately attempting to guess how the localized filename for photos can be retrieved given the path to that file. For instance, given the path
c:\images\jellyfish.png - Win 7 explorer and the built in image viewer program both display the word "Méduses" for a french win 7. Does this hold true for other versions of windows ?
GetFileTitle only removes the extension and folder path giving me 'jellyfish' which is not what I am after, and after having read through MSDN and google it seems that the Windows Media Format's http://msdn.microsoft.com/en-us/library/dd798508(v=VS.85).aspx interface wouldn't help here. Either I have lost my googling skills or this is very poorly documented. Help please ?
thank you
I'm not sure about this case specifically (I've never encountered localized filenames in that form) but the only officially supported way I know of to get the localized filenames for system directories and the standard Windows applets, etc., is to use IShellFolder::GetDisplayNameOf.
So briefly, you need to get a PIDL for the file (SHParseDisplayName), bind to its parent folder (SHBindToParent), and then query for the display name using the SHGDN_INFOLDER flag.
Addendum: An even easier way (which I completely forgot about) is to use SHGetFileInfo to get the display name with the SHGFI_DISPLAYNAME flag. This means you don't need to muck around with PIDLs. SHGetFileInfo is essentially a wrapper around the various shell COM classes like IShellFolder - either way, the key is to use the shell to get the display name rather than the underlying API functions.
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.