/// <summary> /// Handles the Click event of the deleteProfileToolStripMenuItem control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param> private void deleteProfileToolStripMenuItem_Click(object sender, EventArgs e) { toolStripStatusLabel1.Text = ""; string currentProfileName = currentProfile.ProfileName; DialogResult dResTest; dResTest = MessageBox.Show("Are you sure you want to delete this Profile ?", "Confirm Profile Deletion", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (dResTest == DialogResult.No) { return; } else { comboBoxProfiles.Items.Remove(currentProfile.ProfileName); comboBoxProfiles.SelectedItem = null; man.DeleteProfile(currentProfile); currentProfile = null; textBoxProfileName.Text = ""; textBoxProfileName.Enabled = true; comboBoxConnectionSource.SelectedItem = null; toolStripStatusLabel1.Text = "Profile " + currentProfileName + " deleted"; } }
//private static MSCRMAuditExportManager man; private static void Main(string[] args) { //Set the application directory as the current directory string appPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase); appPath = appPath.Replace("file:\\", ""); Directory.SetCurrentDirectory(appPath); MSCRMAuditExportManager man = new MSCRMAuditExportManager(); string selectedProfileName = ""; if (args.Length == 0) { if (man.Profiles.Count == 0) { Console.WriteLine("\nNo profiles found."); return; } //Display all profiles for selection Console.WriteLine("\nSpecify the Profile to run (1-{0}) [1] : ", man.Profiles.Count); int tpCpt = 1; foreach (MSCRMAuditExportProfile profile in man.Profiles) { Console.WriteLine(tpCpt + ". " + profile.ProfileName); tpCpt++; } String input = Console.ReadLine(); if (input == String.Empty) { input = "1"; } int depNumber; Int32.TryParse(input, out depNumber); if (depNumber > 0 && depNumber <= man.Profiles.Count) { selectedProfileName = man.Profiles[depNumber - 1].ProfileName; } else { Console.WriteLine("The specified Profile does not exist."); return; } } else { //Check that the Profile name is provided if (string.IsNullOrEmpty(args[0])) { return; } selectedProfileName = args[0]; } MSCRMAuditExportProfile p = man.GetProfile(selectedProfileName); if (p == null) { Console.WriteLine("The specified Profile does not exist."); return; } man.RunProfile(p); }
/// <summary> /// Saves the profile. /// </summary> /// <returns>True or False if the profile was succesfuly saved.</returns> private bool SaveProfile() { bool result = true; //Check that all fields are provided if (string.IsNullOrEmpty(textBoxProfileName.Text)) { MessageBox.Show("Profile Name is mandatory!"); return false; } //Check that the name of the connection is valid if (textBoxProfileName.Text.Contains(" ") || textBoxProfileName.Text.Contains("\\") || textBoxProfileName.Text.Contains("/") || textBoxProfileName.Text.Contains(">") || textBoxProfileName.Text.Contains("<") || textBoxProfileName.Text.Contains("?") || textBoxProfileName.Text.Contains("*") || textBoxProfileName.Text.Contains(":") || textBoxProfileName.Text.Contains("|") || textBoxProfileName.Text.Contains("\"") || textBoxProfileName.Text.Contains("'") ) { MessageBox.Show("You shouldn't use spaces nor the following characters (\\/<>?*:|\"') in the Profile Name as it will be used to create folders and files."); return false; } if (comboBoxConnectionSource.SelectedItem == null) { MessageBox.Show("You must select a Source for the Profile"); return false; } if (comboBoxAuditTypeExport.SelectedItem == null) { MessageBox.Show("You must select an Audit Type to Export for the Profile"); return false; } if (comboBoxFormat.SelectedItem == null) { MessageBox.Show("You must select an Export Format for the Profile"); return false; } if (checkedListBoxActions.CheckedItems.Count == 0) { MessageBox.Show("You must select a least 1 Action"); return false; } if (checkedListBoxOperations.CheckedItems.Count == 0) { MessageBox.Show("You must select a least 1 Operation"); return false; } if (checkedListBoxUsers.CheckedItems.Count == 0) { MessageBox.Show("You must select a least 1 User"); return false; } if (comboBoxAuditTypeExport.SelectedItem.ToString() != "User Acces Audit" && checkedListBoxEntities.CheckedItems.Count == 0) { MessageBox.Show("You must select a least 1 Entity"); return false; } if (comboBoxAuditTypeExport.SelectedItem.ToString() == "Attribute Change History") { List<SelectedAuditEntity> SAEList = SelectedEntityList.Where(x => (x.SelectedAttributes == null || x.SelectedAttributes.Count == 0)).ToList<SelectedAuditEntity>(); if (SAEList.Count > 0) { MessageBox.Show("You must select 1 Attribute for each selected Entity!"); return false; } } //Check if this is a creation if (currentProfile == null) { //Check if a Data Export Profile having the same name exist already MSCRMAuditExportProfile existingProfile = man.Profiles.Find(d => d.ProfileName.ToLower() == textBoxProfileName.Text.ToLower()); if (existingProfile != null) { MessageBox.Show("Profile with the name " + textBoxProfileName.Text + " exist already. Please select another name"); return false; } MSCRMAuditExportProfile newProfile = new MSCRMAuditExportProfile(); newProfile.ProfileName = textBoxProfileName.Text; newProfile.SourceConnectionName = comboBoxConnectionSource.SelectedItem.ToString(); newProfile.setSourceConneciton(); newProfile.ExportFormat = comboBoxFormat.SelectedItem.ToString(); newProfile.AuditType = comboBoxAuditTypeExport.SelectedItem.ToString(); newProfile.Encoding = "Default"; if (comboBoxEncoding.SelectedIndex == 1) newProfile.Encoding = "UTF8"; else if (comboBoxEncoding.SelectedIndex == 1) newProfile.Encoding = "Unicode"; else if (comboBoxEncoding.SelectedIndex == 2) newProfile.Encoding = "ASCII"; else if (comboBoxEncoding.SelectedIndex == 3) newProfile.Encoding = "BigEndianUnicode"; newProfile.SelectedActions = new List<int>(); if (checkedListBoxActions.CheckedItems.Count == checkedListBoxActions.Items.Count) { newProfile.AllActionsSelected = true; } else { newProfile.AllActionsSelected = false; foreach (ActionListBoxItem checkedAction in checkedListBoxActions.CheckedItems) { newProfile.SelectedActions.Add(checkedAction.Key); } } newProfile.SelectedOperations = new List<int>(); if (checkedListBoxOperations.CheckedItems.Count == checkedListBoxOperations.Items.Count) { newProfile.AllOperationsSelected = true; } else { newProfile.AllOperationsSelected = false; for (int i = 0; i < checkedListBoxOperations.Items.Count; i++) { if (checkedListBoxOperations.CheckedItems.IndexOf(checkedListBoxOperations.Items[i]) > -1) { KeyValuePair<int, string> u = new KeyValuePair<int, string>(i + 1, checkedListBoxOperations.Items[i].ToString()); newProfile.SelectedOperations.Add(u.Key); } } } newProfile.SelectedUsers = new List<AuditUser>(); if (checkedListBoxUsers.CheckedItems.Count == checkedListBoxUsers.Items.Count) { newProfile.AllUsersSelected = true; } else { newProfile.AllUsersSelected = false; foreach (CheckListBoxItem checkedUser in checkedListBoxUsers.CheckedItems) { AuditUser u = new AuditUser { Id = checkedUser.Id, FullName = checkedUser.Text }; newProfile.SelectedUsers.Add(u); } } newProfile.SelectedEntities = new List<SelectedAuditEntity>(); if (checkedListBoxEntities.CheckedItems.Count == checkedListBoxEntities.Items.Count) newProfile.AllEntitiesSelected = true; else newProfile.AllEntitiesSelected = false; foreach (EntityListBoxItem checkedEntity in checkedListBoxEntities.CheckedItems) { SelectedAuditEntity ee = new SelectedAuditEntity(); ee.LogicalName = checkedEntity.Value; ee.ObjectTypeCode = checkedEntity.ObjectTypeCode; SelectedAuditEntity seForIgnoredAttributes = SelectedEntityList.Find(match => match.LogicalName == checkedEntity.Value); if (seForIgnoredAttributes != null) { ee.SelectedAttributes = seForIgnoredAttributes.SelectedAttributes; ee.Filter = seForIgnoredAttributes.Filter; } newProfile.SelectedEntities.Add(ee); } if (comboBoxAuditRecordCreatedOnFilter.SelectedItem != null) newProfile.AuditRecordCreatedOnFilter = comboBoxAuditRecordCreatedOnFilter.SelectedItem.ToString(); newProfile.AuditRecordCreatedOnFilterLastX = numericUpDownLastX.Value; newProfile.AuditRecordCreatedOnFilterFrom = dateTimePickerAuditCreatedFrom.Value; newProfile.AuditRecordCreatedOnFilterTo = dateTimePickerAuditCreatedTo.Value; man.CreateProfile(newProfile); currentProfile = newProfile; comboBoxProfiles.Items.AddRange(new object[] { newProfile.ProfileName }); comboBoxProfiles.SelectedItem = newProfile.ProfileName; } else { currentProfile.ProfileName = textBoxProfileName.Text; currentProfile.SourceConnectionName = comboBoxConnectionSource.SelectedItem.ToString(); currentProfile.ExportFormat = comboBoxFormat.SelectedItem.ToString(); currentProfile.AuditType = comboBoxAuditTypeExport.SelectedItem.ToString(); currentProfile.Encoding = "Default"; if (comboBoxEncoding.SelectedIndex == 1) currentProfile.Encoding = "UTF8"; else if (comboBoxEncoding.SelectedIndex == 1) currentProfile.Encoding = "Unicode"; else if (comboBoxEncoding.SelectedIndex == 2) currentProfile.Encoding = "ASCII"; else if (comboBoxEncoding.SelectedIndex == 3) currentProfile.Encoding = "BigEndianUnicode"; currentProfile.SelectedActions = new List<int>(); if (checkedListBoxActions.CheckedItems.Count == checkedListBoxActions.Items.Count) { currentProfile.AllActionsSelected = true; } else { currentProfile.AllActionsSelected = false; foreach (ActionListBoxItem checkedAction in checkedListBoxActions.CheckedItems) { currentProfile.SelectedActions.Add(checkedAction.Key); } } currentProfile.SelectedOperations = new List<int>(); if (checkedListBoxOperations.CheckedItems.Count == checkedListBoxOperations.Items.Count) { currentProfile.AllOperationsSelected = true; } else { currentProfile.AllOperationsSelected = false; for (int i = 0; i < checkedListBoxOperations.Items.Count; i++) { if (checkedListBoxOperations.CheckedItems.IndexOf(checkedListBoxOperations.Items[i]) > -1) { KeyValuePair<int, string> u = new KeyValuePair<int, string>(i + 1, checkedListBoxOperations.Items[i].ToString()); currentProfile.SelectedOperations.Add(u.Key); } } } currentProfile.SelectedUsers = new List<AuditUser>(); if (checkedListBoxUsers.CheckedItems.Count == checkedListBoxUsers.Items.Count) { currentProfile.AllUsersSelected = true; } else { currentProfile.AllUsersSelected = false; foreach (CheckListBoxItem checkedUser in checkedListBoxUsers.CheckedItems) { AuditUser u = new AuditUser { Id = checkedUser.Id, FullName = checkedUser.Text }; currentProfile.SelectedUsers.Add(u); } } currentProfile.SelectedEntities = new List<SelectedAuditEntity>(); if (checkedListBoxEntities.CheckedItems.Count == checkedListBoxEntities.Items.Count) currentProfile.AllEntitiesSelected = true; else currentProfile.AllEntitiesSelected = false; foreach (EntityListBoxItem checkedEntity in checkedListBoxEntities.CheckedItems) { SelectedAuditEntity ee = new SelectedAuditEntity(); ee.LogicalName = checkedEntity.Value; ee.ObjectTypeCode = checkedEntity.ObjectTypeCode; SelectedAuditEntity seForIgnoredAttributes = SelectedEntityList.Find(match => match.LogicalName == checkedEntity.Value); if (seForIgnoredAttributes != null) { ee.SelectedAttributes = seForIgnoredAttributes.SelectedAttributes; ee.Filter = seForIgnoredAttributes.Filter; } currentProfile.SelectedEntities.Add(ee); } if (comboBoxAuditRecordCreatedOnFilter.SelectedItem != null) currentProfile.AuditRecordCreatedOnFilter = comboBoxAuditRecordCreatedOnFilter.SelectedItem.ToString(); currentProfile.AuditRecordCreatedOnFilterLastX = numericUpDownLastX.Value; currentProfile.AuditRecordCreatedOnFilterFrom = dateTimePickerAuditCreatedFrom.Value; currentProfile.AuditRecordCreatedOnFilterTo = dateTimePickerAuditCreatedTo.Value; currentProfile.setSourceConneciton(); MSCRMAuditExportProfile oldDEP = man.GetProfile(currentProfile.ProfileName); man.UpdateProfile(currentProfile); } //runProfileToolStripMenuItem.Enabled = true; toolStripStatusLabel1.Text = "Profile " + currentProfile.ProfileName + " saved."; LogManager.WriteLog("Profile " + currentProfile.ProfileName + " saved."); return result; }
/// <summary> /// Handles the SelectedIndexChanged event of the comboBoxProfiles control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param> private void comboBoxProfiles_SelectedIndexChanged(object sender, EventArgs e) { toolStripStatusLabel1.Text = ""; comboBoxConnectionSource.SelectedItem = null; if (comboBoxProfiles.SelectedItem != null) { currentProfile = man.Profiles[comboBoxProfiles.SelectedIndex]; SelectedEntityList = currentProfile.SelectedEntities; textBoxProfileName.Text = currentProfile.ProfileName; comboBoxConnectionSource.SelectedItem = currentProfile.SourceConnectionName; comboBoxFormat.SelectedItem = currentProfile.ExportFormat; comboBoxAuditTypeExport.SelectedItem = currentProfile.AuditType; comboBoxEncoding.SelectedItem = "Default"; if (currentProfile.Encoding == "UTF8") comboBoxEncoding.SelectedItem = "UTF8"; else if (currentProfile.Encoding == "Unicode") comboBoxEncoding.SelectedItem = "Unicode"; else if (currentProfile.Encoding == "ASCII") comboBoxEncoding.SelectedItem = "ASCII"; else if (currentProfile.Encoding == "BigEndianUnicode") comboBoxEncoding.SelectedItem = "BigEndianUnicode"; comboBoxAuditRecordCreatedOnFilter.SelectedItem = currentProfile.AuditRecordCreatedOnFilter; numericUpDownLastX.Value = currentProfile.AuditRecordCreatedOnFilterLastX; dateTimePickerAuditCreatedFrom.Value = currentProfile.AuditRecordCreatedOnFilterFrom; dateTimePickerAuditCreatedTo.Value = currentProfile.AuditRecordCreatedOnFilterTo; deleteProfileToolStripMenuItem.Enabled = true; newToolStripMenuItem.Enabled = true; saveToolStripMenuItem.Enabled = true; textBoxProfileName.Enabled = false; runProfileToolStripMenuItem.Enabled = true; comboBoxAuditTypeExport.Enabled = false; comboBoxConnectionSource.Enabled = false; } else { currentProfile = null; textBoxProfileName.Text = ""; comboBoxFormat.SelectedItem = null; comboBoxAuditTypeExport.SelectedItem = null; comboBoxAuditTypeExport.Enabled = true; deleteProfileToolStripMenuItem.Enabled = false; newToolStripMenuItem.Enabled = false; saveToolStripMenuItem.Enabled = false; textBoxProfileName.Enabled = true; runProfileToolStripMenuItem.Enabled = false; comboBoxConnectionSource.Enabled = true; } buttonOpenInExcel.Visible = false; //dataExportReportToolStripMenuItem.Visible = false; }
/// <summary> /// Exports the specified profile. /// </summary> /// <param name="profile">The profile.</param> private void Export(MSCRMAuditExportProfile profile) { MSCRMConnection connection = profile.getSourceConneciton(); _serviceProxy = cm.connect(connection); IOrganizationService service = (IOrganizationService)_serviceProxy; es = ReadEnvStructure(profile.SourceConnectionName); List<string> columns = new List<string> { "transactionid", "createdon", "userid", "objecttypecode", "objectid", "action", "operation" }; List<string> DisplayedColumns = new List<string> { "TransactionId", "Date", "User", "Entity", "Record", "Action", "Operation" }; if (!(profile.AuditType == "User Acces Audit") && !(profile.AuditType == "Audit Summary View")) { columns.Add("key"); columns.Add("oldValue"); columns.Add("newValue"); DisplayedColumns.Add("Attribute"); DisplayedColumns.Add("Old_Value"); DisplayedColumns.Add("New_Value"); } if (profile.AuditType == "User Acces Audit" || profile.AuditType == "Audit Summary View") { LogManager.WriteLog("Exporting " + profile.AuditType); string fetchXml = "<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>"; fetchXml += "<entity name='audit'>"; fetchXml += "<attribute name='transactionid' />"; fetchXml += "<attribute name='attributemask' />"; fetchXml += "<attribute name='action' />"; fetchXml += "<attribute name='createdon' />"; fetchXml += "<attribute name='auditid' />"; fetchXml += "<attribute name='userid' />"; fetchXml += "<attribute name='operation' />"; fetchXml += "<attribute name='objectid' />"; fetchXml += "<order attribute='createdon' descending='true' />"; fetchXml += "<filter type='and'>"; if (!profile.AllUsersSelected && profile.SelectedUsers.Count > 0) { //When a User Access Audit type is selected the User is in the Object if (profile.AuditType == "User Acces Audit") fetchXml += "<condition attribute='objectid' operator='in'>"; else fetchXml += "<condition attribute='userid' operator='in'>"; foreach (AuditUser u in profile.SelectedUsers) { fetchXml += "<value uitype='systemuser'>" + u.Id.ToString() + "</value>"; } fetchXml += "</condition>"; } if (!profile.AllActionsSelected && profile.SelectedActions.Count > 0) { fetchXml += "<condition attribute='action' operator='in'>"; foreach (int i in profile.SelectedActions) { fetchXml += "<value>" + i + "</value>"; } fetchXml += "</condition>"; } if (!profile.AllOperationsSelected && profile.SelectedOperations.Count > 0) { fetchXml += "<condition attribute='operation' operator='in'>"; foreach (int i in profile.SelectedOperations) { fetchXml += "<value>" + i + "</value>"; } fetchXml += "</condition>"; } if (profile.AuditType != "User Acces Audit" && !profile.AllEntitiesSelected && profile.SelectedEntities.Count > 0) { fetchXml += "<condition attribute='objecttypecode' operator='in'>"; foreach (SelectedAuditEntity i in profile.SelectedEntities) { fetchXml += "<value>" + i.ObjectTypeCode + "</value>"; } fetchXml += "</condition>"; } if (profile.AuditRecordCreatedOnFilter == "Last X Days") fetchXml += "<condition attribute='createdon' operator='last-x-days' value='" + profile.AuditRecordCreatedOnFilterLastX + "' />"; else if (profile.AuditRecordCreatedOnFilter == "Last X Months") fetchXml += "<condition attribute='createdon' operator='last-x-months' value='" + profile.AuditRecordCreatedOnFilterLastX + "' />"; else if (profile.AuditRecordCreatedOnFilter == "Last X Years") fetchXml += "<condition attribute='createdon' operator='last-x-years' value='" + profile.AuditRecordCreatedOnFilterLastX + "' />"; else if (profile.AuditRecordCreatedOnFilter == "Between Dates") { fetchXml += "<condition attribute='createdon' operator='on-or-after' value='" + String.Format("{0:yyyy-MM-dd}", profile.AuditRecordCreatedOnFilterFrom) + "' />"; fetchXml += "<condition attribute='createdon' operator='on-or-before' value='" + String.Format("{0:yyyy-MM-dd}", profile.AuditRecordCreatedOnFilterTo) + "' />"; } fetchXml += "</filter>"; fetchXml += "</entity></fetch>"; int recordCountPerEntity = ExportEntity(profile, fetchXml, "", columns, DisplayedColumns, null); } else { foreach (SelectedAuditEntity sae in profile.SelectedEntities) { //Get entity PrimaryNameAttribute String PrimaryNameAttribute = es.Entities.Find(e => e.LogicalName == sae.LogicalName).PrimaryNameAttribute; LogManager.WriteLog("Exporting audit data for entity " + sae.LogicalName); string fetchXml = "<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>"; fetchXml += "<entity name='" + sae.LogicalName + "'>"; fetchXml += "<attribute name='" + PrimaryNameAttribute + "' />"; fetchXml += sae.Filter; fetchXml += "</entity></fetch>"; int recordCountPerEntity = ExportEntity(profile, fetchXml, PrimaryNameAttribute, columns, DisplayedColumns, sae); } } }
/// <summary> /// Creates the profile. /// </summary> /// <param name="profile">The profile.</param> public void CreateProfile(MSCRMAuditExportProfile profile) { if (!Directory.Exists(Folder + "\\" + profile.ProfileName)) Directory.CreateDirectory(Folder + "\\" + profile.ProfileName); //Creating new Profile Profiles.Add(profile); WriteProfiles(); }
/// <summary> /// Displays the audit details. /// </summary> /// <param name="detail">The detail.</param> /// <param name="profile">The profile.</param> /// <param name="ObjectName">Name of the object.</param> /// <param name="path">The path.</param> /// <param name="columns">The columns.</param> /// <param name="DisplayedColumns">The displayed columns.</param> private void DisplayAuditDetails(AuditDetail detail, MSCRMAuditExportProfile profile, string ObjectName, string path, List<string> columns, List<string> DisplayedColumns) { Audit record = (Audit)detail.AuditRecord; if (profile.AuditRecordCreatedOnFilter == "Last X Days") { DateTime CreatedOnBottomLimit = DateTime.Today.AddDays(-(double)profile.AuditRecordCreatedOnFilterLastX); if (CreatedOnBottomLimit > record.CreatedOn) return; } else if (profile.AuditRecordCreatedOnFilter == "Last X Months") { DateTime CreatedOnBottomLimit = DateTime.Today.AddMonths(-(int)profile.AuditRecordCreatedOnFilterLastX); if (CreatedOnBottomLimit > record.CreatedOn) return; } else if (profile.AuditRecordCreatedOnFilter == "Last X Years") { DateTime CreatedOnBottomLimit = DateTime.Today.AddYears(-(int)profile.AuditRecordCreatedOnFilterLastX); if (CreatedOnBottomLimit > record.CreatedOn) return; } else if (profile.AuditRecordCreatedOnFilter == "Between Dates") { if (profile.AuditRecordCreatedOnFilterFrom > record.CreatedOn || profile.AuditRecordCreatedOnFilterTo < record.CreatedOn) return; } List<AuditDetailLine> AuditDetailLines = new List<AuditDetailLine>(); // Show additional details for certain AuditDetail sub-types. var detailType = detail.GetType(); if (detailType == typeof(AttributeAuditDetail)) { var attributeDetail = (AttributeAuditDetail)detail; AuditDetailLine adl = new AuditDetailLine(); if (attributeDetail.NewValue != null) { // Display the old and new attribute values. foreach (KeyValuePair<String, object> attribute in attributeDetail.NewValue.Attributes) { String oldValue = "(no value)", newValue = "(no value)"; //format values oldValue = getFormattedValue(attributeDetail.OldValue, attribute.Key); newValue = getFormattedValue(attributeDetail.NewValue, attribute.Key); adl = new AuditDetailLine(); adl.TransactionId = record.Id; adl.createdon = record.CreatedOn.Value.ToLocalTime(); adl.UserName = record.UserId.Name; adl.RecordLogicalName = record.ObjectId.LogicalName; adl.RecordName = ObjectName; adl.action = record.FormattedValues["action"]; adl.operation = record.FormattedValues["operation"]; adl.key = attribute.Key; adl.oldValue = oldValue; adl.newValue = newValue; AuditDetailLines.Add(adl); } } if (attributeDetail.OldValue != null) { foreach (KeyValuePair<String, object> attribute in attributeDetail.OldValue.Attributes) { if (!attributeDetail.NewValue.Contains(attribute.Key)) { String newValue = "(no value)"; //format values String oldValue = getFormattedValue(attributeDetail.OldValue, attribute.Key); adl = new AuditDetailLine(); adl.TransactionId = record.Id; adl.createdon = record.CreatedOn.Value.ToLocalTime(); adl.UserName = record.UserId.Name; adl.RecordLogicalName = record.ObjectId.LogicalName; adl.RecordName = ObjectName; adl.action = record.FormattedValues["action"]; adl.operation = record.FormattedValues["operation"]; adl.key = attribute.Key; adl.oldValue = oldValue; adl.newValue = newValue; AuditDetailLines.Add(adl); } } } } else { AuditDetailLine adl = new AuditDetailLine(); adl.TransactionId = record.Id; adl.createdon = record.CreatedOn.Value.ToLocalTime(); adl.UserName = record.UserId.Name; adl.RecordLogicalName = record.ObjectId.LogicalName; adl.RecordName = ObjectName; adl.action = record.FormattedValues["action"]; adl.operation = record.FormattedValues["operation"]; AuditDetailLines.Add(adl); } if (profile.ExportFormat.ToLower() == "csv") WriteCSVAuditDetail(AuditDetailLines, fileName, columns, DisplayedColumns); else if (profile.ExportFormat.ToLower() == "xml") WriteXMLAuditDetail(AuditDetailLines, fileName, columns, DisplayedColumns); else if (profile.ExportFormat.ToLower() == "xml spreadsheet 2003") WriteXMLSpreadsheet2003AuditDetail(AuditDetailLines, fileName, columns, DisplayedColumns); }
/// <summary> /// Updates the profile. /// </summary> /// <param name="profile">The profile.</param> /// <exception cref="System.Exception">Audit Export Profile Update failed. The Audit Export Profile + profile.ProfileName + was not found in the configuration file.</exception> public void UpdateProfile(MSCRMAuditExportProfile profile) { if (!Directory.Exists(Folder + "\\" + profile.ProfileName)) Directory.CreateDirectory(Folder + "\\" + profile.ProfileName); int index = Profiles.FindIndex(d => d.ProfileName == profile.ProfileName); if (index > -1) { Profiles[index] = profile; } else { LogManager.WriteLog("Audit Export Profile Update failed. The Audit Export Profile " + profile.ProfileName + " was not found in the configuration file."); throw new Exception("Audit Export Profile Update failed. The Audit Export Profile " + profile.ProfileName + " was not found in the configuration file."); } WriteProfiles(); }
/// <summary> /// Runs the profile. /// </summary> /// <param name="profile">The profile.</param> public void RunProfile(MSCRMAuditExportProfile profile) { LogManager.WriteLog("Running Audit Export Profile: " + profile.ProfileName); DateTime now = DateTime.Now; ReportFileName = Folder + "\\" + profile.ProfileName + "\\ExecutionReports\\AuditExportReport" + now.Year + "-" + now.Month + "-" + now.Day + "-" + now.Hour + "-" + now.Minute + "-" + now.Second + ".xml"; //Initialize Execution Reports folder string executionReportsFolder = Folder + "\\" + profile.ProfileName + "\\ExecutionReports"; if (!Directory.Exists(executionReportsFolder)) { Directory.CreateDirectory(executionReportsFolder); } //Set Encoding if (profile.Encoding == "UTF8") encoding = System.Text.Encoding.UTF8; else if (profile.Encoding == "Unicode") encoding = System.Text.Encoding.Unicode; else if (profile.Encoding == "ASCII") encoding = System.Text.Encoding.ASCII; else if (profile.Encoding == "BigEndianUnicode") encoding = System.Text.Encoding.BigEndianUnicode; string fileExtension = profile.ExportFormat.ToLower(); if (profile.ExportFormat.ToLower() == "xml spreadsheet 2003") fileExtension = "xml"; fileName = Folder + "\\" + profile.ProfileName + "\\AuditExport_" + now.Year + "-" + now.Month + "-" + now.Day + "-" + now.Hour + "-" + now.Minute + "-" + now.Second + "." + fileExtension; //Create Audit Export Report //DataExportReport der = new DataExportReport(profile.ProfileName); //WriteReport(der, ReportFileName); //Export Audit Export(profile); //DataExportReport report = ReadReport(ReportFileName); //report.DataExportFinishedAt = DateTime.Now.ToString(); //report.DataExportCompleted = true; //TimeSpan ExportTimeSpan = DateTime.Now - Convert.ToDateTime(report.DataExportStartedAt); //report.DataExportedIn = ExportTimeSpan.ToString().Substring(0, 10); //WriteReport(report, ReportFileName); }
/// <summary> /// Exports the entity. /// </summary> /// <param name="profile">The profile.</param> /// <param name="fetchXml">The fetch XML query.</param> /// <param name="PrimaryNameAttribute">The primary name attribute.</param> /// <param name="columns">The columns.</param> /// <param name="DisplayedColumns">The displayed columns.</param> /// <param name="sae">The sae.</param> /// <returns>The number of exported records</returns> public int ExportEntity(MSCRMAuditExportProfile profile, string fetchXml, string PrimaryNameAttribute, List<string> columns, List<string> DisplayedColumns, SelectedAuditEntity sae) { //Set the number of records per page to retrieve. //This value should not be bigger than 5000 as this is the limit of records provided by the CRM int fetchCount = 5000; // Initialize the file number. int fileNumber = 1; // Initialize the number of records. int recordCount = 0; // Specify the current paging cookie. For retrieving the first page, pagingCookie should be null. string pagingCookie = null; string entityName = ""; while (true) { // Build fetchXml string with the placeholders. string xml = CreateXml(fetchXml, pagingCookie, fileNumber, fetchCount); RetrieveMultipleRequest fetchRequest = new RetrieveMultipleRequest { Query = new FetchExpression(xml) }; EntityCollection returnCollection = ((RetrieveMultipleResponse)_serviceProxy.Execute(fetchRequest)).EntityCollection; recordCount += returnCollection.Entities.Count; if (recordCount > 0) { if (profile.AuditType == "User Acces Audit" || profile.AuditType == "Audit Summary View") { if (profile.ExportFormat.ToLower() == "csv") WriteCSV(returnCollection, fileName, columns, DisplayedColumns); else if (profile.ExportFormat.ToLower() == "xml") WriteXML(returnCollection, fileName, columns, DisplayedColumns); else if (profile.ExportFormat.ToLower() == "xml spreadsheet 2003") WriteXMLSpreadsheet2003(returnCollection, fileName, columns, DisplayedColumns); } else { foreach (Entity e in returnCollection.Entities) { AuditDetailCollection details = new AuditDetailCollection(); if (profile.AuditType == "Record Change History") { RetrieveRecordChangeHistoryRequest changeRequest = new RetrieveRecordChangeHistoryRequest(); changeRequest.Target = new EntityReference(returnCollection.EntityName, e.Id); RetrieveRecordChangeHistoryResponse changeResponse = (RetrieveRecordChangeHistoryResponse)_serviceProxy.Execute(changeRequest); details = changeResponse.AuditDetailCollection; } else { //Attribute change history var attributeChangeHistoryRequest = new RetrieveAttributeChangeHistoryRequest { Target = new EntityReference(e.LogicalName, e.Id), AttributeLogicalName = sae.SelectedAttributes[0] }; var attributeChangeHistoryResponse = (RetrieveAttributeChangeHistoryResponse)_serviceProxy.Execute(attributeChangeHistoryRequest); details = attributeChangeHistoryResponse.AuditDetailCollection; } foreach (AuditDetail detail in details.AuditDetails) { DisplayAuditDetails(detail, profile, (string)e[PrimaryNameAttribute], fileName, columns, DisplayedColumns); } } } } // Check for more records, if it returns 1. if (returnCollection.MoreRecords) { // Increment the page number to retrieve the next page. fileNumber++; pagingCookie = returnCollection.PagingCookie; } else { // If no more records in the result nodes, exit the loop. break; } } if (profile.ExportFormat.ToLower() == "xml" && File.Exists(fileName)) { using (var writer = new StreamWriter(fileName, true, encoding)) { writer.WriteLine("</Records>"); writer.Flush(); } } else if (profile.ExportFormat.ToLower() == "xml spreadsheet 2003" && File.Exists(fileName)) { using (var writer = new StreamWriter(fileName, true, encoding)) { writer.WriteLine("</Table></Worksheet></Workbook>\n"); writer.Flush(); } } LogManager.WriteLog("Exported " + recordCount + " " + entityName + " records."); return recordCount; }
/// <summary> /// Deletes the profile. /// </summary> /// <param name="profile">The profile.</param> /// <exception cref="System.Exception">Audit Export Profile deletion failed. The Audit Export Profile + profile.ProfileName + was not found in the configuration file.</exception> public void DeleteProfile(MSCRMAuditExportProfile profile) { int index = Profiles.FindIndex(d => d.ProfileName == profile.ProfileName); if (index > -1) { Profiles.RemoveAt(index); } else { LogManager.WriteLog("Audit Export Profile deletion failed. The Audit Export Profile " + profile.ProfileName + " was not found in the configuration file."); throw new Exception("Audit Export Profile deletion failed. The Audit Export Profile " + profile.ProfileName + " was not found in the configuration file."); } //Delete Profile folder try { if (Directory.Exists(Folder + "\\" + profile.ProfileName)) Directory.Delete(Folder + "\\" + profile.ProfileName, true); } catch (Exception) { throw; } //Save Profiles WriteProfiles(); }