Monday, November 5, 2007

Starting With Visual Studio 2005 and C#








When one starts up VS(C#) and invokes the "New Project" menu item, one sees:

and when one choose a Windows Application and gives it a unique name, one gets a window showing a form. Double clicking on this form shows its code.
On my machine, that code is:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace TestApplication1 {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e) {
}
}
}

since I named my application "TestApplication1". Notice that the figure (above) shows a template highlighted, but when I created the above code, I clicked on the upper left icon.

The code "looks" like:

There are two tabs on the top, "Form1.cs*" and "Form1.cs[design]*". Clicking on one of these two tabs switches us from the code to the Design and vice versa.

Making the form design active makes the screen look like:

where the "Toolbox" in the upper left corner has an item circled (by me) where one can click next (to make active).
Dragging it to the form places a button on the form:

where we've juxtaposed two parts which will be separated on your screen.

You will see that what we've got is a button, "button1" written on its face. On the propertied window, you will see "Text" and to the right of that, "button1". You can change "button1" to "Do It If You Dare" by overtyping the text in the Properties Text value box. Try it, you'll like it:

Wow. Since the button as created by VS(C#) doesn't show all the letters in "Do It If You Dare" resize it using the mouse.

Looking at the top of the Properties list, you will see:

and you can change the name from button1, which is in my world, meaningless to something like "DoItButton" which will change all the code which refers to this button into a self-referential form tagged with "DoItButton".


When one double clicks on this button now, an EventHandler will be created for it.
This is the place where we put our code for what to do when the button is pushed. The code created is:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace TestApplication1 {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e) {

}

private void DoItButton_Click(object sender, EventArgs e) {

}
}
}

where it would have read "button1_Click had we not re-named the button.

Our interest is in setting up an elementary application which will not only act as a kind of template for future developmental work, but also illustrate how that developmental work can be incorporated into future products efficiently. Thus, we are going to create another form, and in that (daughter) form, we are going to do our actual experimental coding, passing an answer back to the above (main) application. We are therefore going to add a new class.

To do this, right click on the "TestApplication1" (highlighted partially in the accompanying figure) line in Solution Explorer, go down to "Add"

and choose "New Item". Inside this choice, you will see lots of choices, and we choose a new class, which we call "TestApplicationDlg":
using System;
using System.Collections.Generic;
using System.Text;

namespace TestApplication1 {
class TestApplicationDlg {
}
}
since this will be a Dialog. Change the appropriate line to:

class TestApplicationDlg:System.Windows.Forms.Form

and now, when you right click on the C# code, you will be allowed to create a new Form! Incredible!

Here is the new Form's code:

using System;
using System.Collections.Generic;
using System.Text;

namespace TestApplication1 {
class TestApplicationDlg : System.Windows.Forms.Form {
private System.Windows.Forms.TextBox myTextBox;
private System.Windows.Forms.Button Submit;
// added by cwd
public TestApplicationDlg() {
InitializeComponent();
}
// end of addition by cwd

private void InitializeComponent() {
this.myTextBox = new System.Windows.Forms.TextBox();
this.Submit = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// myTextBox
//
this.myTextBox.Location = new System.Drawing.Point(73, 55);
this.myTextBox.Name = "myTextBox";
this.myTextBox.Size = new System.Drawing.Size(100, 20);
this.myTextBox.TabIndex = 0;
this.myTextBox.Text = "Enter Text Here";
//
// Submit
//
this.Submit.Location = new System.Drawing.Point(192, 215);
this.Submit.Name = "Submit";
this.Submit.Size = new System.Drawing.Size(75, 23);
this.Submit.TabIndex = 1;
this.Submit.Text = "Submit";
this.Submit.UseVisualStyleBackColor = true;
this.Submit.Click += new System.EventHandler(this.Submit_Click);
//
// TestApplicationDlg
//
this.ClientSize = new System.Drawing.Size(292, 266);
this.Controls.Add(this.Submit);
this.Controls.Add(this.myTextBox);
this.Name = "TestApplicationDlg";
this.ResumeLayout(false);
this.PerformLayout();
}
//beginning of new code by cwd
private void Submit_Click(object sender, EventArgs e) {
DialogResult = System.Windows.Forms.DialogResult.OK;
Close();
}
public String getText() {
return myTextBox.Text;
}

}

}

and here is the slightly adjusted (and to be explained) Form1 code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;


namespace TestApplication1 {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e) {

}

private void DoItButton_Click(object sender, EventArgs e) {
TestApplicationDlg myTestApplicationDlg = new TestApplicationDlg();
if (myTestApplicationDlg.ShowDialog(this) == DialogResult.OK) {
String returned_text = myTestApplicationDlg.getText();
MessageBox.Show("results = "+returned_text);
}
myTestApplicationDlg.Dispose();
}
}
}


The MessageBox.Show gives the results of the Dialog we've initiated above. This set of two programs, created as we've done, acts as a scaffold on which test items can be added to the Dialog and checked so that, when all is ready, that Dialog can be employed elsewhere without copying code.










Google


















Avoiding KeyStrokes in Windows Applications using C#



============================



In keeping with the bcrypt.exe example cited elsewhere in this blog (belowbcrypt.exe development), we seek a method of avoiding using the keypad to enter pass words and/or phrases. A version of this appeared on the Treasury Direct site, but I had the idea earlier, and herein implement it here.

The code is much to large to enter here, so I've removed parts to highlight what must be done.
We've created a class (Typer) and it puts up a form which has the standard keyboard implemented as buttons, along with one label and one textwindow. Each button is dragged over from the palette, placed and sized appropriately, re-named so that the internal code references are self-identifying. Notice that this is the simplest programming possible, i.e., no indexing of arrays has been used to make the code compact and/or swift. This is simple mindedness carried to an extreme! Here is the layout of the final screen which I've employed:



The beginning code, with parts excluded, especially those generated by the Forms generator, begins here:

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Text.RegularExpressions;

namespace Typer {
///
/// Summary description keystroke eliminator for password input.
///

public class TyperDlg : System.Windows.Forms.Form {
private Button bq;
private Button bw;
private Button be;
private Button br;
private Button bt;
private Button by;
private Button bu;
private Button bi;
private Button bo;
private Button bp;
private Button b0;
private Button b9;
private Button b8;
private Button b7;
private Button b6;
private Button b5;
private Button b4;
private Button b3;
private Button b2;
private Button b1;
private Button bminus;
private Button bequals;
private Button bl;
private Button bk;
private Button bj;
private Button bh;
private Button bg;
private Button bf;
private Button bd;
private Button bs;
private Button ba;
private Button bm;
private Button bn;
private Button bb;
private Button bv;
private Button bc;
private Button bx;
private Button bz;
private Button Shift;
private Button Submit;
private TextBox textBox1;
private Label label1;
private Button BackSpace;
private Button Delete;
private Button buttonLeft;
private Button buttonRight;
private Button SpaceBar;
///
/// Required designer variable.
///

private System.ComponentModel.Container components = null;

public TyperDlg() {
//
// Required for Windows Form Designer support
//
InitializeComponent();

We're going to use the vertical separator as a running cursor, so we make our output equal to it at the outset.

resultant = "|";
textBox1.Text = resultant;
//
// TODO: Add any constructor code after InitializeComponent call
//
}

///
/// Clean up any resources being used.
///

protected override void Dispose(bool disposing) {
if (disposing) {
if (components != null) {
components.Dispose();
}
}
base.Dispose(disposing);
}

#region Windows Form Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///

private void InitializeComponent() {
this.bq = new System.Windows.Forms.Button();
this.bw = new System.Windows.Forms.Button();
this.be = new System.Windows.Forms.Button();
this.br = new System.Windows.Forms.Button();

We've omitted lots of similar code here for each button.

this.SuspendLayout();

Each key is created by dragging a button from the palette, re-naming it, and putting in the lower case text which will be shown (unshifted). However, note below that number keys are specially handled, since their upcase/lowercase functionality is not present the way it is with simple letters.

Later, each key will also be doubleclicked, leading to an EventHandler whose definition shows up here, but which is actually inserted later in the creation process. Be that as it may, to get to that code, double click on the button whose code you want to deal with (see below).

//
// bq
//
this.bq.Location = new System.Drawing.Point(62, 130);
this.bq.Name = "bq";
this.bq.Size = new System.Drawing.Size(26, 23);
this.bq.TabIndex = 0;
this.bq.Text = "q";
this.bq.UseVisualStyleBackColor = true;
this.bq.Click += new System.EventHandler(this.bq_Click);
//
// bw
//
this.bw.Location = new System.Drawing.Point(94, 130);
this.bw.Name = "bw";
this.bw.Size = new System.Drawing.Size(26, 23);
this.bw.TabIndex = 1;
this.bw.Text = "w";
this.bw.UseVisualStyleBackColor = true;
this.bw.Click += new System.EventHandler(this.bw_Click);
//
// be
//
this.be.Location = new System.Drawing.Point(126, 130);
this.be.Name = "be";
this.be.Size = new System.Drawing.Size(26, 23);
this.be.TabIndex = 2;
this.be.Text = "e";
this.be.UseVisualStyleBackColor = true;
this.be.Click += new System.EventHandler(this.be_Click);
//
// br
//
this.br.Location = new System.Drawing.Point(158, 130);
this.br.Name = "br";
this.br.Size = new System.Drawing.Size(26, 23);
this.br.TabIndex = 3;
this.br.Text = "r";
this.br.UseVisualStyleBackColor = true;
this.br.Click += new System.EventHandler(this.br_Click);
//
// bt
//
this.bt.Location = new System.Drawing.Point(190, 130);
this.bt.Name = "bt";
this.bt.Size = new System.Drawing.Size(26, 23);
this.bt.TabIndex = 4;
this.bt.Text = "t";
this.bt.UseVisualStyleBackColor = true;
this.bt.Click += new System.EventHandler(this.bt_Click);
//
// by
//
this.by.Location = new System.Drawing.Point(222, 130);
this.by.Name = "by";
this.by.Size = new System.Drawing.Size(26, 23);
this.by.TabIndex = 5;
this.by.Text = "y";
this.by.UseVisualStyleBackColor = true;
this.by.Click += new System.EventHandler(this.by_Click);
//
// bu
//
this.bu.Location = new System.Drawing.Point(254, 130);
this.bu.Name = "bu";
this.bu.Size = new System.Drawing.Size(26, 23);
this.bu.TabIndex = 6;
this.bu.Text = "u";
this.bu.UseVisualStyleBackColor = true;
this.bu.Click += new System.EventHandler(this.bu_Click);
//
// bi

Again, we eliminate lots of code here, one set of 7 lines per key.


//
// bequals
//
this.bequals.Location = new System.Drawing.Point(399, 101);
this.bequals.Name = "bequals";
this.bequals.Size = new System.Drawing.Size(26, 23);
this.bequals.TabIndex = 21;
this.bequals.Text = "=";
this.bequals.UseVisualStyleBackColor = true;
this.bequals.Click += new System.EventHandler(this.bequals_Click);
//
// bl
//

And we again eliminate code which teaches us nothing:

Here we treat some special keys:

//
// Shift
//
this.Shift.BackColor = System.Drawing.Color.DodgerBlue;
this.Shift.Location = new System.Drawing.Point(12, 217);
this.Shift.Name = "Shift";
this.Shift.Size = new System.Drawing.Size(72, 36);
this.Shift.TabIndex = 39;
this.Shift.Text = "Shift";
this.Shift.UseVisualStyleBackColor = false;
this.Shift.Click += new System.EventHandler(this.Shift_Click);
//
// Submit
//
this.Submit.BackColor = System.Drawing.Color.Lime;
this.Submit.Location = new System.Drawing.Point(329, 210);
this.Submit.Name = "Submit";
this.Submit.Size = new System.Drawing.Size(107, 43);
this.Submit.TabIndex = 40;
this.Submit.Text = "Submit";
this.Submit.UseVisualStyleBackColor = false;
this.Submit.Click += new System.EventHandler(this.Submit_Click);
//
//textBox1
//
this.textBox1.Location = new System.Drawing.Point(44, 47);
this.textBox1.Multiline = true;
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(281, 48);
this.textBox1.TabIndex = 41;
//
// label1
//
this.label1.AutoSize = true;
this.label1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Italic, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label1.ForeColor = System.Drawing.Color.Aqua;
this.label1.Location = new System.Drawing.Point(12, 10);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(424, 19);
this.label1.TabIndex = 42;
this.label1.Text = "Enter your passphrase here (including spaces) then press Submit";
//
// BackSpace
//
this.BackSpace.BackColor = System.Drawing.Color.Red;
this.BackSpace.Location = new System.Drawing.Point(329, 43);
this.BackSpace.Name = "BackSpace";
this.BackSpace.Size = new System.Drawing.Size(106, 23);
this.BackSpace.TabIndex = 43;
this.BackSpace.Text = "BackSpace Delete";
this.BackSpace.UseVisualStyleBackColor = false;
this.BackSpace.Click += new System.EventHandler(this.BackSpace_Click);
//
// Delete
//
this.Delete.BackColor = System.Drawing.Color.Yellow;
this.Delete.Location = new System.Drawing.Point(329, 72);
this.Delete.Name = "Delete";
this.Delete.Size = new System.Drawing.Size(106, 23);
this.Delete.TabIndex = 44;
this.Delete.Text = "Delete (Forward)";
this.Delete.UseVisualStyleBackColor = false;
this.Delete.Click += new System.EventHandler(this.Delete_Click);
//
// buttonLeft
//
this.buttonLeft.BackColor = System.Drawing.Color.Salmon;
this.buttonLeft.Location = new System.Drawing.Point(13, 175);
this.buttonLeft.Name = "buttonLeft";
this.buttonLeft.Size = new System.Drawing.Size(60, 36);
this.buttonLeft.TabIndex = 45;
this.buttonLeft.Text = "Left Cursor";
this.buttonLeft.UseVisualStyleBackColor = false;
this.buttonLeft.Click += new System.EventHandler(this.buttonLeft_Click);
//
// buttonRight
//
this.buttonRight.BackColor = System.Drawing.Color.PaleGreen;
this.buttonRight.Location = new System.Drawing.Point(377, 168);
this.buttonRight.Name = "buttonRight";
this.buttonRight.Size = new System.Drawing.Size(58, 36);
this.buttonRight.TabIndex = 46;
this.buttonRight.Text = "Right Cursor";
this.buttonRight.UseVisualStyleBackColor = false;
this.buttonRight.Click += new System.EventHandler(this.buttonRight_Click);
//
// SpaceBar
//
this.SpaceBar.Location = new System.Drawing.Point(90, 227);
this.SpaceBar.Name = "SpaceBar";
this.SpaceBar.Size = new System.Drawing.Size(235, 22);
this.SpaceBar.TabIndex = 47;
this.SpaceBar.Text = "SpaceBar";
this.SpaceBar.UseVisualStyleBackColor = true;
this.SpaceBar.Click += new System.EventHandler(this.SpaceBar_Click);
//
// TyperDlg
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(452, 275);
this.Controls.Add(this.SpaceBar);
this.Controls.Add(this.buttonRight);
this.Controls.Add(this.buttonLeft);
this.Controls.Add(this.Delete);
this.Controls.Add(this.BackSpace);
this.Controls.Add(this.label1);
this.Controls.Add(this.textBox1);
this.Controls.Add(this.Submit);
this.Controls.Add(this.Shift);
this.Controls.Add(this.bm);
this.Controls.Add(this.bn);
this.Controls.Add(this.bb);
this.Controls.Add(this.bv);
this.Controls.Add(this.bc);
this.Controls.Add(this.bx);

And again, we eliminate repetitive coding which is obvious.


this.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "TyperDlg";
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Please Enter a PassPhrase";
this.Load += new System.EventHandler(this.typerDlg_Load);
this.ResumeLayout(false);
this.PerformLayout();

}
#endregion

private void typerDlg_Load(object sender, System.EventArgs e) {
}


Here we indicate the EventHandler for making the display react to the Shift button.
Notice that the top line of keys has to be handled separately, since the display tokens are different between upper case and lower case. Shift_engaged is a flag used to remember whether or not the shift key was hit (CAPS-LOCK).

private void Shift_Click(object sender, EventArgs e) {
if (!Shift_engaged) {
safety_color = Shift.BackColor;
Shift.BackColor = Color.Red;
bq.Text = bq.Text.ToUpper();
bw.Text = bw.Text.ToUpper();
be.Text = be.Text.ToUpper();
br.Text = br.Text.ToUpper();
bt.Text = bt.Text.ToUpper();
by.Text = by.Text.ToUpper();
bu.Text = bu.Text.ToUpper();
bi.Text = bi.Text.ToUpper();
bo.Text = bo.Text.ToUpper();
bp.Text = bp.Text.ToUpper();
//row 2
ba.Text = ba.Text.ToUpper();
bs.Text = bs.Text.ToUpper();
bd.Text = bd.Text.ToUpper();
bf.Text = bf.Text.ToUpper();
bg.Text = bg.Text.ToUpper();
bh.Text = bh.Text.ToUpper();
bj.Text = bj.Text.ToUpper();
bk.Text = bk.Text.ToUpper();
bl.Text = bl.Text.ToUpper();
//row 2
bz.Text = bz.Text.ToUpper();
bx.Text = bx.Text.ToUpper();
bc.Text = bc.Text.ToUpper();
bv.Text = bv.Text.ToUpper();
bb.Text = bb.Text.ToUpper();
bn.Text = bn.Text.ToUpper();
bm.Text = bm.Text.ToUpper();
b1.Text = "!";
b2.Text = "@";
b3.Text = "#";
b4.Text = "$";
b5.Text = "%";
b6.Text = "^";
b7.Text = "&";
b8.Text = "*";
b9.Text = "(";
bminus.Text = ")";
bequals.Text = "_";
Shift_engaged = !Shift_engaged;
return;
}
else {
Shift.BackColor = safety_color;
bq.Text = bq.Text.ToLower();
bw.Text = bw.Text.ToLower();
be.Text = be.Text.ToLower();
br.Text = br.Text.ToLower();
bt.Text = bt.Text.ToLower();
by.Text = by.Text.ToLower();
bu.Text = bu.Text.ToLower();
bi.Text = bi.Text.ToLower();
bo.Text = bo.Text.ToLower();
bp.Text = bp.Text.ToLower();
//row 2
ba.Text = ba.Text.ToLower();
bs.Text = bs.Text.ToLower();
bd.Text = bd.Text.ToLower();
bf.Text = bf.Text.ToLower();
bg.Text = bg.Text.ToLower();
bh.Text = bh.Text.ToLower();
bj.Text = bj.Text.ToLower();
bk.Text = bk.Text.ToLower();
bl.Text = bl.Text.ToLower();
//row 3
bz.Text = bz.Text.ToLower();
bx.Text = bx.Text.ToLower();
bc.Text = bc.Text.ToLower();
bv.Text = bv.Text.ToLower();
bb.Text = bb.Text.ToLower();
bn.Text = bn.Text.ToLower();
bm.Text = bm.Text.ToLower();
//row 0
b1.Text = "1";
b2.Text = "2";
b3.Text = "3";
b4.Text = "4";
b5.Text = "5";
b6.Text = "6";
b7.Text = "7";
b8.Text = "8";
b9.Text = "9";
bminus.Text = "-";
bequals.Text = "=";

Shift_engaged = !Shift_engaged;
return;
}
}
public Boolean Shift_engaged = false;
public Color safety_color;
public String resultant = "|";

When the user clicks Submit, we want the resultant to be prepared and ready for whatever use the program wants. For testing purposes, we have a MessageBox which we use to tell us what pass phrase is being assembled, but we comment it out when in "production".

private void Submit_Click(object sender, EventArgs e) {
// resultant = "|";//set up for next time?
if (resultant.Length == 0) {
MessageBox.Show(this,
"Please enter a valid password here.", "Input Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
DialogResult = DialogResult.OK;
resultant = resultant.Replace("|","");
resultant = resultant.Trim();
/*
MessageBox.Show("Your password was:\n\r" + resultant, "Result from Submit Button ",
MessageBoxButtons.OK, MessageBoxIcon.Warning);

* */
Close();
}

Notice that in the above code, we've removed our cursor, and trimmed off outlying blanks. This is our choice!


public System.String getPass() {
return resultant;
}

What follows is the EventHandler for some of the keys, beginning with the "q" key. Each key is handled identically, but with a different letter being used. We are not trying to be sophisticated here, just transparent in the coding!


private void bq_Click(object sender, EventArgs e) {
if (Shift_engaged) {
resultant = resultant.Replace("|", "Q|");
}
else {
resultant = resultant.Replace("|", "q|");
}
textBox1.Text = resultant;
return;
}

private void bw_Click(object sender, EventArgs e) {
if (Shift_engaged) {
resultant = resultant.Replace("|", "W|");
}
else {
resultant = resultant.Replace("|", "w|");
}
textBox1.Text = resultant;
return;
}

private void be_Click(object sender, EventArgs e) {
if (Shift_engaged) {
resultant = resultant.Replace("|", "E|");
}
else {
resultant = resultant.Replace("|", "e|");
}
textBox1.Text = resultant;
return;
}

private void br_Click(object sender, EventArgs e) {
if (Shift_engaged) {
resultant = resultant.Replace("|", "R|");
}
else {
resultant = resultant.Replace("|", "r|");
}
textBox1.Text = resultant;
return;
}

private void bt_Click(object sender, EventArgs e) {
if (Shift_engaged) {
resultant = resultant.Replace("|", "T|");
}
else {
resultant = resultant.Replace("|", "t|");
}
textBox1.Text = resultant;
return;
}

We need a handler for each key, but the coding is so repetitive and simpleminded that there's no point in repeating it all here.

private void buttonRight_Click(object sender, EventArgs e) {
int index = resultant.IndexOf(@"|");
if (index < resultant.Length-1) {
String mychar = resultant.Substring(index + 1, 1);
String subsin = "|" + mychar;
String subsout = mychar + "|" ;
resultant = resultant.Replace(subsin, subsout); textBox1.Text = resultant;
}
}

Text eliminated here for other buttons, but you get the idea.

}

We've attempted to indicate enough code so that you can follow the logic without seeing each and every key and its functioning.

There are two aspects of key stroke handling being employed here.
First, we have the appearance, which is controlled by the "Shift" button, which here functions as a CAPS-LOCK toggle. Each key's symbol changes on the keyboard itself from one case to the other when the "Shift" key is toggled.

The second aspect is the handling of each mouse click on a key, which is handled with separate handlers. Several of them are shown above.




Google















Friday, November 2, 2007

Using bcrypt.exe as a Windows App in C#






Command Line to Windows Application Conversion Using C# and cmd.exe


The desire to adapt the bcrypt module (bcrypt.sourceforge.net) to a Windows Application format motivated this work, which is explained here. bcrypt encrypts files using the Blowfish scheme; details about the encryption and decryption may be



using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.IO;
using System.Collections;
using System.Threading;
using System.Text.RegularExpressions;
using PasswordDialog;/* see earlier manuscript (password dialog and namespace discussion:



C# Namespace Usage for Including Foreign Projects



namespace bcrypt {
public partial class Form1 : Form {
public Form1() {
//this form was created in the standard manner with one button only ("DOIT").
InitializeComponent();
}
(The creation of this form by drop-and-drag in Visual Studio is not discussed here.)

I simplified the user interface by having one button only, which when pressed, caused the following process to be carried out. The color coding of instances is intended to make the dispersed information slightly more understandable (I hope it works).

The first task is to realize that I am going to need a cmd.exe shell, which in C# is called a Process. We call my version of this process myBcrypt, and intend to use it further on down in the code.

But first, I need to find out what file we want encrypted or decrypted. For this I employ a FileDialog. The next few lines of code are settings required for this FileDialog. The only one that should be changed when in production, is the InitialDirectory value, which is set to the place where the bcrypt.exe files and the appropriate dll files are stored:

In the example being discussed, the directory structure is shown above. I stored test case files there for en- and de-cryption during debugging. This saves some repetitive clicking about, and should/can be changed by the reader!



private void button1_Click(object sender, EventArgs e) {
//this is the DOIT buttons action
Process myBcrypt = new Process();// see the code below marked ($%$).
OpenFileDialog fdlg = new OpenFileDialog();
fdlg.Title = "BCRYPTOpen File Dialog";
fdlg.InitialDirectory = @"C:/Documents and Settings/david/My Documents/Visual Studio 2005/Projects/bcrypt";
fdlg.Filter = "All files (*.*)*.*All files (*.*)*.*";
fdlg.FilterIndex = 2;
fdlg.RestoreDirectory = true;


Ah, not so fast! Before I do the file directory thing, let's do the password thing, so that we can apply the password to the file when the time comes. So here is the password thing. This has been discussed (password dialog and namespace discussion) already in these pages. The password program was downloaded into a separate project, compiled and tested there, and part of it is to be used here.

passwordDlg passForm = new passwordDlg();
if (passForm.ShowDialog(this) == DialogResult.OK) {
/* OK, do something with the password. This is just a demo.. so lets just splash it up for the world to see.
MessageBox.Show(this,"The password entered was: " + passForm.getPass(), "Password Result",
MessageBoxButtons.OK, MessageBoxIcon.Information);
used earlier to confirm that entered password was the one desired
*/
}
passForm.Dispose();




If we get this far, the password has passed muster, i.e., is 14 characters long (at least) has lower case, uppercase, numbers, strange symbols, etc., and we're ready to do. The following text checks the password, and executes the including code if all is well.

if (Regex.IsMatch(passForm.getPass(), regex_psswd)) {
if (fdlg.ShowDialog() == DialogResult.OK) {

myFile = fdlg.FileName;
FileInfo fleMembers = new FileInfo(myFile);
myFile = fleMembers.Name;


First, we need to obtain the file's name from the dialog. Then, it turns out that this is the entire one, i.e., "C:\Doc..." and when that was passed to brcypt, it failed. Therefore, we need to remove the directory pre-pended information to obtain just the filename itself. fleMembers does this for us as shown. "myFile" contains the name actually chosen by the FileDialog.

// use command prompt
myBcrypt.StartInfo.FileName = "cmd.exe";//($%$).
myBcrypt.StartInfo.WorkingDirectory = @"C:/Documents and Settings/david/My Documents/Visual Studio 2005/Projects/bcrypt";
myBcrypt.StartInfo.ErrorDialog = true;

// /c switch sends a command

myBcrypt.StartInfo.Arguments = "/c bcrypt.exe " + myFile;//.bfe";


myBcrypt.StartInfo.WorkingDirectory has to be set with care. bcrypt.exe requires that "zlib.dll" exist in the same directory as the executable, and I happened to have placed them both in the directory you see above. You, of course, can place them anywhere you like so long as you change this entry!


We've got to stop, for a moment, and smell the roses. The "cmd.exe" executable usually opens a window which is the old Command Prompt (or DOS Window). One can type in it, and programs executing usually print to it. We need to

1. not open the window if possible,
2. not type in it, but have the windows application act as if its typing into it, and
3. not have any output written to it, i.e., if necessary, have the output redirected in some way to the windows application.

I started, as an ignorant beginner, with the assumption that I could "stack" the things to be typed into the cmd.exe window, two exactly equal versions of the password, onto the command stack passed to bcrypt.exe. I was wrong and the following failed:

/* myBcrypt.StartInfo.Arguments = myBcrypt.StartInfo.Arguments + "\r" + "somepassword" +
"\r" + "somepasswor";
\r\n attempt at loading the command line stack
\r failed. window flashed by died, no encryption
if failed.*/

It turns out to be more complicated than I thought. Instead, one has to redirect I/O intelligently, and you will see in the next few lines how that was done.

// don't exec with shellexecute api
myBcrypt.StartInfo.UseShellExecute = false;

// redirect stdout to this program
myBcrypt.StartInfo.RedirectStandardOutput = false;//failed true & false

// don't open a cmd prompt window
myBcrypt.StartInfo.CreateNoWindow = false;
myBcrypt.StartInfo.RedirectStandardInput = true;
myBcrypt.StartInfo.RedirectStandardOutput = true;

So, what we've done is to redirect input and output (ignoring errors now).

myBcrypt.Start();

Having started the cms.exe file, we create a StreamWriter from the redirected input and write the result of the PasswordDialog (above) twice. This is the password. We did it.


StreamWriter sw = myBcrypt.StandardInput;
StreamReader sr = myBcrypt.StandardOutput;
sw.WriteLine(passForm.getPass());
sw.WriteLine(passForm.getPass());
myBcrypt.CloseMainWindow();//this may not be necessary
myBcrypt.Close();
}
}
else {
MessageBox.Show("Your password does not pass the sniff test!");
}
}
string myFile;
String regex_psswd = @"(?x)^(?=.* ( \d \p{P} \p{S} )).{8,}";
}
}

The regex_passwd above was stolen from a good web page: Regular Expressions which should be referenced for further information.


What have we done? We've 1) used the password dialog from another program, 2) caused a command line program to function under Windows as a Windows application, and 3) made it possible to input to this (in essence DOS program) data obtained from the Windows application!


One note in ending. The bcrypt module actually uses passphrases, not passwords. In essence, the idea is to use a phrase, presumably one which is simple, instead of a single expression. Therefore one should play with the regex_psswd string to check that there is at least one blank, and to lower the requirements about special characters, upper case characters, etc..







Google