private void OnAssemblyDownloaded(Stream data) { RemoteCheckProgress.IsIndeterminate = false; if (data == null || data.Length == 0) return; var definition = AssemblyDefinition.ReadAssembly(data, new ReaderParameters(ReadingMode.Immediate)); if (definition == null || !definition.FullName.Equals(_reference.FullName, StringComparison.OrdinalIgnoreCase)) { RemoteCheckLabel.Text = "Failed to download assembly."; BrowseButton.IsEnabled = true; DownloadButton.IsEnabled = true; return; } string fileName = definition.Name.Name + ".dll"; // TODO: take into account partial trust in-browser mode string assemblyPath = Definition.IsSilverlight() ? StorageService.CacheSilverlightAssembly(fileName, data) : StorageService.CacheNetAssembly(fileName, data); var assemblyStream = new AssemblyMemoryStream(fileName, data); ApplicationModel.Current.AssemblyCache.LoadAssembly(assemblyStream, definition); Definition = definition; DialogResult = true; }
// TODO: add possibility to clear cache from UI // TODO: Silvelright 5 will allow accessing local system files without COM hacks! public static AssemblyDefinition FindExternalAssembly(AssemblyNameReference reference, Dispatcher dispatcher) { // TODO: add support User folders /* * User folders can be accessed without Automation Factory so it should be possible to * define a reference path based on User folders hierarchy. In this case this feature will work * for MacOs platforms. * * Possible ways to implement: * * 1. Allow "Reference Paths" tab to be visible when running on Macs * 2. When adding reference path a check should be performed (whether path belongs to User folder hierarchy) * 3. The paths that do not belong to User folder hierachy should not be added (Macs only, provide some warning/notification) * * Reference caching should also work fine for User folders. */ if (!Application.Current.HasElevatedPermissions) { return(null); } if (!AutomationFactory.IsAvailable) { return(null); } if (reference == null) { return(null); } var referencePaths = ReferencePathsSettings.Current.Folders.ToArray(); var targetName = string.Format("{0}.dll", reference.Name); try { var savedPath = GetCachedPath(reference); // TODO: optimize code and remove duplication if (!string.IsNullOrEmpty(savedPath)) { using (var stream = LoadFile(savedPath)) { var definition = AssemblyDefinition.ReadAssembly(stream); if (definition != null && definition.FullName == reference.FullName) { Debug.WriteLine("Successfully resolved external assembly from cache: {0}", savedPath); var assemblyStream = new AssemblyMemoryStream(targetName, stream); dispatcher.BeginInvoke(() => ApplicationModel.Current.AssemblyCache.LoadAssembly(assemblyStream, definition)); return(definition); } } } var fso = AutomationFactory.CreateObject("Scripting.FileSystemObject"); foreach (var referenceFolder in referencePaths) { var file = FindFile(fso, referenceFolder.Path, targetName, referenceFolder.RecursiveSearch); if (file == null) { continue; } string path = file.Path; using (var stream = LoadFile(path)) { var definition = AssemblyDefinition.ReadAssembly(stream); if (definition == null) { continue; } if (definition.FullName != reference.FullName) { continue; } Debug.WriteLine("Successfully resolved external assembly: {0}", path); AddCachedPath(reference, path); var assemblyStream = new AssemblyMemoryStream(targetName, stream); dispatcher.BeginInvoke(() => ApplicationModel.Current.AssemblyCache.LoadAssembly(assemblyStream, definition)); return(definition); } } } catch { if (Debugger.IsAttached) { Debugger.Break(); } return(null); } return(null); }
// TODO: add possibility to clear cache from UI // TODO: Silvelright 5 will allow accessing local system files without COM hacks! public static AssemblyDefinition FindExternalAssembly(AssemblyNameReference reference, Dispatcher dispatcher) { // TODO: add support User folders /* * User folders can be accessed without Automation Factory so it should be possible to * define a reference path based on User folders hierarchy. In this case this feature will work * for MacOs platforms. * * Possible ways to implement: * * 1. Allow "Reference Paths" tab to be visible when running on Macs * 2. When adding reference path a check should be performed (whether path belongs to User folder hierarchy) * 3. The paths that do not belong to User folder hierachy should not be added (Macs only, provide some warning/notification) * * Reference caching should also work fine for User folders. */ if (!Application.Current.HasElevatedPermissions) return null; if (!AutomationFactory.IsAvailable) return null; if (reference == null) return null; var referencePaths = ReferencePathsSettings.Current.Folders.ToArray(); var targetName = string.Format("{0}.dll", reference.Name); try { var savedPath = GetCachedPath(reference); // TODO: optimize code and remove duplication if (!string.IsNullOrEmpty(savedPath)) { using (var stream = LoadFile(savedPath)) { var definition = AssemblyDefinition.ReadAssembly(stream); if (definition != null && definition.FullName == reference.FullName) { Debug.WriteLine("Successfully resolved external assembly from cache: {0}", savedPath); var assemblyStream = new AssemblyMemoryStream(targetName, stream); dispatcher.BeginInvoke(() => ApplicationModel.Current.AssemblyCache.LoadAssembly(assemblyStream, definition)); return definition; } } } var fso = AutomationFactory.CreateObject("Scripting.FileSystemObject"); foreach (var referenceFolder in referencePaths) { var file = FindFile(fso, referenceFolder.Path, targetName, referenceFolder.RecursiveSearch); if (file == null) continue; string path = file.Path; using (var stream = LoadFile(path)) { var definition = AssemblyDefinition.ReadAssembly(stream); if (definition == null) continue; if (definition.FullName != reference.FullName) continue; Debug.WriteLine("Successfully resolved external assembly: {0}", path); AddCachedPath(reference, path); var assemblyStream = new AssemblyMemoryStream(targetName, stream); dispatcher.BeginInvoke(() => ApplicationModel.Current.AssemblyCache.LoadAssembly(assemblyStream, definition)); return definition; } } } catch { if (Debugger.IsAttached) Debugger.Break(); return null; } return null; }