Closed LRN closed 7 years ago
QuickViewer doesn't put itself into Windows registry
I'd consider this to be a good thing..
BTW, your linked MSDN article mentions that it does not apply to Windows 10. So it's probably not a good idea..
QuickViewer doesn't put itself into Windows registry
I'd consider this to be a good thing..
Image viewers are among the applications that absolutely require OS integration to be of use. All viewers are file-centric (or directory-centric), users should never have to run an application and then open a file from it.
There are other programs, which do not require such integration, and for those programs i would generally agree with you (case in point - Putty; i absolutely loathe the fact that i have to muck around with the registry keys to do batch changes to its settings, and there's no disk file that i can handily move around with it).
BTW, your linked MSDN article mentions that it does not apply to Windows 10. So it's probably not a good idea..
Nah, it's OK. I did specifically mention not to touch HKEY_LOCAL_MACHINE\SOFTWARE\Classes\.foo
keys - that's a big no-no since Windows 10. As the blog post linked in that MSDN article says, you just register your app without changing any existing associations (note how all the instructions i've mentioned don't touch any keys that do not belong to QuickViewer - these will never conflict with any other application), and then call up the OS Settings UI to change default associations. Doing things the "hard" way is still possible, but Windows might be quite miffed, and could even reverse your changes.
Thank you for using QuickViewer.
Since I think that this application is the second image viewer to be added, I did not consider using it as OS default viewer. However I know that there are some people who want to use this app as the default viewer.
In order for QuickViewer to be launched automatically in association with the file on the OS, some kind of registry change is necessary. Especially with Windows Explorer.
According to the discussion so far, it seems that it is no longer necessary to add an explicit registry for a specific extension of HKEY_LOCAL_MACHINE, so I will try to realize it without using it.
If you have other suggestions, please create a new topic and write it there :)
Hi @LRN ,
I wrote a reg file here https://gist.github.com/kanryu/ce4afd8956f33fc9e1b857e7191b7791
By registering this registry file, I confirmed that JPEG file is associated with QuickViewer. However, if we just register this registry file, QuickViewer will not start up by double clicking. It is necessary to select "Change Default Program" from the context menu of JPEG file and change "Default Program". This is a necessary task for each extension.
Is it possible to make settings that omit this work in the registry?
Try this one - https://paste.fedoraproject.org/paste/c8Fc0l2DAmPbdLvEyw~jtg
Hi @LRN . Thanks. I tested the pastebin. but I could not confirm the change of the default application on Windows7 x64.
If you can solve this problem by modifying the registry it will. If we can not, I believe there is no need to forcibly resolve.
I found a setting API here. https://msdn.microsoft.com/ja-jp/library/windows/desktop/bb776337(v=vs.85).aspx
Can this API be used on Windows 8 or later?
Ah, sorry, i didn't realize that you're using Windows 7. The changed .reg file i posted earlier was for Windows 10 (though it shouldn't break anything in 7 either).
Yes, in that case you might need to either do more registry modifications, or use API. SetAppAsDefault()
and its friends, SetAppAsDefaultAll()
and QueryAppIsDefaultAll()
could be used, i guess.
If you want to provide a long list of supported formats with checkboxes (the way nomacs and/or 7zip do), then you'll need to use multiple separate QueryAppIsDefault()
calls to fill out the checkboxes, and then (after the user sets everything up and clicks "OK") multiple calls to SetAppAsDefault()
to change the associations (though i don't see an unset
function there...how are you going to unassociate it later on? Is it even necessary?).
If you want to just set it default for all supported types, then QueryAppIsDefaultAll()
and SetAppAsDefaultAll()
will be sufficient. Found a blog post about this (though i would advise against doing changes in more obscure branches of the registry tree).
An alternative to all that is to just do it all via registry, manually. You can get a better idea of which keys and values need changing by using the RegShot program to record and compare the state of the registry before and after something (the APIs mentioned above, or some third-party application that knows how to register itself is installed) happens. It's a bit unwieldy (RegShot can take minutes to complete its work, often looks like it just hung up, and finds everything that changed, including all the system cruft) and mildly dangerous (there's always the possibility that you'll change something wrong), but it's feasible.
For Windows 10 (and possibly 8, can't be sure) you'll only need the minimal set of registry changes (the .reg file i posted should be sufficient - i call it "minimal set", because i removed all the "nice" items, like user-readable names for the application and types, to emphasize the keys and values that actually matter, and, yes, you must register for .jpg and .jpeg and .png for Windows to consider your program suitable as a "Photo viewer"), and the only API you'll need to (optionally) use is IApplicationActivationManager
as described here, to make the Windows 10 "Default Apps" settings page appear.
@LRN @Hrxn I made it :)
Seems to be working well enough for me on Windows 10. That said, i already had some info in the registry, so the file association in 0.8.3 working on my machine is not a 100% indicator of it working everywhere. You'd need someone else to test this.
As for the nature of this fix, i still think that you should use Qt API to query supported image formats instead of just hardcoding them the way you did. And show the checkboxes in a (scrollable) listview, the way 7zip does, not just put them in a dialog box.
Possible enhancements:
HKEY_CURRENT_USER
instead of HKEY_LOCAL_MACHINE
. As for HKEY_CLASSES_ROOT
, it's actually a merged view, composed of HKEY_LOCAL_MACHINE\Software\Classes
and HKEY_CURRENT_USER\Software\Classes
. You'll have to be careful about requesting elevation, because when you run as admin, HKEY_CURRENT_USER is an alias for the admin registry branch, not for the branch of your normal user account. Again, 7zip offers you separate associations for the whole machine ("All users") and only your own account, but doing it for the whole machine requires administrative privileges, and fails if you lack them (the way around this is to explicitly run 7zip file manager as admin, and i still think that this is bad UX). If you request elevation using some kind of API, then it should be possible to make that conditional on the commandline options to the file associations program. If you request elevation purely by making the associations program an always-run-as-admin kind of program (which seems to be the case)...I don't know. Duplicate the code? This sounds bad either way...Probably the cleanest way is to change the association program to not be an always-run-as-admin and instead run it as admin explicitly when you need it to modify stuff that requires privileges (and run it not as admin when you don't), then inside the program do a check for the current privilege level, and display the UI differently depending on its outcome. This example totally works for me. You might be able to actually show the UI inside QuickViewer normally, but do the registry modification inside a helper program that lacks the UI, receives instructions from the parent app, and it started with or without admin privileges after the user clicks "apply" or "ok", depending on the user choices..ico
and .tiff
, for example, or any multipage formats - see https://bugreports.qt.io/browse/QTBUG-1364 )I now know that you can set file associations using HKEY_CURRENT_USER for the first time. That's because I did not find such a description in the MSDN article that you first presented.
There is a big restriction on reading / writing of registry by Qt and switching of UAC, and it is restriction of development.
Since the procedure to rewrite the registry with QSettings was officially no document at all, we decided how to implement by fumbling by checking the SDK source code.
Changing the authority of UAC by QProcess :: startDetached () is very restrictive. You have to set up a program to forcibly execute UAC by /MANIFESTUAC option of the compiler on the started program. In this case you will not be able to launch with normal authority as you claim.
To avoid such restrictions, as you often do in other parts of QuickViewer, I was giving up Qt implementation directly and running Win32 API directly, but of course such programs are not portable.
QuickViewer is not compatible with the second case, where multiple images are included in one file, and for the time being, we do not have that plan. Animation can be played, but it is an exceptional solution.
Because of this it can't be assigned as default viewer for images. The OS has absolutely zero knowledge of the fact that QuickViewer even exists.
How to fix: Follow the MSDN article and put QuickViewer information into registry. Specifically to QuickViewer, i would propose this way of creating filetype keys:
QImageReader::supportedMimeTypes()
to get the list of supported MIME/type stringsQMimeDatabase::mimeTypeForName()
to getQMimeType
object that represents that MIME/typeQMimeType
object callQMimeType::comment()
to get its human-readable name (description) andQMimeType::suffixes()
to get the list of its usual suffixes (i.e. file extensions)foo/bar
create the following key:HKEY_LOCAL_MACHINE\SOFTWARE\Classes\QuickViewer.AssocFile.foo_bar
(replacing '/' with '', and doing any other necessary substitutions to remove characters that are illegal in key names), set its (Default)_ value to the human-readable description obtained fromQMimeType
.ico
file or an.ico
file stored as a resource in a DLL), createHKEY_LOCAL_MACHINE\SOFTWARE\Classes\QuickViewer.AssocFile.foo_bar\DefaultIcon
and set its (Default) value to the icon path (path to.ico
file orpath\to\file.dll,x
wherex
is the resource index)HKEY_LOCAL_MACHINE\SOFTWARE\Classes\QuickViewer.AssocFile.foo_bar\shell\open
, set its (Default) value to"View with QuickViewer"
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\QuickViewer.AssocFile.foo_bar\shell\open\command
, set its (Default) value to"path\to\quickviewer.exe" "%1"
HKEY_LOCAL_MACHINE\SOFTWARE\QuickViewer
(MSDN article describes this in more detail), then createHKEY_LOCAL_MACHINE\SOFTWARE\QuickViewer\Capabilities
(again, fill out the values as required -ApplicationDescription
,ApplicationIcon
,ApplicationName
etc), thenHKEY_LOCAL_MACHINE\SOFTWARE\QuickViewer\Capabilities\FileAssociations
foo
that is a possible suffix for MIME/typefoo/bar
create a string value named.foo
and set it toQuickViewer.AssocFile.foo_bar
HKEY_LOCAL_MACHINE\SOFTWARE\RegisteredApplications
key (if it doesn't exist) and set itsQuickViewer
value toSoftware\QuickViewer\Capabilities
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\QuickViewer.AssocFile.*
keys and delete the ones that do not correspond to supported MIME/types.This can be done from the QuickViewer application itself, somewhere in Options. Consider doing two buttons (one does all of the above, the other does all of the above, but in HKEY_CURRENT_USER tree instead of HKEY_LOCAL_MACHINE; the former will require administrative privileges, obviously). Either way, after doing all this the button should call up the OS Default Applications Settings window (i forgot how to do that; there should be an API, or maybe you can run something to make it appear; google for it)
Human-readable strings can be localized.
Apart from
FileAssociations
subkey there's alsoMimeAssociations
, but i'm not sure how useful they would be, as Windows doesn't seem to be able to launch stuff based on MIME/types in most circumstances.HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Applications\QuickViewer
(as mentioned in MSDN article) creation will only allow QuickViewer to be present in OpenWith list, but it could be a good starting point.I have no idea whether Qt has API for working with the registry. If it doesn't, you'll have to use W32 API.
Another developer quickstart trick - write stuff into .reg file (it's UTF-16-LE-encoded, without BOM) instead of actually creating keys and values in the registry, then you can load this file into the registry manually and check how it works, without mucking around with the registry APIs.
Install some application that already knows how to do this, then observe the keys it creates. That should help a lot.
Don't touch
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\.foo
and other keys that start with a.