6

I'm making a program which requires arguments from context menu (click a file and invoke my program with the file name as parameter).

I'm trying to add a registry key to ...\shell\myThing\command. What I'd like to is the following:

C:\Program Files (x86)\Feliratozo\Feliratozo.exe %1

I'd like to use %ProgramFiles(x86)% environment variable, because I've read somewhere that it works on x86 and x64 Windows as well. (Changing to "normal" Program Files on x86.) The problem comes when I try to set:

%ProgramFiles(x86)%\Feliratozo\Feliratozo.exe %1

This way when I try to use the said context menu item, it gives the following error:

Windows cannot access the specified device, path, or file. You may not have the appropriate permissions to access the item.

The permission problem doesn't seem to be correct because when using absolute path it works.

What can I do now?

  • 4
    Did you remember to Change the registry Setting to be a REG_EXPAND_SZ instead of a REG_SZ!? – Werner Henze May 23 '13 at 11:57
  • 1
    By the way, part of your premise is faulty. on a 32bit PC, you cannot evaluate the env var %ProgramFiles(x86)%. you will recieve the message 'The system cannot find the path specified.'. Personally from a pathing perspective, its better to use regular old '%ProgramFiles%' since it will always resolve to a folder regardless of the bittedness of the host. – Frank Thomas May 23 '13 at 12:08
  • 1
    Thank you both. Werner Henze, if you make an answer, I can accept it, this way I can't even give a Vote Up for your comment. – Martin Fejes May 23 '13 at 12:56
  • @Martin Fejes: Made it an answer. Please only accept it if you tested it and it worked. I am not sure if Explorer is expanding environment variables in these registry keys at all. – Werner Henze May 23 '13 at 13:19
10

You should remember to make the registry value a REG_EXPAND_SZ instead of a REG_SZ. Normally, only REG_EXPAND_SZ values are expanded.

  • 2
    If the value happens to be the (Default) key, you will find you cannot change its type via the Registry Editor GUI. To get around this, create the key manually: copy/save its current value, from an Admin PowerShell window/command prompt run reg.exe add <path-to-value> /ve /t REG_EXPAND_SZ /d "<value>". Voila, your (Default) key is now a REG_EXPAND_SZ! – Ian Kemp Jun 15 '18 at 5:12
  • 1
    @IanKemp don't forget to quote the "<path-to-value>" and remember the angle brackets are not part of the value – smac89 Apr 13 at 8:44
1

Don't forget that %ProgramFiles(x86)% will expand with spaces in the name so the path(s) needs to be enclosed in quotes. It might work like: "%ProgramFiles(x86)%\Feliratozo\Feliratozo.exe" "%1" Also, Frank Thomas is correct about %ProgramFiles(x86)% not working on 32bit Windows.

Variables are expanded based on the parent process though. %ProgramFiles% will expand to C:\Program Files (x86) on a 64bit installation if you use the 32bit console or regedit (Located in SysWOW64).

A simple solution:

Install.cmd:

IF EXIST %WinDIR%\SysWOW64\regedit.exe (
   %WinDIR%\SysWOW64\regedit.exe /s Install.reg
) ELSE (
   %WinDIR%\regedit.exe /s Install.reg
)

Install.reg:

Windows Registry Editor Version 5.00

[...\shell\myThing\command]
@="\"%ProgramFiles%\\Feliratozo\\Feliratozo.exe\" \"%1\""
-1

Use an Expandable String

DWORD = dword: Expandable String = hex(2): Multi String = hex(7):

A DWORD is a 32-bit unsigned integer (range: 0 through 4294967295 decimal) In the registry, a DWORD always begins with 0x. In the registry, DWORDS always have 8 digits that follow 0x. This can be in decimal or hexadecimal format, 1000 can be written as: 0x00001000 or 0x000003e8

DWORDS can only make use of the digits 0-9. Strings, any kind, always use ASCII, in ACSII 1000 can only be written as 31,30,30,30 For the String data type, ASCII works in the background without you even knowing. It has to because the computer only understand 1s and 0s. For Expandable String and Multi String data types, these save your entries as a series of ASCII codes in a hexadecimal format, separated by a commas and hex zeroes. So, an Expandable String of 1000 would be: hex(2):31,00,30,00,30,00,30,00

So let's convert %PROGRAMFILES% into an expandable string. First, download this: https://hotfile.com/dl/244097278/55aa086/ASCII_2_HEX_Conversion_Tool.7z.html

Now open that in any modern browser. Put %PROGRAMFILES% into the ASCII box, and select encode it. It will give you %25%50%52%4F%47%52%41%4D%46%49%4C%45%53%25 Copy paste that into a text editor, move the first % to the end. Select the replace command, find all "%" and replace with ",00,". Remove the comma at the very end. You should get: 25,00,50,00,52,00,4F,00,47,00,52,00,41,00,4D,00,46,00,49,00,4C,00,45,00,53,00,25,00 And finally, hex(2):25,00,50,00,52,00,4F,00,47,00,52,00,41,00,4D,00,46,00,49,00,4C,00,45,00,53,00,25,00

Done.

Have you ever tried to convert a curious hex registry entry into ASCII and failed miserably. This lesson contains all the knowledge required to reverse engineer any hex coded registry entry that is not encrypted. Have Fun!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.