C++ Shell Context Menu Extension - c++

I try to create a context menu extension for windows files/folders. I´ve already tried very much, but nothing worked for me. I already have such an extension for 32-Bit systems, but it´s outdated. I want to recreate it using C++ for 64-Bit systems.
This one was closest to what I want to do: Klick
But this is for 32-Bit systems. After reading the comments, I was able to modify&build it for x64.
Registering it using the system32/regsvr32.exe on my 64-Bit system, tells that it was successfully registered. All the registry entries are created correctly. But the menu item does not appear. I have no clue why...
Can someone help me? I can upload the project for you if you want.
UPDATE
I use the original Project from the link above and changed the following things:
1) set target to "x64"
2) since I couln't compile it, i changed the following things:
2.1) Before the includes in stdafx.h I added:
#define _ATL_NO_UUIDOF
2.2) I changed UINT to UINT_PTR here:
HRESULT CFSBankShellExtension::GetCommandString (
UINT_PTR idCmd,
UINT uFlags,
UINT* pwReserved,
LPSTR pszName,
UINT cchMax )
3) I changed txtfile to * in the .rgs file, so that it should apper on all filetypes.
4) I was able to compile and register it
If you can´t help me, it would be cool if you could upload a template, that will work on x64 system.

This article might help you as it worked out for my project..
Simple shell context menu
Context menus for all files, folders, and drives
You can also hookup context menus to all files, folders, and drives by
adding entries to the file type's *, Directory, and Drive registry
keys. For example, XP PowerToys adds the Open Command Window Here menu
to all folders with the following registry script:
REGEDIT4
[HKEY_CLASSES_ROOT\Directory\shell\cmd] #="Open Command Window Here"
[HKEY_CLASSES_ROOT\Directory\shell\cmd\command] #="cmd.exe /k \"cd
%L\""

Related

Open Public Documents folder in Windows Explorer

I have the following file I need to open in a windows explorer window
C:\Users\Public\Documents\folder1\test.txt
So far opening this file using the above path is fine and I can read it as usual.
However when trying to open this this folder through Windows Explorer using wxExecute((wxChar **)cmd, wxEXEC_ASYNC, NULL); where cmd is the above path(minus the file), It opens to my user documents.
I've tried various Windows API functions to get the path, some including where Public Documents has it's own ID and these still generate the path I already have. Are there any CLI options I can give to Windows Explorer so that it can actually open Public Documents without reverting to my User Documents folder?
First of all, why do you cast your string to wxChar**? This just can't be right.
Second, you should be using wxLaunchDefaultApplication() instead of "raw" wxExecute() in the first place (FWIW wxLaunchDefaultApplication() is a straightforward wrapper for ShellExecute() under MSW, while wxExecute() is much more complicated).
It's undocumented, but has worked across multiple windows Versions since at least XP with the following command line:
explorer.exe /select,"path-to-open"
Note the comma, and make sure the path is quoted. The path may include a file name, in which case that file gets selected.
(With Windows 10, it's actually a good idea to use a file name, since otherwise the parent folder is opened with the specified sub folder selected)
Should be the same with CreateProcess, ShellExecute, or system(), or whatever comfort wxWidgets offer.
Actually turned out to be an issue with wxExec from wxWidgets. Converting the command to a ShellExecute opened it up just fine. Potentially Widgets 2.9.5 can't handle Windows 10's pseudo folders and weirdness?.

Make a Qt/C++ program show its file types as known on Windows

Using Qt 5.9 I codded a spreadsheet program and then created an installer for it by Qt Installer Framework (QtIFW2.0.1). Then I sent the program to many of my friends. They installed the app on their Windows machine and now using it, but they have all have a common problem:
when they save files of the app, those files are shown as "unknown" files on Desktop.
The problem is only with the shape and appearance of the stored files not their functionality, and they are opened by the app if double clicked.
The question is, what changes in the code is needed to have the program make its files' shape/appearance shown known?
For example, we offer the code a specific shape using an image file or like that, to be mapped on the stored files and that way they are shown known.
This has actually nothing to do with Qt or C++ itself. You just need to register your file extension in Windows shell, so it can be understood by other Windows components/shells.
Here is general information about File Types and File Associations under windows.
You need to make some Windows Registry entries which look like this:
example.reg:
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Classes\myfirm.myapp.v1\shell\open\command]
#="c:\path\to\your\app.exe \"%1\""
[HKEY_CURRENT_USER\Software\Classes\.myextension]
#="myfirm.myapp.v1"
Here you can read how it works in general
change myfirm.myapp.v1, .myextension and path to your .exe to your prefered names.
Now Windows will know what the files with extension .myextension should be opened by your app. And if you double click on this files your app will be run with path to file as an argument. You can get it in your main() function
To set icon for your extension add Registry entry in Software\\Classes\\.myextension\\DefaultIcon and set it default value to the full path to your app, so windows can get an icon for extension from your .exe app file.
You can also do it at runtime directly in your app:
QSettings s("HKEY_CURRENT_USER\\SOFTWARE\\CLASSES", QSettings::NativeFormat);
QString path = QDir::toNativeSeparators(qApp->applicationFilePath());
s.setValue(".myextension/DefaultIcon/.", path);
s.setValue(".myextension/.","myfirm.myapp.v1");
s.setValue("myfirm.myapp.v1/shell/open/command/.", QStringLiteral("\"%1\"").arg(path) + " \"%1\"");
EDIT: One more, to do it with Qt Installer look at the answers here

C++ move dll files from root to sub folder

I'm making a program in visual c++. The program relies on some dll files, which I don't want to place in system32. Now the dll files is in the same folder as my .exe, but i would like to move them to a sub folder. The problem is, if I move the files, my application fails to start and comes with this error message:
MyProgram.exe - Unable to Locate Component
This application has failed to start because myDll.dll was not found. Re-installing the application may fix the problem.
I have had the same problem before, where if found a solution, which included adding something to the registry, but i forgot how it worked, and now I can't find the guide again.
Can someone please help me?
There is more than one way to solve this problem. As other mentioned you can modify search path for your application in registry. Sometimes, you don't have rights to write to the registry, or you cannot do it for other reasons, then you can set dll path explicitly, the WinAPI function for that is SetDllDirectory, see MSDN.
Sounds like you're after the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths key. See here for complete information. In short, a string called Path points to a DLL search path. For example if your application was called "MyApp" a .reg file like this would do the trick:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AppPaths\MyApp.exe]
#="C:\\Program Files\\MyCompany\\MyApp\\MyApp.exe"
"Path"="C:\\Program Files\\MyCompany\\MyApp\\DLLs"
I believe this is the article you are looking for:
http://www.codeguru.com/Cpp/W-P/dll/article.php/c99
Each application can now store it own path the registry under the following key:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths
The use the application path, set a key for your application, using ONE.EXE from the example above:
HKEY_LOCAL_MACHINE...\CurrentVersion\App Paths\ONE.exe
Set the (Default) value to the full path of your executable, for example:
C:\Program Files\ONE\ONE.exe
Add a sub-key named Path

programmatically check for subsystem

I have a .exe created with a windows subsystem. I copy that .exe to another .exe, and I run:
editbin.exe /SUBSYSTEM:CONSOLE my.exe
So my intention is to have a .exe that runs with a GUI, and another .exe that is meant for command line operations (no GUI).
How do I check what subsystem is currently active in my C++ code?
Subsystem type (GUI, console, etc.) is stored in the PE header, which you can access via the ImageHlp functions. You can get it with the following code:
// Retrieve the header for the exe. GetModuleHandle(NULL) returns base address
// of exe.
PIMAGE_NT_HEADERS header = ImageNtHeader((PVOID)GetModuleHandle(NULL));
if (header->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI)
{
// Console application.
}
Relevent MSDN entries:
ImageNtHeader
IMAGE_NT_HEADERS
IMAGE_OPTIONAL_HEADER
Look at the ImageLoad function in the Imagehlp library. This returns a LOADED_IMAGE structure which has a IMAGE_NT_HEADERS structure in its FileHeader field. The OptionalHeader field in this structure is an IMAGE_OPTIONAL_HEADER which has a Subsytem filed containg the information that you want.
Far easier than spelunking in your own headers: check if you've got console handles.
For a GUI subsystem app, GetStdHandle() will return NULL handles.

Where can I find the default icons used for folders and applications?

I'm trying to load the default HICON that explorer displays for:
An open folder
An exe that has no embedded default icon of its own. This can also be seen in 'Add/Remove Programs' or 'Programs and Features' as it's called on Vista.
Do you know where these can be found? I think the folder icon might be in the resources of explorer.exe. But have no idea where the default application icon can be retrieved from.
And additionally, do you have any sample code that could load them into HICONs.
I really need this to work on multiple Windows OSs: 2000, XP, Vista, 2008
Thanks for the help so far. I'm on Vista and have looked through Shell32.dll. I don't see an icon in there that looks the same as the default one displayed by an application in explorer. I could be missing it - there are 278 icons to look through - is it definitely in there, or is there some other location I should look?
Use the SHGetFileInfo API.
SHFILEINFO sfi;
SecureZeroMemory(&sfi, sizeof sfi);
SHGetFileInfo(
_T("Doesn't matter"),
FILE_ATTRIBUTE_DIRECTORY,
&sfi, sizeof sfi,
SHGFI_ICON | SHGFI_SMALLICON | SHGFI_USEFILEATTRIBUTES);
will get you the icon handle to the folder icon.
To get the 'open' icon (i.e., the icon where the folder is shown as open), also pass SHGFI_OPENICON in the last parameter to SHGetFileInfo().
[edit]
ignore all answers which tell you to poke around in the registry! Because that won't work reliably, will show the wrong icons if they're customized/skinned and might not work in future windows versions.
Also, if you extract the icons from system dlls/exes you could get into legal troubles because they're copyrighted.
Vista added SHGetStockIconInfo and so on NT6+ its the best way.
Archive of MSDN documentation that shows the available icons
On older platforms, SHGetFileInfo like Stefan says.
If you want to use undocumented stuff, the first 5 or so icons in the system image list includes the default folder and application icon (system image list is NOT shared on NT, but for some reason, all the copies get the first 5 or so icons without asking for them with SHGetFileInfo)
These default icons come from shell32.dll by default, but can be changed in the registry:
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Icons
In Visual Studio:
click on File|Open
select
C:\WINDOWS\System32\Shell32.dll
VS will open the file using the resource explorer. You can now look at all the icon & other resources embedded in shell32.dll.
I think they are in %windir%\system32\SHELL32.dll
Found some code in the internet, try if that works:
HINSTANCE hDll;
hDll = LoadLibrary ( "SHELL32.dll" );
wincl.hIcon = LoadIcon (hDll , MAKEINTRESOURCE ( 1 ));
wincl.hIconSm = LoadIcon (hDll, MAKEINTRESOURCE ( 2 ));
Edit: Windows has a lot more icons in the "moricons.dll", but I think the file and folder icons should all be in the shell32.dll. Remind, that icons in Vista have different resolutions, up to 256x256, so the icon you are looking at a resolution 32x32 might look different then the full resolution version of the same icon.
The user's selected icon can be found in the registry at HKEY_CLASSES_ROOT\Folder\DefaultIcon
By looking up the value here, you'll also pick up if they've changed it for whatever reason.
For folders where a desktop.ini file exists, you'd need to read the IconFile and IconIndex entries.
If you are in MFC, following code for loading icons should work.
HICON hicon;
hicon = LoadIcon(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_ICON1));
In the above example, AfxGetResourceHandle() is the only thing where MFC is used, otherwise LoadIcon is an API call as far as I remember.
Icons are available in windows\system32\shell32.dll
If you have visual studio installed, then visual studio is also shipped with a set of icons at a path like this "C:\Program Files\Microsoft Visual Studio 9.0\Common7\VS2008ImageLibrary"
It's probably in explorer.exe.
it's much easier, just open the shell32.dll with resource hacker
and right-click on "ICONS" and save all icons resource in a directory.
and you'll get all the windows default icons in that directory.
[link]http://www.angusj.com/resourcehacker/[/link]