Ejemplo n.º 1
0
 /// <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";
     }
 }
Ejemplo n.º 2
0
        //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);
        }
Ejemplo n.º 3
0
        /// <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;
        }
Ejemplo n.º 4
0
        /// <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();
        }