55READ_RESULT ReadRegistryString( HKEY aRoot,
const wxString& aKey,
const wchar_t* aValueName, wxString& aValue )
77 return ReadRegistryString( HKEY_CURRENT_USER, aKey, aValueName, aValue );
81READ_RESULT ReadClassString(
const wxString& aKey,
const wchar_t* aValueName, wxString& aValue )
83 return ReadRegistryString( HKEY_CLASSES_ROOT, aKey, aValueName, aValue );
135 if( !GetFileVersionInfoW( aPath.wc_str(), 0, size, data.data() )
149 wxString bundledPath = BundledHandlerPath();
151 if( bundledPath.empty() || !wxFileName::FileExists( bundledPath ) )
160 bool missingAssociation =
false;
161 bool foreignOwner =
false;
163 for(
const wchar_t* extension : EXTENSIONS )
166 wxString mergedKey = wxString::Format(
L"%ls\\shellex\\%ls", extension, PREVIEW_HANDLER_IID );
168 switch( ReadClassString( mergedKey,
nullptr, owner ) )
170 case READ_RESULT::MISSING:
171 missingAssociation =
true;
174 case READ_RESULT::READ_ERROR:
178 case READ_RESULT::FOUND:
179 foreignOwner = foreignOwner || owner.CmpNoCase( HANDLER_CLSID ) != 0;
190 wxString registeredPath;
191 wxString inprocKey = wxString::Format(
L"Software\\Classes\\CLSID\\%ls\\InprocServer32", HANDLER_CLSID );
192 wxString mergedInprocKey = wxString::Format(
L"CLSID\\%ls\\InprocServer32", HANDLER_CLSID );
193 READ_RESULT pathResult = ReadClassString( mergedInprocKey,
nullptr, registeredPath );
195 if( pathResult == READ_RESULT::READ_ERROR )
201 if( pathResult == READ_RESULT::MISSING )
207 registeredPath = ExpandRegistryPath( registeredPath );
208 wxFileName registeredFile( registeredPath );
209 wxFileName bundledFile( bundledPath );
210 registeredFile.Normalize( wxPATH_NORM_ABSOLUTE | wxPATH_NORM_DOTS | wxPATH_NORM_CASE | wxPATH_NORM_LONG );
211 bundledFile.Normalize( wxPATH_NORM_ABSOLUTE | wxPATH_NORM_DOTS | wxPATH_NORM_CASE | wxPATH_NORM_LONG );
213 if( registeredFile.GetFullPath().CmpNoCase( bundledFile.GetFullPath() ) != 0 )
223 wxString registeredVersion;
224 READ_RESULT registeredVersionResult = ReadString( inprocKey,
L"KiCadHandlerVersion", registeredVersion );
226 if( registeredVersionResult == READ_RESULT::READ_ERROR )
234 for(
const wchar_t* extension : EXTENSIONS )
237 wxString key = wxString::Format(
L"Software\\Classes\\%ls\\shellex\\%ls", extension, PREVIEW_HANDLER_IID );
238 READ_RESULT ownerResult = ReadString( key,
nullptr, owner );
240 if( ownerResult == READ_RESULT::READ_ERROR )
246 if( ownerResult == READ_RESULT::FOUND && owner.CmpNoCase( HANDLER_CLSID ) != 0 )
254 wxString appIdKey = wxString::Format(
L"Software\\Classes\\AppID\\%ls", HANDLER_APPID );
255 READ_RESULT appIdResult = ReadString( appIdKey,
L"DllSurrogate", surrogate );
257 if( appIdResult == READ_RESULT::READ_ERROR )
264 wxString threadingModel;
265 wxString clsidKey = wxString::Format(
L"Software\\Classes\\CLSID\\%ls", HANDLER_CLSID );
266 READ_RESULT clsidAppIdResult = ReadString( clsidKey,
L"AppID", clsidAppId );
267 READ_RESULT threadingResult = ReadString( inprocKey,
L"ThreadingModel", threadingModel );
269 if( clsidAppIdResult == READ_RESULT::READ_ERROR || threadingResult == READ_RESULT::READ_ERROR )
275 wxString previewHandlerName;
276 READ_RESULT previewListResult = ReadString( wxS(
"Software\\Microsoft\\Windows\\CurrentVersion\\PreviewHandlers" ),
277 HANDLER_CLSID, previewHandlerName );
279 if( previewListResult == READ_RESULT::READ_ERROR )
289 snapshot.
classMetadata = clsidAppIdResult == READ_RESULT::FOUND && threadingResult == READ_RESULT::FOUND
290 && clsidAppId.CmpNoCase( HANDLER_APPID ) == 0
291 && threadingModel.CmpNoCase( wxS(
"Apartment" ) ) == 0
294 snapshot.
previewList = previewListResult == READ_RESULT::FOUND && !previewHandlerName.empty()
311 wxString handlerPath = BundledHandlerPath();
312 HMODULE
module = LoadLibraryExW( handlerPath.wc_str(),
nullptr,
313 LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_DEFAULT_DIRS );
317 aError = wxString::Format( wxS(
"Unable to load the Windows preview handler (error %lu)." ), GetLastError() );
321 using REGISTER_SERVER = HRESULT( STDAPICALLTYPE* )();
322 REGISTER_SERVER registerServer =
reinterpret_cast<REGISTER_SERVER
>( GetProcAddress(
module,
"DllRegisterServer" ) );
323 HRESULT
result = registerServer ? registerServer() : HRESULT_FROM_WIN32( ERROR_PROC_NOT_FOUND );
328 aError = wxString::Format( wxS(
"Windows preview registration failed (0x%08lx)." ),
329 static_cast<unsigned long>(
result ) );
wxString result
Test unit parsing edge cases and error handling.