54READ_RESULT ReadRegistryString( HKEY aRoot,
const wxString& aKey,
const wchar_t* aValueName, wxString& aValue )
76 return ReadRegistryString( HKEY_CURRENT_USER, aKey, aValueName, aValue );
80READ_RESULT ReadClassString(
const wxString& aKey,
const wchar_t* aValueName, wxString& aValue )
82 return ReadRegistryString( HKEY_CLASSES_ROOT, aKey, aValueName, aValue );
134 if( !GetFileVersionInfoW( aPath.wc_str(), 0, size, data.data() )
148 wxString bundledPath = BundledHandlerPath();
150 if( bundledPath.empty() || !wxFileName::FileExists( bundledPath ) )
159 bool missingAssociation =
false;
160 bool foreignOwner =
false;
162 for(
const wchar_t* extension : EXTENSIONS )
165 wxString mergedKey = wxString::Format(
L"%ls\\shellex\\%ls", extension, PREVIEW_HANDLER_IID );
167 switch( ReadClassString( mergedKey,
nullptr, owner ) )
169 case READ_RESULT::MISSING:
170 missingAssociation =
true;
173 case READ_RESULT::READ_ERROR:
177 case READ_RESULT::FOUND:
178 foreignOwner = foreignOwner || owner.CmpNoCase( HANDLER_CLSID ) != 0;
189 wxString registeredPath;
190 wxString inprocKey = wxString::Format(
L"Software\\Classes\\CLSID\\%ls\\InprocServer32", HANDLER_CLSID );
191 wxString mergedInprocKey = wxString::Format(
L"CLSID\\%ls\\InprocServer32", HANDLER_CLSID );
192 READ_RESULT pathResult = ReadClassString( mergedInprocKey,
nullptr, registeredPath );
194 if( pathResult == READ_RESULT::READ_ERROR )
200 if( pathResult == READ_RESULT::MISSING )
206 registeredPath = ExpandRegistryPath( registeredPath );
207 wxFileName registeredFile( registeredPath );
208 wxFileName bundledFile( bundledPath );
209 registeredFile.Normalize( wxPATH_NORM_ABSOLUTE | wxPATH_NORM_DOTS | wxPATH_NORM_CASE | wxPATH_NORM_LONG );
210 bundledFile.Normalize( wxPATH_NORM_ABSOLUTE | wxPATH_NORM_DOTS | wxPATH_NORM_CASE | wxPATH_NORM_LONG );
212 if( registeredFile.GetFullPath().CmpNoCase( bundledFile.GetFullPath() ) != 0 )
222 wxString registeredVersion;
223 READ_RESULT registeredVersionResult = ReadString( inprocKey,
L"KiCadHandlerVersion", registeredVersion );
225 if( registeredVersionResult == READ_RESULT::READ_ERROR )
233 for(
const wchar_t* extension : EXTENSIONS )
236 wxString key = wxString::Format(
L"Software\\Classes\\%ls\\shellex\\%ls", extension, PREVIEW_HANDLER_IID );
237 READ_RESULT ownerResult = ReadString( key,
nullptr, owner );
239 if( ownerResult == READ_RESULT::READ_ERROR )
245 if( ownerResult == READ_RESULT::FOUND && owner.CmpNoCase( HANDLER_CLSID ) != 0 )
253 wxString appIdKey = wxString::Format(
L"Software\\Classes\\AppID\\%ls", HANDLER_APPID );
254 READ_RESULT appIdResult = ReadString( appIdKey,
L"DllSurrogate", surrogate );
256 if( appIdResult == READ_RESULT::READ_ERROR )
263 wxString threadingModel;
264 wxString clsidKey = wxString::Format(
L"Software\\Classes\\CLSID\\%ls", HANDLER_CLSID );
265 READ_RESULT clsidAppIdResult = ReadString( clsidKey,
L"AppID", clsidAppId );
266 READ_RESULT threadingResult = ReadString( inprocKey,
L"ThreadingModel", threadingModel );
268 if( clsidAppIdResult == READ_RESULT::READ_ERROR || threadingResult == READ_RESULT::READ_ERROR )
274 wxString previewHandlerName;
275 READ_RESULT previewListResult = ReadString( wxS(
"Software\\Microsoft\\Windows\\CurrentVersion\\PreviewHandlers" ),
276 HANDLER_CLSID, previewHandlerName );
278 if( previewListResult == READ_RESULT::READ_ERROR )
288 snapshot.
classMetadata = clsidAppIdResult == READ_RESULT::FOUND && threadingResult == READ_RESULT::FOUND
289 && clsidAppId.CmpNoCase( HANDLER_APPID ) == 0
290 && threadingModel.CmpNoCase( wxS(
"Apartment" ) ) == 0
293 snapshot.
previewList = previewListResult == READ_RESULT::FOUND && !previewHandlerName.empty()
310 wxString handlerPath = BundledHandlerPath();
311 HMODULE
module = LoadLibraryExW( handlerPath.wc_str(),
nullptr,
312 LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_DEFAULT_DIRS );
316 aError = wxString::Format( wxS(
"Unable to load the Windows preview handler (error %lu)." ), GetLastError() );
320 using REGISTER_SERVER = HRESULT( STDAPICALLTYPE* )();
321 REGISTER_SERVER registerServer =
reinterpret_cast<REGISTER_SERVER
>( GetProcAddress(
module,
"DllRegisterServer" ) );
322 HRESULT
result = registerServer ? registerServer() : HRESULT_FROM_WIN32( ERROR_PROC_NOT_FOUND );
327 aError = wxString::Format( wxS(
"Windows preview registration failed (0x%08lx)." ),
328 static_cast<unsigned long>(
result ) );
wxString result
Test unit parsing edge cases and error handling.