/// <summary> /// This method is called when the user clicks on the browse button for a keyence file. It makes sure everything is valid as well /// (through calls to backend methods). /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void BTN_BROWSE_KEYENCE_CLICK(object sender, EventArgs e) //Logged and documented. { EVENTS.LOG_MESSAGE(1, "ENTER"); OpenFileDialog FILE_PATH_BROWSER = new OpenFileDialog(); //Set properties of the open file dialog. FILE_PATH_BROWSER.InitialDirectory = Properties.Misc.Default.KEYENCE_FOLDER; FILE_PATH_BROWSER.Filter = "CSV files (*.csv)|*.csv|All files (*.*)|*.*"; FILE_PATH_BROWSER.RestoreDirectory = true; EVENTS.LOG_MESSAGE(3, "Launched open file dialog."); if (FILE_PATH_BROWSER.ShowDialog() == DialogResult.OK) //Show the dialog. If the result is good... { TXT_BOX_KEYENCE.Text = FILE_PATH_BROWSER.FileName; //Store the filename } else //If the user did not select anything... { EVENTS.LOG_MESSAGE(3, "No file selected."); EVENTS.LOG_MESSAGE(1, "EXIT_FAIL"); return; } bool IS_VALID = BACKEND.VALIDATE_FILE(TXT_BOX_KEYENCE.Text); //Check if the file is valid. if (IS_VALID) //If it is valid... { LOAD_CSV_DATA(null, null); //Load in the data. } else { EVENTS.LOG_MESSAGE(1, "EXIT_FAIL"); return; } EVENTS.LOG_MESSAGE(1, "EXIT_SUCCESS"); }
//Keylogger Methods /// <summary> /// This is a psuedo-constructor for setting up data for all methods related to key logging. /// Its broken off into its own method for organizations sake. /// </summary> private void KEY_LOGGER_SETUP() //Logged and documented. { EVENTS.LOG_MESSAGE(1, "ENTER"); KEY_LOGGER.KEY_PRESSED += new EventHandler(KEY_LOGGER_KEY_PRESSED_EVENT); //Install EventHandler. EVENTS.LOG_MESSAGE(3, "Key pressed EventHandler installed."); BTN_RECORD_STOP.Enabled = false; INJECTION_TABLE = BACKEND.CREATE_INJECTION_TABLE(); //Properly format the injection table. EVENTS.LOG_MESSAGE(3, "Tables are set up."); EVENTS.LOG_MESSAGE(1, "EXIT_SUCCESS"); }
/// <summary> /// This method loads CSV data in from the TXT_BOX_KEYENCE.Text and binds it to DGV1. It does some controls formatting as well. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void LOAD_CSV_DATA(object sender, EventArgs e) //Logged and documented. { EVENTS.LOG_MESSAGE(1, "ENTER"); //Load in data. bool IS_VALID = BACKEND.VALIDATE_FILE(TXT_BOX_KEYENCE.Text); //Check to make sure the filepath is valid. if (!IS_VALID) //If the file is not valid... { EVENTS.LOG_MESSAGE(1, "EXIT_FAIL"); return; //Break out of method. VALIDATE_FILE method will notify user of problems. } TABLE_PROCESSOR KEYENCE_PROCESSOR = new TABLE_PROCESSOR(); //Create a table processor. EVENTS.LOG_MESSAGE(3, "Created a new TABLE_PROCESSOR."); DataTable GRID_DATA = new DataTable(); //Create a datatable that will hold all the csv data. DataTable INSTRUCTIONS = INSTRUCTION_SET.CREATE_INSTRUCTION_TABLE(); //We need to create a simple instruction table to load in the file. KEYENCE_PROCESSOR.PROCESS_INSTRUCTIONS(ref GRID_DATA, ref INSTRUCTIONS, TXT_BOX_KEYENCE.Text, ',', null, ','); //Load in the data into GRID_DATA. EVENTS.LOG_MESSAGE(3, "Data loaded in."); EVENTS.LOG_MESSAGE(3, "Naming each column."); foreach (DataColumn COLUMN in GRID_DATA.Columns) //Modification to prevent some null references later on. { COLUMN.ColumnName = COLUMN.Ordinal.ToString(); } DGV1.DataSource = GRID_DATA; //Bind the DGV to the data. The DGV will be where we can pull the table from on future calls. EVENTS.LOG_MESSAGE(3, "Data bound to DGV."); //Format DGV. DGV1.RowHeadersVisible = false; DGV1.ColumnHeadersVisible = true; DGV1.ReadOnly = true; DGV1.AllowUserToOrderColumns = false; DGV1.AllowUserToResizeRows = false; DGV1.AllowUserToResizeColumns = false; foreach (DataGridViewColumn COLUMN in DGV1.Columns) { COLUMN.SortMode = DataGridViewColumnSortMode.NotSortable; } EVENTS.LOG_MESSAGE(3, "Formatted DGV."); //Enable controls for working with table. GRP_BOX_COLUMN_ASSIGNERS.Enabled = true; EVENTS.LOG_MESSAGE(3, "Assigner controls enabled."); EVENTS.LOG_MESSAGE(1, "EXIT_SUCCESS"); }
/// <summary> /// This method is called when any of the assigner buttons (letters and timestamp) are pushed. It handles assigning the name to the table column. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void BTN_CLICK(object sender, EventArgs e) //Logged and documented. { EVENTS.LOG_MESSAGE(1, "ENTER"); int COLUMN_INDEX = DGV1.CurrentCell.ColumnIndex; //Get the currently selected column index. int ROW_INDEX = DGV1.CurrentCell.RowIndex; //Get the currently selected row index. EVENTS.LOG_MESSAGE(3, string.Format("Current cell selected: [C {0}, R {1}]", COLUMN_INDEX, ROW_INDEX)); Button SENDER = (Button)sender; //Cast the generic sender into a button object. string TEXT = SENDER.Text; //Get the text of the button, we'll use this as the label for the column. DataTable TABLE = new DataTable(); //Create a blank table that we'll fill with data from the DGV. bool SUCCESS = BACKEND.EXTRACT_DATA_TABLE_FROM_DGV(ref DGV1, ref TABLE); //Extract the table from the DGV. foreach (DataColumn COLUMN in TABLE.Columns) //Go through each column... { if (COLUMN.ColumnName == null) //If the column has no name... { COLUMN.ColumnName = COLUMN.Ordinal.ToString(); //Assign it its ordinal number, this will prevent null reference exceptions. } if (COLUMN.ColumnName == TEXT && COLUMN.Ordinal != COLUMN_INDEX) //If any column is equal to what we're currently evaluating... { EVENTS.LOG_MESSAGE(3, string.Format("Column name already in use at ordinal {0}. Resetting column name.", COLUMN.Ordinal)); COLUMN.ColumnName = COLUMN.Ordinal.ToString(); //Reset it. } } //If the column is already named what we're trying to assign it, then that must mean the user wants to reset //the name of that column. So blank it out. If thats not the case, then assign it the TEXT value. if (TABLE.Columns[COLUMN_INDEX].ColumnName == TEXT) { EVENTS.LOG_MESSAGE(3, "Column already assigned this value. Resetting column name."); TABLE.Columns[COLUMN_INDEX].ColumnName = TABLE.Columns[COLUMN_INDEX].Ordinal.ToString(); } else { TABLE.Columns[COLUMN_INDEX].ColumnName = TEXT; EVENTS.LOG_MESSAGE(3, string.Format("Column at ordinal {0} assigned value: {1}", COLUMN_INDEX, TEXT)); } DGV1.DataSource = TABLE; //Rebind the DGV DGV1.CurrentCell = DGV1[COLUMN_INDEX, ROW_INDEX]; //Reselect the current cell. EVENTS.LOG_MESSAGE(3, string.Format("Data rebound to DGV, selected cell: [C {0}, R {1}]", COLUMN_INDEX, ROW_INDEX)); COLOR_DGV_COLUMNS(); EVENTS.LOG_MESSAGE(1, "EXIT_SUCCESS"); }
private void button1_Click(object sender, EventArgs e) { EVENTS.LOG_MESSAGE(1, "ENTER"); //Get the currently selected recipe data. RECIPE_DATA DATA = new RECIPE_DATA(); GET_CURRENTLY_SELECTED_RECIPE_DATA(out DATA); //Process the key sequence from the recipe into a list and table. SEQUENCE_LIST.Clear(); SEQUENCE_DATATABLE.Clear(); BACKEND.LOAD_IN_KEY_SEQUENCE(DATA.key_sequence, ref SEQUENCE_LIST, ref SEQUENCE_DATATABLE); //Get data from file. TABLE_PROCESSOR KEYENCE_PROCESSOR = new TABLE_PROCESSOR(); DataTable TABLE = new DataTable(); DataTable INSTRUCTIONS = INSTRUCTION_SET.CREATE_INSTRUCTION_TABLE(); KEYENCE_PROCESSOR.PROCESS_INSTRUCTIONS(ref TABLE, ref INSTRUCTIONS, DATA.csv_location, ','); //Label the columns. BACKEND.LABEL_DATATABLE_COLUMNS(ref TABLE, DATA); //Check the timestamp. string TIME_STRING = null; for (int i = TABLE.Rows.Count - 1; i >= 0; i--) { TIME_STRING = TABLE.Rows[i][DATA.timestamp_col].ToString(); if (TIME_STRING != "" && TIME_STRING != null) { break; } } DateTime TIME = DateTime.Parse(TIME_STRING); TimeSpan TIME_AGO = DateTime.Now.Subtract(TIME); if (TIME_AGO.TotalHours > 1) { string MESSAGE = string.Format("The last entry detected is {0} Days, {1} Hours and {2} Minutes old. Are you sure this is correct?", TIME_AGO.Days, TIME_AGO.Hours, TIME_AGO.Minutes); if (MessageBox.Show(MESSAGE, "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.No) { return; } } FORM_REPLAY NEW_FORM = new FORM_REPLAY(); NEW_FORM.Show(); NEW_FORM.TopMost = true; //Fill out the injection table. BACKEND.MOVE_CSV_DATA_INTO_INJECTION_TABLE(TABLE, INJECTION_TABLE); //Start the keylogger. REPLAY_SEQUENCE_START(null, null); EVENTS.LOG_MESSAGE(1, "EXIT_SUCCESS"); }
//Methods /// <summary> /// This method is called when the form loads and it is determined to be a "edit recipe" call rather than a "new recipe call". /// The method loads in passed data into all the form objects. /// </summary> /// <param name="CURRENT_RECIPE_DATA">Recipe data to load into the form fields.</param> private void LOAD_IN_EDIT_DATA(RECIPE_DATA CURRENT_RECIPE_DATA) //Logged and documented. { EVENTS.LOG_MESSAGE(1, "ENTER"); TXT_BOX_PART_NUM.Text = CURRENT_RECIPE_DATA.part_number; //Load in part number. EVENTS.LOG_MESSAGE(3, "Part number loaded."); LISTBOX_CHECKSHEET_TYPE.SelectedItem = CURRENT_RECIPE_DATA.checksheet_type; //Load in checksheet type. EVENTS.LOG_MESSAGE(3, "Checksheet type loaded."); string MODIFIED_PATH = CURRENT_RECIPE_DATA.csv_location; //Load in CSV file location. MODIFIED_PATH.Replace(@"\", @"\\"); //The SQL db was squirrelly with storing slashes, it seems to be fine //now and not entirely needed but I don't think its hurting. I'm gonna keep it. TXT_BOX_KEYENCE.Text = MODIFIED_PATH; //Assign the value to the textbox. EVENTS.LOG_MESSAGE(3, "Filepath loaded."); //Load CSV file into viewer. LOAD_CSV_DATA(null, null); DataTable TABLE = new DataTable(); bool SUCCESS = BACKEND.EXTRACT_DATA_TABLE_FROM_DGV(ref DGV1, ref TABLE); if (SUCCESS) { foreach (DataColumn COLUMN in TABLE.Columns) { if (COLUMN.Ordinal == CURRENT_RECIPE_DATA.a_col) { COLUMN.ColumnName = "A"; } if (COLUMN.Ordinal == CURRENT_RECIPE_DATA.b_col) { COLUMN.ColumnName = "B"; } if (COLUMN.Ordinal == CURRENT_RECIPE_DATA.c_col) { COLUMN.ColumnName = "C"; } if (COLUMN.Ordinal == CURRENT_RECIPE_DATA.d_col) { COLUMN.ColumnName = "D"; } if (COLUMN.Ordinal == CURRENT_RECIPE_DATA.e_col) { COLUMN.ColumnName = "E"; } if (COLUMN.Ordinal == CURRENT_RECIPE_DATA.f_col) { COLUMN.ColumnName = "F"; } if (COLUMN.Ordinal == CURRENT_RECIPE_DATA.g_col) { COLUMN.ColumnName = "G"; } if (COLUMN.Ordinal == CURRENT_RECIPE_DATA.h_col) { COLUMN.ColumnName = "H"; } if (COLUMN.Ordinal == CURRENT_RECIPE_DATA.i_col) { COLUMN.ColumnName = "I"; } if (COLUMN.Ordinal == CURRENT_RECIPE_DATA.j_col) { COLUMN.ColumnName = "J"; } if (COLUMN.Ordinal == CURRENT_RECIPE_DATA.k_col) { COLUMN.ColumnName = "K"; } if (COLUMN.Ordinal == CURRENT_RECIPE_DATA.l_col) { COLUMN.ColumnName = "L"; } if (COLUMN.Ordinal == CURRENT_RECIPE_DATA.m_col) { COLUMN.ColumnName = "M"; } if (COLUMN.Ordinal == CURRENT_RECIPE_DATA.timestamp_col) { COLUMN.ColumnName = "TimeStamp"; } } } EVENTS.LOG_MESSAGE(3, "Column names assigned."); DGV1.DataSource = TABLE; EVENTS.LOG_MESSAGE(3, "Table bound to DGV."); COLOR_DGV_COLUMNS(); BACKEND.LOAD_IN_KEY_SEQUENCE(CURRENT_RECIPE_DATA.key_sequence, ref SEQUENCE_LIST, ref SEQUENCE_DATATABLE); EVENTS.LOG_MESSAGE(1, "EXIT_SUCCESS"); }
/// <summary> /// This method is called every time a key is pressed while the key logger is on. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void KEY_LOGGER_KEY_PRESSED_EVENT(object sender, EventArgs e) //Logged and documented. { EVENTS.LOG_MESSAGE(1, "ENTER"); bool KEY_GOOD_TO_LOG = false; if (RECORD_SEQUENCE_ACTIVE) //If the record sequence is active... { string TEXT = (string)sender; if (TEXT.Length == 1) //Indicates that it's not a control key. { char CHAR = TEXT[0]; //Get the character out of the string. if (char.IsLetter(CHAR)) //Determine if the character is a letter... { KEY_GOOD_TO_LOG = true; //Indicate that this key press is valid to log. EVENTS.LOG_MESSAGE(3, string.Format("Detected key {0} will be logged.", TEXT)); } } else //if the key press generated more than one character, its a control key... { if (TEXT == "{TAB}") //Currently TAB key is the only control key we care about. { KEY_GOOD_TO_LOG = true; //Indicate that this key press is valid to log. EVENTS.LOG_MESSAGE(3, string.Format("Detected key {0} will be logged.", TEXT)); } else { EVENTS.LOG_MESSAGE(3, string.Format("Detected key {0} will NOT be logged.", TEXT)); } } if (KEY_GOOD_TO_LOG) //If the key is good to log... { SEQUENCE_LIST.Add(TEXT); //Add the key to the sequence. SEQUENCE_DATATABLE.Rows.Add(TEXT); //Add the key to the sequence. } } else if (REPLAY_SEQUENCE_ACTIVE) //Check if the replay sequence is active (and record is not active due to "else"). { if ((string)sender == "{ESC}") { EVENTS.LOG_MESSAGE(3, "ESC key detected, stopping replay."); REPLAY_SEQUENCE_STOP(null, null); EVENTS.LOG_MESSAGE(1, "EXIT_SUCCESS"); return; } if ((string)sender == "{INSERT}") { EVENTS.LOG_MESSAGE(3, "INSERT key detected, starting replay."); RECORD_SEQUENCE_STOP(null, null); DataTable SOURCE = new DataTable(); bool SUCCESS = BACKEND.EXTRACT_DATA_TABLE_FROM_DGV(ref DGV1, ref SOURCE); if (SUCCESS) { BACKEND.MOVE_CSV_DATA_INTO_INJECTION_TABLE(SOURCE, INJECTION_TABLE); } BACKEND.REPLAY(SEQUENCE_LIST, INJECTION_TABLE); //Where the actual replaying happens. System.Threading.Thread.Sleep(75); //Delay a bit. SendKeys.SendWait("{INSERT}"); //As the insert key is a latched key, we want to turn it back to its original state, so resend. REPLAY_SEQUENCE_ACTIVE = false; } else { EVENTS.LOG_MESSAGE(3, "Program in replay mode, INSERT and ESC are the only valid keys."); } } EVENTS.LOG_MESSAGE(1, "EXIT_SUCCESS"); }
/// <summary> /// This method handles checking that all data is good for saving. It is called when the save button is clicked. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void BTN_SAVE_CLICK(object sender, EventArgs e) //Logged and documented. { EVENTS.LOG_MESSAGE(1, "ENTER"); //Check the part number is good---------------------------------------------------------------------- string TEXT = TXT_BOX_PART_NUM.Text; //Get the canidate string from the textbox. int RESULT = BACKEND.VALIDATE_PART_NUMBER(ref TEXT); //Check the string validity. TXT_BOX_PART_NUM.Text = TEXT; //Reassign the string to the textbox so its capitalized. if (RESULT != 0) //If VALIDATE_PART_NUMBER did not execute successfully... { string MESSAGE = null; switch (RESULT) //Determine exactly what happened and throw the appropriate message. { case (1): MESSAGE = "The part number is not valid. It must be six (6) characters long."; MessageBox.Show(MESSAGE, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); break; case (2): MESSAGE = "The part number is not valid. The first two characters need to be letters."; MessageBox.Show(MESSAGE, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); break; case (3): MESSAGE = "The part number is not valid. The last four characters need to be digits."; MessageBox.Show(MESSAGE, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); break; } EVENTS.LOG_MESSAGE(2, "EXCEPTION", MESSAGE); EVENTS.LOG_MESSAGE(1, "EXIT_FAIL"); return; //Cancel all other operations. } EVENTS.LOG_MESSAGE(3, "Part number is good."); //Check that a checksheet type is selected----------------------------------------------------------- string CHECKSHEET_TYPE = ""; try { CHECKSHEET_TYPE = LISTBOX_CHECKSHEET_TYPE.SelectedItem.ToString(); } catch (NullReferenceException) { string MESSAGE = "Please select a checksheet type."; MessageBox.Show(MESSAGE, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); EVENTS.LOG_MESSAGE(2, "EXCEPTION", MESSAGE); EVENTS.LOG_MESSAGE(1, "EXIT_FAIL"); return; //Cancel all other operations. } EVENTS.LOG_MESSAGE(3, "Sheet type is good."); //Check if the keyence csv path is valid------------------------------------------------------------- bool IS_CSV_VALID = BACKEND.VALIDATE_FILE(TXT_BOX_KEYENCE.Text); if (!IS_CSV_VALID) { return; } EVENTS.LOG_MESSAGE(3, "Path is valid."); //Check that data has been previewed in the viewer--------------------------------------------------- //This bit should no longer be relevant because I changed the code to automatically load whatever //the filepath is, but it can't hurt to keep it in case I did not think of something. if (DGV1.Rows.Count <= 0) { string MESSAGE = "The Keyence CSV file has not been opened and assignments have not been made."; MessageBox.Show(MESSAGE, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); EVENTS.LOG_MESSAGE(2, "EXCEPTION", MESSAGE); EVENTS.LOG_MESSAGE(1, "EXIT_FAIL"); return; //Cancel all other operations. } //Get the DGV table for the next couple steps-------------------------------------------------------- DataTable TABLE = new DataTable(); bool SUCCESS = BACKEND.EXTRACT_DATA_TABLE_FROM_DGV(ref DGV1, ref TABLE); EVENTS.LOG_MESSAGE(3, "Retrieved DataTable."); //Check that a timestamp column is selected---------------------------------------------------------- int TIMESTAMP_INDEX = -1; foreach (DataColumn COLUMN in TABLE.Columns) { if (COLUMN.ColumnName == "TimeStamp") { TIMESTAMP_INDEX = COLUMN.Ordinal; } } if (TIMESTAMP_INDEX == -1) { string MESSAGE = "A timestamp column was not designated, this is required."; MessageBox.Show(MESSAGE, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); EVENTS.LOG_MESSAGE(2, "EXCEPTION", MESSAGE); EVENTS.LOG_MESSAGE(1, "EXIT_FAIL"); return; //Cancel all other operations. } //Generate a string of all the keystrokes------------------------------------------------------------ string KEY_SEQUENCE = ""; foreach (string KEY in SEQUENCE_LIST) { KEY_SEQUENCE += KEY + ","; } EVENTS.LOG_MESSAGE(3, "Key sequence generated."); //Commit the data to the returning package----------------------------------------------------------- RECIPE_DATA DATA = new RECIPE_DATA(); DATA.part_number = TXT_BOX_PART_NUM.Text; DATA.checksheet_type = CHECKSHEET_TYPE; DATA.key_sequence = KEY_SEQUENCE; DATA.csv_location = TXT_BOX_KEYENCE.Text; DATA.timestamp_col = TIMESTAMP_INDEX; DATA.a_col = -1; DATA.b_col = -1; DATA.c_col = -1; DATA.d_col = -1; DATA.e_col = -1; DATA.f_col = -1; DATA.g_col = -1; DATA.h_col = -1; DATA.i_col = -1; DATA.j_col = -1; DATA.k_col = -1; DATA.l_col = -1; DATA.m_col = -1; if (SUCCESS) { foreach (DataColumn COLUMN in TABLE.Columns) { switch (COLUMN.ColumnName) { case ("A"): DATA.a_col = COLUMN.Ordinal; break; case ("B"): DATA.b_col = COLUMN.Ordinal; break; case ("C"): DATA.c_col = COLUMN.Ordinal; break; case ("D"): DATA.d_col = COLUMN.Ordinal; break; case ("E"): DATA.e_col = COLUMN.Ordinal; break; case ("F"): DATA.f_col = COLUMN.Ordinal; break; case ("G"): DATA.g_col = COLUMN.Ordinal; break; case ("H"): DATA.h_col = COLUMN.Ordinal; break; case ("I"): DATA.i_col = COLUMN.Ordinal; break; case ("J"): DATA.j_col = COLUMN.Ordinal; break; case ("K"): DATA.k_col = COLUMN.Ordinal; break; case ("L"): DATA.l_col = COLUMN.Ordinal; break; case ("M"): DATA.m_col = COLUMN.Ordinal; break; } } EVENTS.LOG_MESSAGE(3, "Columns assigned."); } else { string MESSAGE = "Failed to extract DGV Data"; MessageBox.Show(MESSAGE, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); EVENTS.LOG_MESSAGE(2, "EXCEPTION", MESSAGE); EVENTS.LOG_MESSAGE(1, "EXIT_FAIL"); } //Invoke delegate with info pack and close----------------------------------------------------------- DATA_READY?.Invoke(null, DATA); EVENTS.LOG_MESSAGE(1, "EXIT_SUCCESS"); }