Registry does not like long filename for shell commands or verbs - windows

(if not applicable to SO, please refer to another appropriate place, thanks).
When using the registry to associate file extensions and application, I put in the full filename of my application, but that does not work well, only if I use the 8.3 filename.
for example ( taken from the registry) this works:
[HKEY_CLASSES_ROOT\Toto.Document\shell\myVerb\command]
#="C:\\my\\path\\bin\\Debug\\bin\\myexe_~1.EXE /dde"
[HKEY_CLASSES_ROOT\Toto.Document\shell\myVerb\ddeexec]
#="[myVerb(\"%1\")]"
but this does not work :
[HKEY_CLASSES_ROOT\Toto.Document\shell\myVerb\command]
#="C:\\my\\path\\bin\\Debug\\bin\\myexecutable.EXE /dde"
[HKEY_CLASSES_ROOT\Toto.Document\shell\myVerb\ddeexec]
#="[myVerb(\"%1\")]"
The action is called by right-clicking on the file in Explorer, I get the error :
"Windows cannot find 'c:\users\me\desktop\tata.toto'. Make sure you typed the name correctly, and then try again".
I'm creating the keys programatically with CRegKey and using GetModuleFileName to get the application path.
2 questions :
- I'm probably missing something in my registry entry ? (i've tried quoting the paths, but does not work)
- Can I get the "short" filename ? (searching a little bit seems that GetShortPath should work, but not always!)
Thanks.
Max.
(edit 22/03/2011)
I tried using quotes but it did not work (with /dde)
I decided to use normal parameters instead of /dde and it seems to work nicely with the normal path (not shortened like stated above).
I'm still not certain why when creating a simple MFC SDI project it will write out registry values with the old short name instead of the long name.
Thanks again.
Max.

Try creating the key with another couple of double-quotes (note between .EXE and /dde:
#="C:\\my\\path\\bin\\Debug\\bin\\myexecutable.EXE" "/dde"

Related

Is there a way CMD can open a folder with an emoji in its name by using os.execute in Lua 5.2?

As soon as I try to access a folder/file containing an emoji in its name from my Lua 5.2 script, for example like this:
os.execute('start "" "' .. path .. "\\scripts\\menu\\📄 My Scripts" .. '"')
The Windows' Command Prompt simply refuses to open it with the following error message:
I'm aware Windows' Command Prompt doesn't support emojis and therefore is not possible to make it work just like that, but my doubt is if won't exist some workaround or whatever I can do to ensure any Windows/Unix user is going to able to get the folder open by my Lua script without any problem.
I have tried i.e. things like use the codes instead (1246 and U+1F4F0 in this page facing up case) without success. Couldn't I for example simply use some kind of "wildcard" instead? I mean, knowing it's always going to be the very first character in the name. Or, well, any other ideas will be welcomed, cause nothing I'm trying really seems to work...
Of course if it's going to represent any problem I'll simply refuse to use them, but it came in handy for some "first sight" folder distinction and, if possible, I'd like to can count this little visual resource 🙄
This is a Problem about how the string is constructed.
I found only one solution with [[command "path"]] (on Windows 11 and Lua 5.3)...
os.execute([[start ]] .. path .. [["\scripts\menu\📄 My Scripts"]])
-- My Testpath is/was: os.execute([[dir "%localappdata%\nvim\📄 Lua"]])
...the long string ([[]]) will not be interpreted (coercionated) by Lua.
That also have the side effect that you can use single backslashs with that kind of string.
Environment variable expansion (e.g. Windows: %localappdata%) only works inside doublequotes.
Single quotes instead ([[command '%localappdate%\path\']]) will not work (expanded).
os.execute accepts only ANSI-encoded strings (win-1252 in European Windows), but it is unable to encode an emoji.
Hint: you can create .bat-file to do the task for you and invoke it from Lua with os.execute.

How to SHSetLocalizedName with a hard coded string?

I want to localize a shortcut and have come across this API SHSetLocalizedName() which takes a path to an executable and a resource ID. However, I want to use a string instead. It looks like it just writes to desktop.ini:
[LocalizedFileNames]
Test.lnk=#program.exe,-101
I played with it manually and I can just do this:
[LocalizedFileNames]
Test.lnk=Localized Name of Test Shortcut
Does anyone know a programmatic way of doing this? I really don't want to write to desktop.ini myself.
Thanks.
A hard coded string is the opposite of localization!
The point of SHSetLocalizedName is to have various parts of the start menu and some special folders (My documents etc.) display in a language that matches the users current UI language. To do this the string has to be a resource in a PE file so that the magic of multiple versions of a resource in different languages can work.
If you always want a specific name you can just rename the file. If you can't do that (you don't have write access or you are trying to trick the user) then perhaps this is not something you should programmatically be doing?
SHGetSetFolderCustomSettings knows how to change some values in desktop.ini but this string is not one of them. I believe using WritePrivateProfileString is the only solution...

Insert a hyperlink to another file (Word) into Visual Studio code file

I am currently developing some functionality that implements some complex calculations. The calculations themselves are explained and defined in Word documents.
What I would like to do is create a hyperlink in each code file that references the assocciated Word document - just as you can in Word itself. Ideally this link would be placed in or near the XML comments for each class.
The files reside on a network share and there are no permissions to worry about.
So far I have the following but it always comes up with a file not found error.
file:///\\165.195.209.3\engdisk1\My Tool\Calculations\111-07 MyToolCalcOne.docx
I've worked out the problem is due to the spaces in the folder and filenames.
My Tool
111-07 MyToolCalcOne.docx
I tried replacing the spaces with %20, thus:
file:///\\165.195.209.3\engdisk1\My%20Tool\Calculations\111-07%20MyToolCalcOne.docx
but with no success.
So the question is; what can I use in place of the spaces?
Or, is there a better way?
One way that works beautifully is to write your own URL handler. It's absolutely trivial to do, but so very powerful and useful.
A registry key can be set to make the OS execute a program of your choice when the registered URL is launched, with the URL text being passed in as a command-line argument. It just takes a few trivial lines of code to will parse the URL in any way you see fit in order to locate and launch the documentation.
The advantages of this:
You can use a much more compact and readable form, e.g. mydocs://MyToolCalcOne.docx
A simplified format means no trouble trying to encode tricky file paths
Your program can search anywhere you like for the file, making the document storage totally portable and relocatable (e.g. you could move your docs into source control or onto a website and just tweak your URL handler to locate the files)
Your URL is unique, so you can differentiate files, web URLs, and documentation URLs
You can register many URLs, so can use different ones for specs, designs, API documentation, etc.
You have complete control over how the document is presented (does it launch Word, an Internet Explorer, or a custom viewer to display the docs, for example?)
I would advise against using spaces in filenames and URLs - spaces have never worked properly under Windows, and always cause problems (or require ugliness like %20) sooner or later. The easiest and cleanest solution is simply to remove the spaces or replace them with something like underscores, dashes or periods.

Rename file in Win32 to name with only differences in capitalization

Does anyone know a pure Win32 solution for renaming a file and only changing its capitalization, that does not involve intermediate renaming to a different name or special privileges (e.g. backup, restore).
Since the Win32 subsystem generally regards two file names differing only in capitalization as the same, I haven't been able to find any solution to the problem.
A test program I made with the MoveFile API seems to work. So does the rename command in cmd.exe. What have you tried, and what error are you getting?
This isn't relevant, but further testing shows that renaming a long filename in this way works but will change the short filename (alternating between ~1 and ~2 for example), incidentally.
Just use the normal MoveFile API. That call probably just turns into ZwSetInformationFile(..., FileRenameInformation,...) The docs for FILE_RENAME_INFORMATION states that you need DELETE access and the file can't be locked etc, but those restrictions will probably apply to other solutions also.
I do not believe there is a way to expose two files with identical names that differ only in spelling to the Win32 subsystem. Even if some how you were able to create these files, the most likely result would be that only one file would be accessible - defeating the purpose of staying soley in Win32.
If you want to go into the Native layer, you can create a file with NtCreateFile and InitializeObjectAttributes w/o OBJ_CASE_INSENSITIVE or you can pad the end with extra spaces (if you pad with extra spaces, the file will not be accessible from Win32 dos paths). See here: http://www.osronline.com/ddkx/kmarch/k109_66uq.htm . I'm pretty sure you were already aware but I included it incase you did not know.
So long as your file is not immediately needed by another program, you can use my solution.
When you rename the file, capitalize, and delete the last letter. Then rename again and return the letter.
:)

Are there any invalid linux filenames?

If I wanted to create a string which is guaranteed not to represent a filename, I could put one of the following characters in it on Windows:
\ / : * ? | < >
e.g.
this-is-a-filename.png
?this-is-not.png
Is there any way to identify a string as 'not possibly a file' on Linux?
There are almost no restrictions - apart from '/' and '\0', you're allowed to use anything. However, some people think it's not a good idea to allow this much flexibility.
An empty string is the only truly invalid path name on Linux, which may work for you if you need only one invalid name. You could also use a string like "///foo", which would not be a canonical path name, although it could refer to a file ("/foo"). Another possibility would be something like "/dev/null/foo", since /dev/null has a POSIX-defined non-directory meaning. If you only need strings that could not refer to a regular file you could use "/" or ".", since those are always directories.
Technically it's not invalid but files with dash(-) at the beginning of their name will put you in a lot of troubles. It's because it has conflicts with command arguments.
I personally find that a lot of the time the problem is not Linux but the applications one is using on Linux.
Take for example Amarok. Recently I noticed that certain artists I had copied from my Windows machine where not appearing in the library. I check and confirmed that the files were there and then I noticed that certain characters in the folder names (Named for the artist) were represented with a weird-looking square rather than an actual character.
In a shell terminal the filenames look even stranger: /Music/Albums/Einst$'\374'rzende\ Neubauten is an example of how strange.
While these files were definitely there, Amarok could not see them for some reason. I was able to use some shell trickery to rename them to sane versions which I could then re-name with ASCII-only characters using Musicbrainz Picard. Unfortunately, Picard was also unable to open the files until I renamed them, hence the need for a shell script.
Overall this a a tricky area and it seems to get very thorny if you are trying to synchronise a music collection between Windows and Linux wherein certain folder or file names contain funky characters.
The safest thing to do is stick to ASCII-only filenames.

Resources