C++: How to open IShellFolder drive folder from a shortcut - c++

I am using the following command in a shortcut to open my virtual drive in Windows Explorer.
%SystemRoot%\Explorer.exe /e,::{MyExtension CLSID}
The virtual drive uses IShellFolder interface and is a ShellExtension. It has a couple of predefined folders in it.
The problem is that I can open the virtual drive in Windows explorer directly using the above statement but I cannot directly open one of its folders.
This link explains how to open a IShellFolder
http://msdn.microsoft.com/en-us/library/bb776817(VS.85).aspx#
but I am not sure how to use the objectname param
%SystemRoot%\Explorer.exe /e,::{MyExtension CLSID},objectname

I took the GMail Drive Shell extension, installed it, and create a folder inside the namespace. Then I use the above method (/E,::{CLSID}) to create the shortcut and added ",foldername" at the end.
It worked perfectly, I think that you need to check your IPersistFolder::Initialize implementation.

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

ShellExecute to open a special folder (ex: "Libraries\Documents") without knowing the special folder name

I'm making an application to backup the opened folders.
The problem is that if in that folders are some special folders (ex: "Desktop", "Computer", "Libraries\Documents", ...) they will not open.
I know that there are constants for those objects, but I don't know which folders will be opened so making a dictionary with all SpecialNames => SpecialConstant is not a good solution for me.
So the question is:
Is there any WinApi function to retrieve the full path from a short name of a special folder?
P.S. Tried both ShellExecute("open", "Path") and ShellExecute("open", "explorer.exe", "Path")
If you paste the names in the explorer they work, but opening them from C++ doesn't work
Thanks
Libraries are stored in the users %appdata%\Roaming\Microsoft\Windows\Libraries directory as XML files with the names <libraryname>.library-ms (e.g. Pictures.library-ms.) Opening one of these files with ShellExecute opens an Explorer window and shows the library.

Relative path problem for a deployed win32 application

I have written a c++ program and deployed it in say c:\my_app, and my executable's path is c:\my_app\my_app.exe. Say, my_app needs many files such as the_file.txt, which is located in c:\my_app\the_file.txt.
In my executable, I open the txt file as, xx.open("the_file.txt");
Moreover, I have associated my program with let's say .myp extension.
When I'm on Desktop, and want to open a file named example.myp, my program can not see the_file.txt. Because, it (somehow) assumes that it's currently working on Desktop.
Is there any easy way to handle this problem by changing shell command for open in HKEY_CLASSES_ROOT? The naive solution would be to change all file open operations with something like %my_app_location/the_file.txt". I don't want to do that.
Always use a full path name to open a file. In other words, don't open "foo.txt", open "c:\bar\foo.txt". To find the install directory of your EXE use GetModuleFileName(), passing NULL for the module handle.
These days you shouldn't add files to c:\my_app....
Instead use the ProgramData Folder and full paths.
Use SHGetSpecialFolderPathA with CSIDL_COMMON_APPDATA to get the ProgramData folder and the create your program directory and add your files.
You should set current directory for your app's folder with SetCurrentDirectory function. After that you can open file by name without full path

How do I create a file in VC++ 6.0 when UAC is on?

How do I create a file in C++ when UAC is on, but with out running as administrator?
I'm trying to create a text file in the following path: "C:\Programdata\Desktop" in VC++ 6.0 when Vista's UAC is on. However, Createfile(...) failed with 'permission denied'.
When I run the sample application with "run as administrator" it works. But my sample application should not "run as administrator".
Is there any API to give permission to the above path, when UAC is on?
sample code:
const nSize = 100;
CStdioFile file;
CFileException obFileExp;
CString csFilePath(_T("C:\ProgramData\Desktop\sample.txt"));
if (!file.Open( csFilePath , CFile::modeCreate | CFile::modeWrite ,&obFileExp ) )
{
// opening of file failed
TCHAR szErr[nSize];
obFileExp.GetErrorMessage(szErr,nSize);
AfxMessageBox(szErr);
return ;
}
file.WriteString( "welcome" );
file.Close( );
NOTE: UAC should ON and VC++ 6.0 should NOT run as administrator
C:\ProgramData\Desktop is an alias to C:\Users\Public\Desktop - which is the desktop shared by all users, and which is intended to be configured by system administrators.
With UAC enabled there is no way for a Guest, member of the Users group, or non elevated members of the Administrators group to create either files OR folders on the shared desktop without perverting the entire security model of Windows.
It would be, for example, possible to use an administrator account - during a UAC elevation during app setup - to add a Access Control List entry granting mebers of the users group some kind of create/write control to subfolders or files in the Public\Desktop.
So, unless your 'sample program' is trying to demonstrate a method to write files in a shared location from an unelevated account you would be far better off creating your file in the users own desktop - c:\Users\YourUserAccount\Desktop - The path to which you retrieve is using the appropriate (SHGetSpecialFolderLocation) API of course!
If you are not allowed to write something at somewhere, you are JUST NOT ALLOWED. If you can do it someway, it will be hacking.
Having said that, last thing I knew was that applications are allowed to write in programdata in vista. Thats what it is supposed to do. Store program's data. But I am not sure about Desktop folder in it. There is no such standard folder in vista as far as I know.
Please can you elaborate what exactly you are trying to save in that folder?
Have a look at The Manifest File Mechanism.
You can embed a manifest in your exe OR you can have a separate manifest file through which you can control permissions.
As per my knowledge, if UAC is on & you need to write into C:\Program Files" which is a restricted folder You need to have admin privileges.
There is no workaround to it. At the most UAC may virtualize your application thus making your application think its writing to C:\Program Files but in reality it will be writing into the Virtual Folder present in %UserProfile%.
Instead of making the user always do right click-> Run As, you can embed a manifest (using external manifest tool) with privilege set to "RequireAdministrator". So whenever your app is executed a prompt will as user if to allow your app to be elevated or no.
If you have to write to programdata you do not need Admin privileges.