Brief Information about the November 2015 CSIG Meeting
Obackup - An Occasional Backup Copy Program
by Bruce Arnold(General Csig Info) This month's application is a Microsoft C-sharp program that deals with logic and graphics. We will also be discussing the latest Microsoft free compiler Visual Studio 2015. This new software has many new industry features such as:
Visual Studio Community 2015 |
---|
Framework .NET 4.6 |
Support for Windows, Linux, and Os X |
DotNet Open Source on Github |
Support for all phones |
C# Version 6 |
Code syntax simplification like string formatting |
Website: gethub.com/dotnet/roslyn |
Universal Windows Apps: Phones, Tablets, Raspberry Pi, etc. |
Welcome to the CSIG, a Special Interest Group of the ACGNJ. This is an exciting time for the C Language programming since Microsoft now has 4 different language compilers: C++, C++ Express, C-Sharp, and C-Sharp Express. These are all capable of creating Windows (tm) programs. (Some are FREE!)
The program for this month performs backup copies. This utility will copy a file to a chosen folder every so often. A typical use is as follows: the application is initiated by the Windows Task Scheduler at user log on. If (say) 7 or more days elapsed, the file will be copied. (For example: OUTLOOK.PST ) For more information take a look at the screen images above.
From a computer programming perspective, this app has a number of interesting features:
- It solves the years-old problem of backing up the Outlook mail program that is too big for most automated backup programs.
- It deals with an operating system copy operation.
- The copy operation is further enhanced by using threads in a background operation.
- A large annunciator sign is included to show the user the operation performed.
- It uses various calendar functions of the dotNet library.
- File I/O is initiated by providing dialogs with the user for the selection of files and folders
- String manipulation is added to provide distinct filenames with enclosed date information.
- Windows Registry algorithms are provided in order to save permanent information for repeated runs.
- Windows Event viewer algorithms are provided in order to log activity.
- Windows Timer functions are used for several purposes.
- Text box input is validated to assure proper data is entered.
There are a number of ways to refer to Microsoft's latest compilers and code. Here's what Wikipedia says: The Common Language Infrastructure (CLI) is an open specification developed by Microsoft that describes the executable code and runtime environment that form the core of the Microsoft .NET Framework. The specification defines an environment that allows multiple high-level languages to be used on different computer platforms without being rewritten for specific architectures.
Microsoft .Net Framework 3.5 |
C++ 9.0 |
.Net 3.5 |
CLI |
Common Language Infrastructure |
Managed |
Sample Code
//
// Force entry of numeric digits on screen dialog.
//
private void TimeInDays_Validating(object sender, CancelEventArgs e)
{
int numberEntered;
if (int.TryParse(TimeInDays.Text, out numberEntered))
{
if (numberEntered < 0 || numberEntered > 31)
{
TimeInDays.Text = "7";
}
}
else
TimeInDays.Text = "7";
TimeInDays.Update();
SaveAllTypedInfo();
}
//
// Force TimeInDays_Validating() to validate entry
//
private void Form1_Click(object sender, EventArgs e)
{
this.label4.Focus(); // Trick to remove focus from TimeInDays textbox.
}
//
// Time keeping routines follow.
//
private string GetCurrentDay()
{
DateTime dt_Epoch = new DateTime(2000, 1, 1);
DateTime dt_Today = DateTime.Now;
TimeSpan span_Current = dt_Today - dt_Epoch;
return span_Current.Days.ToString();
}
private bool IsCopyRequired()
{
DateTime dt_Epoch = new DateTime(2000, 1, 1);
DateTime dt_Today = DateTime.Now;
DateTime dt_Lastsave = dt_Epoch.AddDays(Convert.ToInt32(s_Lastsave));
TimeSpan span_Elapsed = dt_Today - dt_Lastsave;
//string status = string.Format(
// " dt_Epoch={0}\r\n dt_Today={1}\r\n dt_Lastsave={2}\r\n span_Elapsed={3}\r\n span_Elapsed.Days={4}",
//dt_Epoch.ToLongDateString(),
//dt_Today.ToLongDateString(),
//dt_Lastsave.ToLongDateString(),
//span_Elapsed.ToString(),
//span_Elapsed.Days.ToString()); MessageBox.Show(status);
if (span_Elapsed.Days >= Convert.ToInt32(this.TimeInDays.Text.ToString()))
return true;
else
return false;
}
// The button above the Source File has been hit.
// Browse for a new file to read and then initialize the logic.
//
private void PickSource_Click(object sender, EventArgs e)
{
OpenFileDialog dlg = new OpenFileDialog();
if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
SourceFile.Text = dlg.FileName;
SourceFilePath = dlg.FileName;
SourceFileBase = System.IO.Path.GetFileNameWithoutExtension(dlg.FileName);
SourceFileExt = System.IO.Path.GetExtension(dlg.FileName);
s_Lastsave = "0"; // set back to Epoch
SaveAllTypedInfo();
}
}
// The button above the Destination Folder has been hit.
// Browse and then initialize the logic.
//
private void PickDestination_Click(object sender, EventArgs e)
{
FolderBrowserDialog dlg = new FolderBrowserDialog();
if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
this.DestinationFolder.Text = dlg.SelectedPath.ToString();
s_Lastsave = "0"; // set back
SaveAllTypedInfo();
}
}
//
// Perform the copy operation if the logic permits.
//
private void CopyNow_Click(object sender, EventArgs e)
{
// LogActivity("Obackup copy attempt"); // System Application Event Log
if (SourceFile.Text.Length > 0)
{
DateTime lastWriteTime = File.GetLastWriteTime(SourceFile.Text);
string suffix = " (" + lastWriteTime.ToString() + ")";
suffix = suffix.Replace(':', '_');
suffix = suffix.Replace('/', '_');
AdjustedDestinationFile = DestinationFolder.Text + "\\" + SourceFileBase + suffix + SourceFileExt;
}
if (AdjustedDestinationFile == null || SourceFilePath == null) return;
if (AdjustedDestinationFile.Length > 0 && SourceFilePath.Length > 0)
{
if (false == File.Exists(AdjustedDestinationFile) && true == IsCopyRequired())
{
CopyNow.Enabled = PickSource.Enabled = PickDestination.Enabled = false; TimeInDays.ReadOnly = true;
WaitLabel.Visible = true;
Update();
LogActivity(AdjustedDestinationFile); // System Application Event Log
this.backgroundWorker1.RunWorkerAsync();
}
else if (autoclose.Checked)
{
this.Close();
}
}
}
//
// THREAD logic here.
//
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
File.Copy(SourceFilePath, AdjustedDestinationFile);
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
s_Lastsave = s_CurrentDay;
SaveAllTypedInfo();
CopyNow.Enabled = PickSource.Enabled = PickDestination.Enabled = true; TimeInDays.ReadOnly = false;
Update();
System.Threading.Thread.Sleep(3000);
WaitLabel.Visible = false;
Update();
if (autoclose.Checked)
{
this.Close(); // That's all folks.
}
}
SOURCE CODE
For help, email me at b a r n o l d @ i e e e . o r gBack to C++ Main Page