DebugLogLevel Enable/Disable
Martin, I wanted a way to enable or disable the DebugLogging & SessionLogging programatically in my app that i built.
On my main form, I added a ToolStripMenu item called Debug and made it Checked type. I then added a bool to the Class file that handles the WinSCP session items, it sets the log paths, and the DebugLogLevel.
Forwarded for info and for use if anyone else is looking for how to do it. Maybe something to add to an example in the documentation section?
[/code]
On my main form, I added a ToolStripMenu item called Debug and made it Checked type. I then added a bool to the Class file that handles the WinSCP session items, it sets the log paths, and the DebugLogLevel.
Forwarded for info and for use if anyone else is looking for how to do it. Maybe something to add to an example in the documentation section?
using System; using System.Collections.Concurrent; using System.Data.SqlClient; using System.IO; using System.Threading; using WinSCP; namespace CnaFirmware { public enum UpdateState { Idle, // black Working, // black Uploading, // complete: CompleteNoError, // green // errors: Aborted, CompleteWithError // red }; public class UploadTask { ConcurrentQueue<string> ConsoleQueue; public string cna_ip; string fingerprint; readonly string ImageFileName; public string CnaVersion; readonly string TargetVersion; public string CurrentFileName; public double CurrentFileProgress; private static string _lastFileName; bool abort = false; Session session; Thread TaskThread; readonly string LogFileName; public string UpdatedFirmwareVersion; public bool WarningShown; // this string is for the user checking status during the update from the UI: public string status; // this status determines the color of the item in the list box public UpdateState state; // these allow the main form to track progress and repaint the item when done public bool UpdateSuccess; public bool JobComplete; public bool NeedUiUpdate; public bool Verbose; // Set WinSCP DebugLogLevel Boolean public bool debug; // need states so the checkedlistbox knows what color to paint this. // this class will push firmware to one CNA. // inputs: IP address of CNA // Fingerprint string // image file (*.run) to upload // queue for sending messages back to main (UI) thread // status: idle // transfering // load (remote script) // complete // logging: only log start, errors, or success to the UI. everything goes to the log file for this cna. // update 20180618: fingerprint is no longer required: WinSCP will scan for fingerprint, then upload firmware. public UploadTask(string cnaip, string fprint, ConcurrentQueue<string> q, string filename) { // DebugLogLevel=0 by default debug = false; cna_ip = cnaip; WarningShown = false; UpdateSuccess = false; fingerprint = fprint; ConsoleQueue = q; ImageFileName = filename; LogFileName = string.Format("{0}\\{1}.log", Globals.LogPath + @"\CNAip\", cna_ip); // for checking file transfer progress: CurrentFileName = string.Empty; CurrentFileProgress = 0; status = "idle"; state = UpdateState.Idle; JobComplete = false; NeedUiUpdate = false; UpdatedFirmwareVersion = ""; // firmware version of target CNA CnaVersion = ""; // new firmware version to be uploaded TargetVersion = ExtractCnaVersion(filename); } // This is to extract the version of the Firmware file string ExtractCnaVersion(string filename) { // ...CNA15xxvX_X_X.run 10,16 string v = "0.0.0"; string f = Path.GetFileName(filename); int posv = f.IndexOf("v"); int posr = f.IndexOf(".run"); posv++; try { v = f.Substring(posv, posr - posv); } catch (Exception) { } return v.Replace("_", "."); } void _PostStatus(string s) { // set status string to what's going on. ConsoleQueue.Enqueue(string.Format("!{0}: {1}", cna_ip, s)); } void NewState(UpdateState s) { state = s; NeedUiUpdate = true; } public void SetCnaVersion(byte[] data) { // Set Expected CNA version if (data[0] < 2) return; string v = string.Format("{0}.{1}.{2}", data[1], data[2], data[3]); Log("SetCnaVersion:" + v); CnaVersion = v; } public void Start() { // Start the Thread TaskThread = new Thread(() => TaskThreadCode()); TaskThread.Start(); } void Logui(string s) { // send to UI ConsoleQueue.Enqueue(string.Format("{0}: {1}", cna_ip, s)); // and file it Log(s); } void Log(string s) { Directory.CreateDirectory(Globals.LogPath + @"\CNAip"); File.AppendAllText(LogFileName, string.Format("{0} {1}: {2}{3}", DateTime.Now.ToString("yyyyMMdd.HHmmss.fff"), cna_ip, s, Environment.NewLine)); } // Upload Status and progress public string GetStatus() { string s = ""; if (status == "uploading binary") { s = string.Format("{0}: uploading binary ({1:P0})", cna_ip, CurrentFileProgress); } else { s = status; s = string.Format("{0}: {1}", cna_ip, status); } return s; } public void TaskThreadCode() { Logui("Starting update"); NewState(UpdateState.Working); try { // first get the CNA SSH fingerprint SessionOptions sessionOptions = new SessionOptions { Protocol = Protocol.Scp, HostName = cna_ip }; sessionOptions.AddRawSettings("KEX", "ecdh,dh-gex-sha1,dh-group14-sha1,dh-group1-sha1,rsa,WARN"); //Session session; using (session = new Session()) { fingerprint = session.ScanFingerprint(sessionOptions, "MD5"); Log($"Fingerprint: {fingerprint}"); } // Set up session options for firmware transfer // The same configuration is used on all devices sessionOptions = new SessionOptions { Protocol = Protocol.Scp, HostName = cna_ip, UserName = "root", Password = "root", SshHostKeyFingerprint = fingerprint }; // This is the same for all connections sessionOptions.AddRawSettings("AuthGSSAPI", "1"); sessionOptions.AddRawSettings("Cipher", "aes,blowfish,3des,chacha20,WARN,arcfour,des"); sessionOptions.AddRawSettings("KEX", "ecdh,dh-gex-sha1,dh-group14-sha1,dh-group1-sha1,rsa,WARN"); status = "uploading binary"; using (session = new Session()) { try { fingerprint = session.ScanFingerprint(sessionOptions, "MD5"); Log($"Fingerprint: {fingerprint}"); // Will continuously report progress of transfer Directory.CreateDirectory(Globals.LogPath + @"\Debug"); // If MenuItem is checked then DebugLogLevel = 2, else Default of 0. // also sets the DebugLogPath and SessionLogPath values. if (debug == true) { session.DebugLogLevel = 2; session.DebugLogPath = Globals.LogPath + @"\Debug\WSCPDebug.log"; session.SessionLogPath = Globals.LogPath + @"\Debug\WSCPSession.log"; } else { session.DebugLogLevel = 0; session.DebugLogPath = null; session.SessionLogPath = null; } session.FileTransferProgress += SessionFileTransferProgress; session.OutputDataReceived += SessionOutputDataReceived; // session.DisableVersionCheck = true; // Connect Log("Opening session"); session.Open(sessionOptions); // Upload files TransferOptions transferOptions = new TransferOptions() { TransferMode = TransferMode.Binary }; // Transfer Results TransferOperationResult transferResult; transferResult = session.PutFiles(ImageFileName, "/var/tmp/*", false, transferOptions); } catch (Exception ex) { Logui("WinSCP: " + ex.Message); ConsoleQueue.Enqueue("@" + ex.Message); status = "WinSCP Error"; NewState(UpdateState.CompleteWithError); JobComplete = true; _PostStatus("Failed"); // terminate thread return; } if (abort) session.Close(); // Write to log upload status Log("File transfer succeeded"); // PutFiles has completed: now run bash script. status = "waiting for remote load"; // Change to the remote directory. session.ExecuteCommand("cd /tmp"); // Modify the permissions on the *.run file. session.ExecuteCommand("chmod 777 *.run"); // Log entry status update. Log("Running remote command: load"); // This command will display the completion of the Load command results, including version information. session.ExecuteCommand(string.Format("./{0} --load", Path.GetFileName(ImageFileName))); // note: you should never get here! // Eprom load completed, executing reboot. status = "remote load complete"; // Add entery to log that session is closing. Log("Closing WinSCP session"); // Close the session. session.Close(); } } catch (Exception e) { // either the update was aborted by the user, or an error occurred, or the upload was successful. // so - this thread will always exit from here. if (e.Message == "Aborted.") { // Abort the Threads. if (abort) { // user abort status = "User abort"; NewState(UpdateState.Idle); Logui("Update cancelled by user"); } else { // normal (success) if (UpdateSuccess) { status = "updating database"; Log("Updating database record"); UpdateDbRecord(); UpdatedFirmwareVersion = TargetVersion; Logui("Update successful"); NewState(UpdateState.CompleteNoError); status = "CNA update complete"; } } } else { // a real error occurred, and this thread will exit with an error status. status = "Error"; NewState(UpdateState.CompleteWithError); Logui(string.Format("Error: {0}", e.Message)); } } JobComplete = true; } void SessionFileTransferProgress(object sender, FileTransferProgressEventArgs e) { // This displays the file transfer status percentage. if (abort) session.Abort(); //New line for every new file if ((_lastFileName != null) && (_lastFileName != e.FileName)) { Log(string.Format("Uploading: {0}", e.FileName)); } // Print transfer progress _PostStatus(string.Format("Uploading: {0:P0}", e.FileProgress)); // Remember a name of the last file reported _lastFileName = e.FileName; CurrentFileProgress = e.FileProgress; } void SessionOutputDataReceived(object sender, OutputDataReceivedEventArgs e) { if (abort) session.Abort(); if ( e.Data.Contains("Starting") || e.Data.Contains("Opening") || e.Data.Contains("Searching") || e.Data.Contains("Connecting") || e.Data.Contains("Updating") || e.Data.Contains("Validating") || e.Data.Contains("Authenticating...") || e.Data == "File transfer succeeded" || e.Data == "Valid firmware" || e.Data == "Update successful" ) _PostStatus(e.Data); Log(e.Data); if (e.Data.Contains("Updating CNA") && e.Data.Contains("success")) { UpdateSuccess = true; _PostStatus("Firmware update was successful."); // done: abort the session now session.Abort(); } } public void Cancel() { abort = true; //logui("Upload Cancelled by User!"); } void UpdateDbRecord() { // This routine is for updating the Firmware version number in the nms_cfg database. SqlConnection NmsRt; using (NmsRt = new SqlConnection(Globals.ConnectionString)) { try { NmsRt.Open(); } catch (Exception) { Logui("Unable to open NMS database."); return; } string query = string.Format("update cna_firmware set firmware_rev = '{0}' where ip_address = '{1}'", TargetVersion, cna_ip); try { using (SqlCommand sql = new SqlCommand(query, NmsRt)) sql.ExecuteNonQuery(); } catch (Exception ex) { Logui("UpdateDbRecord: " + ex.Message); } } } } }