/// <summary> /// Dynamically load assemblies into the API based on what interfaces they implement. Used to allow /// 3rd parties to add custom CapabilitySenders and CapabilityViewers without recompiling the application /// or changing its source code. /// </summary> /// <remarks> /// Because this section of code frequently excepts when a developer is creating a new Capability and does something wrong, /// we both write to the event log and display a message box so that the developer can find the error quickly. In experience, /// just writing to the event log causes failures that new developers don't easily find. /// </remarks> public static void InitializeCapabilityClasses(out CapabilityViewerClassHashtable capabilityViewerClasses, out CapabilitySenderClassHashtable capabilitySenderClasses) { // Initialize outbound parameters capabilityViewerClasses = new CapabilityViewerClassHashtable(); capabilitySenderClasses = new CapabilitySenderClassHashtable(); #region Default RTDocs viewer from app.config // Before starting to iterate through .dll's, check to see if a default // RTDocument CapabilityViewer is identified in app.config. If one is // found in app.config, and there is not already a default stored in // the registry, then set this one as the default. RegistryKey rtdocskey = Registry.CurrentUser.CreateSubKey("SOFTWARE\\Microsoft Research\\ConferenceXP\\Client\\" + System.Reflection.Assembly.GetEntryAssembly().CodeBase + "\\CapabilityViewers"); string appconfigEntry; if ((appconfigEntry = ConfigurationManager.AppSettings[AppConfig.CXP_RTDocumentViewerDefault]) != null) { // We only use the app.config setting if there is not already an entry marked as default // in the registry string[] names = rtdocskey.GetValueNames(); bool defExists = false; foreach (string key in names) { object val = rtdocskey.GetValue(key); if (val.ToString() == "default") { defExists = true; break; } } if (!defExists) { rtdocskey.SetValue(appconfigEntry, "default"); } } #endregion Default RTDocs viewer from app.config // Get the directory of the executing .exe DirectoryInfo diExe = new FileInfo(Assembly.GetExecutingAssembly().Location).Directory; // Find all the DLLs in that directory, looping through them all FileInfo[] fis = diExe.GetFiles("*.dll"); foreach (FileInfo fiDll in fis) { try { // Load each DLL into memory, getting a list of all root types (including classes and interfaces) Type[] types = Assembly.LoadFrom(fiDll.FullName).GetTypes(); foreach (Type type in types) { // You can't instantiate an abstract class if (type.IsAbstract) { continue; } // If the class defines "IsRunable" (inherited through Capability), run it and check // that this class can be run on the current machine. If not, skip the class. if (type.IsSubclassOf(typeof(MSR.LST.ConferenceXP.Capability))) { PropertyInfo runableProp = type.GetProperty("IsRunable", BindingFlags.Static | BindingFlags.Public); if (runableProp != null) // if the dll was compiled off of old code, it won't have "IsRunable" { MethodInfo getRunableMethod = runableProp.GetGetMethod(); object returnObj = getRunableMethod.Invoke(null, null); if (!(returnObj is bool) || (((bool)returnObj) == false)) { continue; // Skip this type becuase its own method says it isn't runable. } } } // Check required capability attributes Type iCV = type.GetInterface("MSR.LST.ConferenceXP.ICapabilityViewer"); Type iCS = type.GetInterface("MSR.LST.ConferenceXP.ICapabilitySender"); Capability.PayloadTypeAttribute pt = null; Capability.NameAttribute capabilityName = null; if (iCV != null || iCS != null) { pt = (Capability.PayloadTypeAttribute)Attribute.GetCustomAttribute(type, typeof(Capability.PayloadTypeAttribute)); capabilityName = (Capability.NameAttribute)Attribute.GetCustomAttribute(type, typeof(Capability.NameAttribute)); // Without a payload type and a name, it is invalidly constructed if (null == pt || null == capabilityName) { continue; } } // Does it have an ICapabilityViewer interface? if (iCV != null) { AddCapabilityViewerClass(fiDll.Name, type, capabilityName.Name, capabilityViewerClasses, pt, rtdocskey); } // Does it have an ICapabilitySender interface? if (iCS != null) { AddCapabilitySenderClass(fiDll.Name, type, capabilityName.Name, capabilitySenderClasses); } } // end foreach tBaseType } // Some DLLs in the directory may not be .NET Assemblies (like msvcrt70.dll), and they will throw a BadImageFormatException here if not. catch (BadImageFormatException) {} // Perhaps a bad or old .Net Dll is here, ignore it. This was firing for Shockwave Flash COM interop assemblies catch (TypeInitializationException) {} // Trying to reload an already loaded Dll, occurs for Conference.Dll, so just continue on... catch (ReflectionTypeLoadException) {} } rtdocskey.Flush(); }
private void ObjectReceived(object capability, ObjectReceivedEventArgs ea) { if (ea.Data is FileObject) { FileObject fileObject = ea.Data as FileObject; FileInfo fileInfo = new FileInfo(fileObject.Name); Type tCapability = null; ItemReceivedDialog dlgFileReceived = null; if (tCapability != null) { Capability.NameAttribute attrName = (Capability.NameAttribute) Attribute.GetCustomAttribute(tCapability, typeof(Capability.NameAttribute)); Capability.PayloadTypeAttribute attrPT = (Capability.PayloadTypeAttribute) Attribute.GetCustomAttribute(tCapability, typeof(Capability.PayloadTypeAttribute)); dlgFileReceived = new ItemReceivedDialog(Strings.CapabilityReceived, Strings.UserSentYouCapability); dlgFileReceived.Button1Label = Strings.InstallHotkey; dlgFileReceived.FileIconTip = string.Format(CultureInfo.CurrentCulture, Strings.CapabilityNamePayloadType, attrName.Name, attrPT.PayloadType.ToString()); } else { dlgFileReceived = new ItemReceivedDialog(Strings.FileReceived, Strings.UserSentYouFile); } dlgFileReceived.Image = Image.FromStream( System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("MSR.LST.ConferenceXP.Images.FileReceived.gif")); dlgFileReceived.From = ea.Participant.Name; dlgFileReceived.Avatar = ea.Participant.Icon; dlgFileReceived.AvatarTip = Strings.AvatarTipText; dlgFileReceived.File = fileInfo.Name; dlgFileReceived.FileIcon = fileObject.Icon; dlgFileReceived.FileIconTip += string.Format(CultureInfo.CurrentCulture, Strings.FileSize, ((double)fileObject.Data.Length / 1024.0).ToString("#,#.00", CultureInfo.CurrentCulture)); dlgFileReceived.Time = DateTime.Now.ToString("h:mm:ss tt", CultureInfo.CurrentCulture); if (dlgFileReceived.ShowDialog() != DialogResult.OK) { return; } if (tCapability != null) { RtlAwareMessageBox.Show(this, Strings.NotYetImplemented, string.Empty, MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1, (MessageBoxOptions)0); } else { SaveFileDialog saveDialog = new SaveFileDialog(); saveDialog.FileName = fileInfo.Name; if (Directory.Exists(fileInfo.DirectoryName)) { saveDialog.InitialDirectory = fileInfo.DirectoryName; } saveDialog.Filter = "All files (*.*)|*.*"; saveDialog.CheckPathExists = true; saveDialog.OverwritePrompt = true; saveDialog.RestoreDirectory = true; if (saveDialog.ShowDialog() != DialogResult.OK) { return; } FileStream fileStream = File.OpenWrite(saveDialog.FileName); fileStream.Write(fileObject.Data, 0, fileObject.Data.Length); fileStream.Close(); } } }
private void ObjectReceived(object capability, ObjectReceivedEventArgs ea) { if (ea.Data is FileObject) { FileObject fileObject = ea.Data as FileObject; FileInfo fileInfo = new FileInfo(fileObject.Name); Type tCapability = null; // if (fileInfo.Extension.ToLower() == ".dll") // tCapability = GetCapability(fileObject.Data); ItemReceivedDialog dlgFileReceived = null; if (tCapability != null) { Capability.NameAttribute attrName = (Capability.NameAttribute) Attribute.GetCustomAttribute(tCapability, typeof(Capability.NameAttribute)); Capability.PayloadTypeAttribute attrPT = (Capability.PayloadTypeAttribute) Attribute.GetCustomAttribute(tCapability, typeof(Capability.PayloadTypeAttribute)); dlgFileReceived = new ItemReceivedDialog("Capability received", "A user has just sent you a capability"); dlgFileReceived.Button1Label = "&Install"; dlgFileReceived.FileIconTip = "Capability name: " + attrName.Name + Environment.NewLine + "Payload type: " + attrPT.PayloadType.ToString() + Environment.NewLine; } else { dlgFileReceived = new ItemReceivedDialog("File received", "A user has just sent you a file"); } dlgFileReceived.Image = Image.FromStream( System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("MSR.LST.ConferenceXP.Images.FileReceived.gif")); dlgFileReceived.From = ea.Participant.Name; dlgFileReceived.Avatar = ea.Participant.Icon; dlgFileReceived.AvatarTip = "IP: " + ea.Participant.RtpParticipant.IPAddress.ToString() + Environment.NewLine + "Id: " + ea.Participant.Identifier + Environment.NewLine + "Email: " + ea.Participant.Email + Environment.NewLine + "Phone: " + ea.Participant.Phone; dlgFileReceived.File = fileInfo.Name; dlgFileReceived.FileIcon = fileObject.Icon; dlgFileReceived.FileIconTip += "File size: " + ((double)fileObject.Data.Length / 1024.0).ToString("#,#.00") + " KB"; dlgFileReceived.Time = DateTime.Now.ToString("h:mm:ss tt"); if (dlgFileReceived.ShowDialog() != DialogResult.OK) { return; } if (tCapability != null) { MessageBox.Show("Not yet implemented"); } else { SaveFileDialog saveDialog = new SaveFileDialog(); saveDialog.FileName = fileInfo.Name; if (Directory.Exists(fileInfo.DirectoryName)) { saveDialog.InitialDirectory = fileInfo.DirectoryName; } saveDialog.Filter = "All files (*.*)|*.*"; saveDialog.CheckPathExists = true; saveDialog.OverwritePrompt = true; saveDialog.RestoreDirectory = true; if (saveDialog.ShowDialog() != DialogResult.OK) { return; } FileStream fileStream = File.OpenWrite(saveDialog.FileName); fileStream.Write(fileObject.Data, 0, fileObject.Data.Length); fileStream.Close(); } } }