4#include "Stroika/Frameworks/StroikaPreComp.h"
8#include "Windows_FileRegistration.h"
12using namespace Stroika::Frameworks;
13using namespace Stroika::Frameworks::Led;
14using namespace Stroika::Frameworks::Led::Platform;
18#if qStroika_Foundation_Common_Platform_Windows
20inline void ThrowIfRegError (LONG e)
22 if (e != ERROR_SUCCESS) {
32inline Win32FileAssociationRegistrationHelper::KeyHolder::KeyHolder (HKEY hk)
36inline Win32FileAssociationRegistrationHelper::KeyHolder::KeyHolder (HKEY baseKey, LPCTSTR lpSubKey)
39 ThrowIfRegError (::RegOpenKey (baseKey, lpSubKey, &fKey));
41inline Win32FileAssociationRegistrationHelper::KeyHolder::KeyHolder (HKEY baseKey, LPCTSTR lpSubKey, [[maybe_unused]] CreateIfNotThereFlag createIfNotThereFlag)
44 Assert (createIfNotThereFlag == eCreateIfNotThere);
46 ThrowIfRegError (::RegCreateKeyEx (baseKey, lpSubKey, 0, REG_NONE, REG_OPTION_NON_VOLATILE, KEY_WRITE | KEY_READ, NULL, &fKey, &ignored));
48inline Win32FileAssociationRegistrationHelper::KeyHolder::~KeyHolder ()
52inline Win32FileAssociationRegistrationHelper::KeyHolder::operator HKEY ()
62Win32FileAssociationRegistrationHelper::Win32FileAssociationRegistrationHelper (
const SDKString& fileSuffix)
63 : fFileSuffix (fileSuffix)
67SDKString Win32FileAssociationRegistrationHelper::GetAssociatedProgID ()
const
71 ThrowIfRegError (::RegQueryValue (HKEY_CLASSES_ROOT, fFileSuffix.c_str (), NULL, &itemLen));
72 StackBuffer<Characters::SDKChar> buf{Memory::eUninitialized,
static_cast<size_t> (itemLen + 1)};
73 ThrowIfRegError (::RegQueryValue (HKEY_CLASSES_ROOT, fFileSuffix.c_str (), buf.data (), &itemLen));
81SDKString Win32FileAssociationRegistrationHelper::GetAssociatedDefaultIcon ()
const
84 SDKString progID = GetAssociatedProgID ();
85 KeyHolder progIDKey (HKEY_CLASSES_ROOT, progID.c_str ());
87 ThrowIfRegError (::RegQueryValue (progIDKey, Led_SDK_TCHAROF (
"DefaultIcon"), NULL, &itemLen));
88 StackBuffer<Characters::SDKChar> buf{Memory::eUninitialized,
static_cast<size_t> (itemLen + 1)};
89 ThrowIfRegError (::RegQueryValue (progIDKey, Led_SDK_TCHAROF (
"DefaultIcon"), buf.data (), &itemLen));
97SDKString Win32FileAssociationRegistrationHelper::GetAssociatedEditCommand ()
const
100 SDKString progID = GetAssociatedProgID ();
101 KeyHolder progIDKey (HKEY_CLASSES_ROOT, progID.c_str ());
102 KeyHolder shellKey (progIDKey, Led_SDK_TCHAROF (
"shell"));
103 KeyHolder openKey (shellKey, Led_SDK_TCHAROF (
"edit"));
105 ThrowIfRegError (::RegQueryValue (openKey, Led_SDK_TCHAROF (
"command"), NULL, &itemLen));
106 StackBuffer<Characters::SDKChar> buf{Memory::eUninitialized,
static_cast<size_t> (itemLen + 1)};
107 ThrowIfRegError (::RegQueryValue (openKey, Led_SDK_TCHAROF (
"command"), buf.data (), &itemLen));
115SDKString Win32FileAssociationRegistrationHelper::GetAssociatedOpenCommand ()
const
118 SDKString progID = GetAssociatedProgID ();
119 KeyHolder progIDKey (HKEY_CLASSES_ROOT, progID.c_str ());
120 KeyHolder shellKey (progIDKey, Led_SDK_TCHAROF (
"shell"));
121 KeyHolder openKey (shellKey, Led_SDK_TCHAROF (
"open"));
123 ThrowIfRegError (::RegQueryValue (openKey, Led_SDK_TCHAROF (
"command"), NULL, &itemLen));
124 StackBuffer<Characters::SDKChar> buf{Memory::eUninitialized,
static_cast<size_t> (itemLen + 1)};
125 ThrowIfRegError (::RegQueryValue (openKey, Led_SDK_TCHAROF (
"command"), buf.data (), &itemLen));
133void Win32FileAssociationRegistrationHelper::SetAssociatedProgIDAndOpenCommand (
const SDKString& progID,
const SDKString& progIDPrettyName,
134 const SDKString& defaultIcon,
const SDKString& editCommandLine,
135 const SDKString& openCommandLine)
140 ThrowIfRegError (::RegSetValue (HKEY_CLASSES_ROOT, fFileSuffix.c_str (), REG_SZ, progID.c_str (),
static_cast<DWORD
> (progID.length ())));
145 ThrowIfRegError (::RegSetValue (HKEY_CLASSES_ROOT, progID.c_str (), REG_SZ, progIDPrettyName.c_str (),
146 static_cast<DWORD
> (progIDPrettyName.length ())));
148 KeyHolder progIDKey (HKEY_CLASSES_ROOT, progID.c_str (), KeyHolder::eCreateIfNotThere);
149 if (defaultIcon != Win32UIFileAssociationInfo::kNoChange) {
150 ThrowIfRegError (::RegSetValue (progIDKey, Led_SDK_TCHAROF (
"DefaultIcon"), REG_SZ, defaultIcon.c_str (),
151 static_cast<DWORD
> (defaultIcon.length ())));
153 if (editCommandLine != Win32UIFileAssociationInfo::kNoChange) {
154 KeyHolder shellKey (progIDKey, Led_SDK_TCHAROF (
"shell"), KeyHolder::eCreateIfNotThere);
155 KeyHolder openKey (shellKey, Led_SDK_TCHAROF (
"edit"), KeyHolder::eCreateIfNotThere);
156 ThrowIfRegError (::RegSetValue (openKey, Led_SDK_TCHAROF (
"command"), REG_SZ, editCommandLine.c_str (),
157 static_cast<DWORD
> (editCommandLine.length ())));
159 if (openCommandLine != Win32UIFileAssociationInfo::kNoChange) {
160 KeyHolder shellKey (progIDKey, Led_SDK_TCHAROF (
"shell"), KeyHolder::eCreateIfNotThere);
161 KeyHolder openKey (shellKey, Led_SDK_TCHAROF (
"open"), KeyHolder::eCreateIfNotThere);
162 ThrowIfRegError (::RegSetValue (openKey, Led_SDK_TCHAROF (
"command"), REG_SZ, openCommandLine.c_str (),
163 static_cast<DWORD
> (openCommandLine.length ())));
172SDKString Win32UIFileAssociationInfo::kNoChange;
173Win32UIFileAssociationInfo::Win32UIFileAssociationInfo (
const SDKString& fileSuffix,
const SDKString& fileProgID,
const SDKString& fileProgIDPrettyName,
174 const SDKString& defaultIcon,
const SDKString& shellEditNOpenCommandLine)
175 : fFileSuffix{fileSuffix}
176 , fFileProgID{fileProgID}
177 , fFileProgIDPrettyName{fileProgIDPrettyName}
178 , fDefaultIcon{defaultIcon}
179 , fShellEditCommandLine{shellEditNOpenCommandLine}
180 , fShellOpenCommandLine{shellEditNOpenCommandLine}
184Win32UIFileAssociationInfo::Win32UIFileAssociationInfo (
const SDKString& fileSuffix,
const SDKString& fileProgID,
185 const SDKString& fileProgIDPrettyName,
const SDKString& defaultIcon,
186 const SDKString& shellEditCommandLine,
const SDKString& shellOpenCommandLine)
187 : fFileSuffix (fileSuffix)
188 , fFileProgID (fileProgID)
189 , fFileProgIDPrettyName (fileProgIDPrettyName)
190 , fDefaultIcon (defaultIcon)
191 , fShellEditCommandLine (shellEditCommandLine)
192 , fShellOpenCommandLine (shellOpenCommandLine)
201Win32UIFileAssociationRegistrationHelper::Win32UIFileAssociationRegistrationHelper (HINSTANCE hInstance)
202 : fHINSTANCE (hInstance)
207Win32UIFileAssociationRegistrationHelper::Win32UIFileAssociationRegistrationHelper (HINSTANCE hInstance,
const vector<Win32UIFileAssociationInfo>& infoRecs)
208 : fHINSTANCE (hInstance)
209 , fInfoRecs (infoRecs)
213void Win32UIFileAssociationRegistrationHelper::Add (
const Win32UIFileAssociationInfo& infoRec)
215 fInfoRecs.push_back (infoRec);
218void Win32UIFileAssociationRegistrationHelper::DoIt () noexcept
224 bool doRegister =
true;
225 if (RegisteredToSomeoneElse () and not CheckUserSaysOKToUpdate ()) {
229 ApplyChangesSilently ();
236bool Win32UIFileAssociationRegistrationHelper::RegisteredToSomeoneElse ()
const
238 for (
auto i = fInfoRecs.begin (); i != fInfoRecs.end (); ++i) {
247 Win32FileAssociationRegistrationHelper registryAssoc ((*i).fFileSuffix);
248 SDKString progid = registryAssoc.GetAssociatedProgID ();
249 SDKString assocEditCmd = registryAssoc.GetAssociatedEditCommand ();
250 SDKString assocOpenCmd = registryAssoc.GetAssociatedOpenCommand ();
251 SDKString editCommandLine = (*i).fShellEditCommandLine;
252 SDKString openCommandLine = (*i).fShellOpenCommandLine;
253 ExpandVariables (&editCommandLine);
254 ExpandVariables (&openCommandLine);
255 if (progid != (*i).fFileProgID or (not editCommandLine.empty () and assocEditCmd != editCommandLine) or
256 (not openCommandLine.empty () and assocOpenCmd != openCommandLine)) {
267void Win32UIFileAssociationRegistrationHelper::ApplyChangesSilently ()
270 for (
auto i = fInfoRecs.begin (); i != fInfoRecs.end (); ++i) {
271 Win32FileAssociationRegistrationHelper registryAssoc ((*i).fFileSuffix);
272 SDKString defaultIcon = (*i).fDefaultIcon;
273 SDKString editCommandLine = (*i).fShellEditCommandLine;
274 SDKString openCommandLine = (*i).fShellOpenCommandLine;
275 ExpandVariables (&defaultIcon);
276 ExpandVariables (&editCommandLine);
277 ExpandVariables (&openCommandLine);
279 registryAssoc.SetAssociatedProgIDAndOpenCommand ((*i).fFileProgID, (*i).fFileProgIDPrettyName, defaultIcon, editCommandLine, openCommandLine);
288bool Win32UIFileAssociationRegistrationHelper::CheckUserSaysOKToUpdate ()
const
295void Win32UIFileAssociationRegistrationHelper::ExpandVariables (SDKString* valWithVars)
const
301 if ((varAt = valWithVars->find (Led_SDK_TCHAROF (
"$EXE$"))) != SDKString::npos) {
302 TCHAR szLongPathName[_MAX_PATH];
303 ::GetModuleFileName (fHINSTANCE, szLongPathName, _MAX_PATH);
304 valWithVars->replace (varAt, 5, szLongPathName);
Logically halfway between std::array and std::vector; Smart 'direct memory array' - which when needed...
basic_string< SDKChar > SDKString