MySQLMove – An Easy To Use Tool To Move MySQL Database Objects and Data

Recently, I was asked to work on a project using a MySQL backend after many years of not having worked with the product. I was amazed when I saw that some of the more common tools to work with MySQL, such as MySQL Workbench or Toad, had still not developed an easy way to move objects and/or data between mySQL databases such as we have become accustomed to in SQL Server Management Studio.  Obviously, this greatly complicated my work and caused me to have to work with data in a production environment more often, which obviously I wasn’t comfortable with.

So like most developers, my brain began to think about how to solve this problem. You could of course, go through each object, get the CREATE script, put it in a giant file, and run it that way. That would be time consuming, bulky and difficult to maintain should there be changes to the database objects. And of course, this did nothing for the issue of data migration.

I looked at other products. MySQLDump, a free tool is fine. Of course, it was more complicated then I would have liked. I just want to move the objects and data and not have a high learning curve of a new product. Just get it done already. Others were available that you had to pay for. Being the cheap bastard that I am, that option didn’t appeal to me either.

So I wrote MySQLMove. This started out as a quick and dirty option to get objects and data moved to another database on another server and gradually moved to including things like a report, the option to only migrate objects, and actually put a user interface on top instead of just running a script. The script was fine for me but it may not be for other developers.

Let’s go into some things you need to know or generally be aware of.

First, some MySQL developers might wonder why I did not use INFILE to import data. The reason is for many such developers, they are coding against a shared hosting environment and often the administrators in such environment have disabled this option. Even using the LOCAL keyword presented problems relating to security. However, in future releases (but see below) I am planning on a interface modification that will allow the end user to indicate that INFILE is available for use and it will operate accordingly.

UPDATE:

The engine now uses INFILE and LOCAL keywords. It is also now lightening fast!

Please make sure you have created the database on the destination server. I know that comes from the “duh” department but you would be surprised…. If you are asking yourself the reason why I don’t do it for you, it is because I drop each object on the destination individually as it is being imported. But more importantly, often each database has a specific username and password designated for access. An idea submitted for future versions (but see below) is that we collect all databases under a given username and password and allow multiple databases to be migrated at one time.  That day is not here yet but it intrigues me.

Another “duh” is it is important to make sure the destination database doesn’t have any users writing changes.

Next…. it is important that if you are importing from or to a Linux based environment, that you are absolutely certain of the case of your database, its objects and server name. Windows is much more forgiving then Linux is in this regard. If you are importing from Linux, be prepared for windows to make all objects lower case, regardless of how you created them in Linux based servers. I have also seen some versions of MySQL run on Windows that were also sticklers for such. My best advice to you is to make all objects lower case. Both Linux and Windows based MySQL servers can handle such and if you are often moving between the two systems you will save yourself a lot of trouble.

Next, you will see an option in a checkbox to only import MySQL objects.

image

If you have the time and the data available to you in text or csv format, I suggest you check this. Why? While this engine can and will move data, it takes longer then a manual import would. The way it is built is all of your insert statements for the data are collected as one statement and inserted collectively. It was about 20 percent faster then inserting a row at a time and also if it should bomb, I can rollback the transaction so that you are not left with a table with partial data. That said, if you are one of those folks who build 300+ column tables, (by the way who hurt you as a child to do that to yourself? Smile jk) it is going to take awhile. But rest assured, it will get there. This was tested against a table with 80000 rows and 30 columns. So it is pretty robust.

UPDATE:

As mentioned above I now use INFILE and LOCAL keyword. The above text is no longer a concern.

Next, it is important you let the code finish. Check that, it is imperative. If you are impatient, switch to decaf and try some breathing exercises.

Finally, MySQLMove will attempt to export database objects as follows: tables, stored procedures, functions and triggers. Not every single one of all those objects can be migrated using this tool. One issue that has commonly arisen is when the code uses a PREPARE statement along with a string for use as the command. Future versions (but see below) will probably rectify this. Should something not be exportable to the destination, at the end of the process a report will appear showing what objects weren’t able to be moved. In my testing, it is a rare occurrence. Also with triggers, remember the “defined user” is copied straight from the trigger to the destination. You will need to make sure that user exists on the destination database as well. Oh and by the way, triggers are migrated last. Otherwise each insert might cause that trigger to fire. And yeah that would not be fun.

Finally, I would love to continue developing this tool. There are so many things I could and would love to do with it. Better reports, table optimization, code optimization, object selection etc. Unfortunately that costs me time, which in translation for those that live under a rock, this means it costs me money. If you find the tool useful and would like to continue to see it developed, please don’t be a cheap bastard like me Smile and make a donation here using my email address – kellyjmartens@hotmail.com .

 

paypal-app

I would be extremely grateful. I know the honor system is putting yourself out there isn’t real effective but it gives those of you who would like to say thank you and keep going with this a chance to do so.

So on to the download…. You have two options….

One if you are a person who already has the MySql.Data dll already installed on your system (make sure it is version 6.9.9.0 and you have at least .NET runtime v4.0.30319) you can download just the bin folder. If you don’t or aren’t sure, get the install package zip file called “MySqlMoveSetup”. If you need the .NET Framework you can download it here.

Both the bin folder zip file and the installer zip file are located here on my OneDrive.

Please do send me an email at kellyjmartens@hotmail.com with any bug reports, suggestions or praise. All are accepted. Smile 

 

Have a great day!

, , , ,

2 Comments

Email Excel Spreadsheet as Email Body Issues

Hello all. I had a production manager wanting an excel spreadsheet mailed as the body of the email. As some of you know the code generated by excel to produce the email is pretty crazy. But as a result, it showed up fine in Outlook and Android but it did not show the gridlines on the spreadsheet. So this code is based on the excellent work by Ron DeBruin over at http://www.rondebruin.nl/win/s1/outlook/bmail3.htm . I did a replacement for the HTML Range in this manner and the grid lines did appear. And the manager was happy.

Sub Mail_Selection_Range_Outlook_Body()
‘For Tips see: http://www.rondebruin.nl/win/winmail/Outlook/tips.htm
‘Don’t forget to copy the function RangetoHTML in the module.
‘Working in Excel 2000-2016
    Dim rng As Range
    Dim OutApp As Object
    Dim OutMail As Object
‘MsgBox Cells(5, 9).Value
    Set rng = Nothing
    On Error Resume Next
    ‘Only the visible cells in the selection
    Set rng = Selection.SpecialCells(xlCellTypeVisible)
    ‘You can also use a fixed range if you want
    ‘Set rng = Sheets(“YourSheet”).Range(“D4:D12”).SpecialCells(xlCellTypeVisible)
    On Error GoTo 0

    If rng Is Nothing Then
        MsgBox “The selection is not a range or the sheet is protected” & _
               vbNewLine & “please correct and try again.”, vbOKOnly
        Exit Sub
    End If

    With Application
        .EnableEvents = False
        .ScreenUpdating = False
    End With

    Set OutApp = CreateObject(“Outlook.Application”)
    Set OutMail = OutApp.CreateItem(0)

    On Error Resume Next
    With OutMail
        .BodyFormat = olFormatHTML
        .To = “you@you.com”       
           
               
       
         .CC = “”
        .BCC = “”
        .Subject = “Testing Purchase Order Email To Steve”
        .HTMLBody = RangetoHTML(rng)
        Replace .HTMLBody, “border-left:none”, “border-left:solid;border-width: 1px;border-color:black”
        Replace .HTMLBody, “border-right:none”, “border-right:solid;border-width: 1px;border-color:black”
        Replace .HTMLBody, “border-bottom:none”, “border-bottom:solid;border-width: 1px;border-color:black”
        Replace .HTMLBody, “border-top:none”, “border-bottom:solid;border-width: 1px;border-color:black”
        .Send
         ‘or use .Display
    End With
    On Error GoTo 0

    With Application
        .EnableEvents = True
        .ScreenUpdating = True
    End With

    Set OutMail = Nothing
    Set OutApp = Nothing
End Sub

, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,

Leave a comment

Class to Simplify and Minimize Code for Stored Procedures and TSQL

First of all if you are using TSQL in your code you really need to get in a another line of work. It isn’t scalable, difficult to maintain and is generally a bad practice. But I know some of you still do it so I did include it. This class will allow you to in a few lines of code do your select, update, insert or delete statements in a very few lines of code. All that is required of the developer is to list the values in order (if you are using stored procedures) that are required. Also included is how to declare a new instance of a sqlparametercollection – which you aren’t suppose to be able to do. I ended up not needing it but included it just in case someone needs to do that someday. Also if you are using a strongly typed dataset there is a method included of how to do that. After the code is example of usage. Have a great day!

using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;

using System.IO;

using System.Data.SqlClient;

public class clsData
{

    public SqlConnection sqlconn = new SqlConnection();
    public string Error_Message;
    public List<SqlParameter> ParamList = new List<SqlParameter>();
    public ArrayList ParamValues = new ArrayList();

    public int SQLExecuteNonQueryValue;
    public clsData()
   

    public enum SQLAction
    {
        SelectAction,
        UpdateInsertDeleteAction
    }

    public virtual DataTable DataAction(clsData.SQLAction Action, DataTable dt, string cmdtext, string ParamValues = “”)
    {
        SQLExecuteNonQueryValue = -1;
        SqlCommand cmd = new SqlCommand();
        cmd.CommandText = cmdtext;
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Connection = sqlconn;
        this.GetParameterList(cmdtext);
        if (!string.IsNullOrEmpty(Error_Message)) {
            return null;
        }
        if (!string.IsNullOrEmpty(ParamValues)) {
            this.ParseSQLParameterValues(ParamValues);
            for (i = 0; i <= this.ParamList.Count – 1; i++) {
                cmd.Parameters.AddWithValue(this.ParamList[i].ToString(), this.ParamValues[i].ToString());
            }
        }
        //Debug.WriteLine(cmd.CommandText)
        try {
            cmd.Connection.Open();
            switch (Action) {
                case SQLAction.SelectAction:
                    dt.Load(cmd.ExecuteReader());
                    break;
                case SQLAction.UpdateInsertDeleteAction:
                    //Check this value to make sure everything went ok
                    SQLExecuteNonQueryValue = cmd.ExecuteNonQuery();
                    cmd.Connection.Close();
                    return null;
            }
            cmd.Connection.Close();

        } catch (Exception ex) {
            Error_Message = “There was a problem with ” + cmdtext + “. “;
            return null;
        }

        //removing duplicate table from dataset
        for (i = 0; i <= ds_Copy.Tables.Count – 1; i++) {
            if (ds_Copy.Tables(i).TableName == dt.TableName) {
                ds_Copy.Tables(i).Clear();
                ds_Copy.Tables(i).Columns.Clear();
            }
        }

        //placing datatable in the dataset
        ds_Copy.Merge(dt, false, MissingSchemaAction.Add);
        Error_Message = “”;
        return dt;
    }

    public DataTable DataActionTSQL(clsData.SQLAction Action, DataTable dt, string sqlstring)
    {
        SQLExecuteNonQueryValue = -1;
        SqlCommand cmd = new SqlCommand();
        cmd.CommandText = sqlstring;
        cmd.Connection = sqlconn;
        try {
            cmd.Connection.Open();
            switch (Action) {
                case SQLAction.SelectAction:
                    dt.Load(cmd.ExecuteReader());
                    break;
                case SQLAction.UpdateInsertDeleteAction:
                    //Check this value to make sure everything went ok
                    SQLExecuteNonQueryValue = cmd.ExecuteNonQuery();
                    cmd.Connection.Close();
                    return null;
            }
            cmd.Connection.Close();

        } catch (Exception ex) {
            Error_Message = “There was a problem with ” + sqlstring + “. “;
            return null;
        }
        //removing duplicate table from dataset
        for (i = 0; i <= ds_Copy.Tables.Count – 1; i++) {
            if (ds_Copy.Tables(i).TableName == dt.TableName) {
                ds_Copy.Tables(i).Clear();
                ds_Copy.Tables(i).Columns.Clear();
            }
        }
        //placing datatable in the dataset
        ds_Copy.Merge(dt, false, MissingSchemaAction.Add);
        Error_Message = “”;
        return dt;
    }

    private List<SqlParameter> GetParameterList(string ProcName)
    {
        //Get the parameters for the selected stored procedure
        List<SqlParameter> inputParamList = new List<SqlParameter>();
        ParamList.Clear();

        using (SqlConnection cn = new SqlConnection()) {
            DispatcherTool.My.MySettings Settings = new DispatcherTool.My.MySettings();
            cn.ConnectionString = Settings.SRAConnectionString;
            SqlCommand myCommand = new SqlCommand();
            myCommand.Connection = cn;
            myCommand.CommandText = ProcName;
            myCommand.CommandType = System.Data.CommandType.StoredProcedure;
            try {
                cn.Open();
                SqlCommandBuilder.DeriveParameters(myCommand);
                cn.Close();
            } catch (Exception ex) {
                Error_Message = “There was a problem with the connection to the database.”;
                return null;
            }

            //Dim sqlparams As SqlParameterCollection = DirectCast(GetType(SqlParameterCollection).GetConstructor(BindingFlags.NonPublic Or BindingFlags.Instance, Nothing, Type.EmptyTypes, Nothing).Invoke(Nothing), SqlParameterCollection)

            foreach (SqlParameter param in myCommand.Parameters) {
                if (param.Direction == System.Data.ParameterDirection.Input || param.Direction == System.Data.ParameterDirection.InputOutput) {
                    //sqlparams.Add(param.ParameterName & ” – ” & param.SqlDbType.ToString())
                    //Debug.WriteLine(param.ParameterName & ” – ” & param.SqlDbType.ToString())
                    inputParamList.Add(param);
                    //Else
                    // sqlparams.Add(param.ParameterName & ” – ” & param.SqlDbType)
                    //Debug.WriteLine(param.ParameterName & ” -2 ” & param.SqlDbType)
                }
            }
        }
        this.ParamList = inputParamList;
        Error_Message = “”;
        return this.ParamList;
    }

    public void ParseSQLParameterValues(string ValueString)
    {
        ParamValues.Clear();
        string[] parts = ValueString.Split(new char[] { ‘,’ });
        string part = null;
        foreach (string part_loopVariable in parts) {
            part = part_loopVariable;
            ParamValues.Add(part);
        }
    }

    //’Public Shared Function ConvertToTypedDataTable(Of T As {Data.DataTable, New})(ByVal dtBase As Data.DataTable) As T
    //’    Dim dtTyped As New T
    //’    dtTyped.Merge(dtBase)
    //’    Return dtTyped
    //’End Function

}

And then it’s use…..

private void Button1_Click(System.Object sender, System.EventArgs e)
{
    Strongly_Typed_DataSet.usp_Your_Stored_Procedure dt = new Strongly_Typed_DataSet.usp_Your_Stored_Procedure();

    DataGridView1.DataSource = cn.DataAction(clsData.SQLAction.SelectAction, dt, ds.usp_Get_PrinterName_for_PickList_Printing.ToString, “Tubing”);

    //DataGridView1.DataSource = cn.DataActionTSQL(clsData.SQLAction.SelectAction, dt, “SELECT *FROM Your_Table”)

}


Join me on Facebook

, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,

Leave a comment

WCF and Email Attachments

First off I want to apologize for being away so long. It has been a crazy ride to say the least.

So a colleague of mine ran into an issue with WCF and emailing attachments and asked for help. In this block of code below it would always fail at:

Attachment attachment = new Attachment(fileAttachment.ContentStream, fileAttachment.Name);”     The error is : “Value cannot be null.
Parameter name: stream”

 

 

 
EmailSendInput emailSendInput = new EmailSendInput
                {
                    Attachments = new List<Attachment>(),
                    Body = model.Body,
                    To = new List<string> { model.EmailTo },
                    From = model.EmailFrom,
                    Subject = model.EmailSubject
                };

                if (model.Files != null)
                {
                    foreach (var currAttachment in model.Files)
                    {
                        if (currAttachment != null && currAttachment.ContentLength > 0)
                        {
                            // the filename needs to be nice looking
                            string fileName =
                                currAttachment.FileName.Substring(
                                    currAttachment.FileName.LastIndexOf(@”\”, System.StringComparison.Ordinal) + 1,
                                    currAttachment.FileName.Length
                                    – currAttachment.FileName.LastIndexOf(@”\”, System.StringComparison.Ordinal) – 1);

                            var attachment = new Attachment(currAttachment.InputStream, fileName);
                            emailSendInput.Attachments.Add(attachment);
                        }
                    }
                }

                B2BMortgageDataServiceAgent b2BMortgageDataServiceAgent = new B2BMortgageDataServiceAgent();
                EmailSendResponse emailSendResponse = b2BMortgageDataServiceAgent.SendEmail(emailSendInput);
                if (!emailSendResponse.Success)
                {
                    throw new Exception(emailSendResponse.Message);
                }
            }

public EmailSendResponse SendEmail(EmailSendInput input)
        {
            EmailSendResponse retVal = new EmailSendResponse();
            try
            {
               
                string smtpServer = “”
                string smtpPort = “”

                using (var client = new SmtpClient(smtpServer, Convert.ToInt32(smtpPort)))
                {
                    var mail = new MailMessage
                    {
                        From = new MailAddress(input.From),
                        Subject = input.Subject,
                        Body = input.Body
                    };
                    input.To.ForEach(t => mail.To.Add(t));

                    if (input.Attachments != null && input.Attachments.Count > 0)
                    {
                        foreach (var fileAttachment in input.Attachments)
                        {
                            //Code Crashes here
                            Attachment attachment = new Attachment(fileAttachment.ContentStream, fileAttachment.Name);
                            mail.Attachments.Add(attachment);
                        }
                    }

                    client.Send(mail);
                }

                retVal.Success = true;
            }
            catch (Exception exception)
            {
                retVal.Success = false;
                LogUtil.LogException(exception);

            
                retVal.Message = exception.ToString();
            }

            return retVal;
        }

and then the contract:

[DataContract]
    public class EmailSendInput
    {
        [DataMember]
        public string From { get; set; }

        [DataMember]
        public List<string> To { get; set; }

        [DataMember]
        public string Subject { get; set; }

        [DataMember]
        public string Body { get; set; }

        [DataMember]
        public List<Attachment> Attachments { get; set; }

    }

Implemented as:

public EmailSendResponse SendEmail(EmailSendInput input)
         {
             try
             {
                 return this.dataAgent.SendEmail(input);
             }
             catch (Exception e)
             {
                 this.logger.LogException(e, 2);
                 throw new FaultException(“An error occured in SendEmail. Error details : ” + this.BuildMessage(e));
             } 
         }

and the Email response:

[DataContract]
    public class EmailSendResponse
    {
        [DataMember]
        public bool Success { get; set; }

        [DataMember]
        public string Message { get; set; }
    }

So now we have the problem. I basically had to recreate his datamember for attachment in the contract EmailSendInput to a

public List<EmailEncodedAttachment> Attachments { get; set; }

and added a new contract called EmailEncodedAttachment and process how he was handling the attachment differently. I’ve also included the MVC controller calls in case it might help you as well.

 

SOLUTION:

[DataContract]
    public class EmailSendInput
    {
        [DataMember]
        public string From { get; set; }

        [DataMember]
        public List<string> To { get; set; }

        [DataMember]
        public string Subject { get; set; }

        [DataMember]
        public string Body { get; set; }

        [DataMember]
        public List<EmailEncodedAttachment> Attachments { get; set; }

    }

 

[DataContract]
    public class EmailEncodedAttachment
    {
        [DataMember]
        public string Base64Attachment;

        [DataMember]
        public string Name;

        /// <summary>
        /// One of the System.Net.Mime.MediaTypeNames
        /// </summary>
        [DataMember]
        public string MediaType;
    }
}
                retVal.Message = exception.ToString();
            }

            return retVal;
        }

 

public EmailSendResponse SendEmail(EmailSendInput input)
        {
            EmailSendResponse retVal = new EmailSendResponse();
            try
            {
               
                string smtpServer = ConfigurationManager.AppSettings[“SmtpServer”] ?? “url”;
                string smtpPort = ConfigurationManager.AppSettings[“SmtpPort”] ?? “portnum”;

                using (var client = new SmtpClient(smtpServer, Convert.ToInt32(smtpPort)))
                {
                    var mail = new MailMessage
                    {
                        From = new MailAddress(input.From),
                        Subject = input.Subject,
                        Body = input.Body
                    };
                    input.To.ForEach(t => mail.To.Add(t));

                    if (input.Attachments != null && input.Attachments.Count > 0)
                    {
                        foreach (var fileAttachment in input.Attachments)
                        {
                            mail.Attachments.Add(this.CreateAttachment(fileAttachment));
                        }
                    }

                    client.Send(mail);
                }

                retVal.Success = true;
            }
            catch (Exception exception)
            {
                retVal.Success = false;
                LogUtil.LogException(exception);
             
                retVal.Message = exception.ToString();
            }

            return retVal;
        }

 

The MVC controller action calls the service like so:

EmailSendInput emailSendInput = new EmailSendInput
                {
                    Attachments = new List<EmailEncodedAttachment>(),
                    Body = model.Body,
                    To = new List<string> { model.EmailTo },
                    From = model.EmailFrom,
                    Subject = model.EmailSubject
                };

                if (model.Files != null)
                {
                    foreach (var file in model.Files)
                    {
                        if (file != null && file.ContentLength > 0)
                        {
                            // the filename needs to be nice looking
                            string prettyFileName =
                                file.FileName.Substring(
                                    file.FileName.LastIndexOf(@”\”, System.StringComparison.Ordinal) + 1,
                                    file.FileName.Length
                                    – file.FileName.LastIndexOf(@”\”, System.StringComparison.Ordinal) – 1);

                            var attachment = this.CreateAttachment(prettyFileName, file.InputStream);
                            emailSendInput.Attachments.Add(attachment);
                        }
                    }
                }

                B2BMortgageDataServiceAgent b2BMortgageDataServiceAgent = new B2BMortgageDataServiceAgent();
                EmailSendResponse emailSendResponse = b2BMortgageDataServiceAgent.SendEmail(emailSendInput);
                if (!emailSendResponse.Success)
                {
                    throw new Exception(emailSendResponse.Message);
                }

 

and finally the encoding method which makes this possible:

private EmailEncodedAttachment CreateAttachment(string fileName, Stream stream)
        {
            EmailEncodedAttachment att = new EmailEncodedAttachment
            {
                Name = fileName,
                MediaType = System.Net.Mime.MediaTypeNames.Text.Plain
            };

            byte[] buffer = new byte[stream.Length];
            stream.Read(buffer, 0, (int)stream.Length);
            att.Base64Attachment = Convert.ToBase64String(buffer);

            return att;
        }

 

There you have it folks. I hope you have a great Sunday!

, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,

Leave a comment

Capture an Image of the Desktop, Specific Screen or Portion of a Screen with C#

So today is my birthday. It has been a wild ride this last 46 years. Lets hope that things continue to get better.

So this is my entire class for capturing screens and desktop appearance to an image file or to print them. I use this class quite often in my error management, saving or emailing the output should errors occur so I can get a good idea of what was going on at the time an error occurs. Why? Because often end users or business analysts, though they are trying their best, sometimes can’t describe in detail how to reproduce what occurred. I suggest using this in conjunction with a logging class as well so that you can replicate the steps needed. The image file is also very handy in reconstructing what a user was or was not doing which, as a coder, can literally save your ass on occasion. So here it is. It is well commented and pretty straight forward.

using System.Windows.Forms;
using System;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Drawing.Imaging;

public class clsScreenCapture
{
    private System.Drawing.Printing.PrintDocument Pd = new System.Drawing.Printing.PrintDocument();
    private PictureBox PicForm = new PictureBox();

    /// Creates an Image object containing a screen shot of the entire desktop
    public Image CaptureScreen()
    {
        return CaptureWindow(User32.GetDesktopWindow());
    } //CaptureScreen
    /// Creates an Image object containing a screen shot of a specific window
    public Image CaptureWindow(IntPtr handle)
    {
        int SRCCOPY = 0xCC0020;
        // get te hDC of the target window
        IntPtr hdcSrc = User32.GetWindowDC(handle);
        // get the size
        User32.RECT windowRect = new User32.RECT();
        User32.GetWindowRect(handle, ref windowRect);
        int width = windowRect.right – windowRect.left;
        int height = windowRect.bottom – windowRect.top;
        // create a device context we can copy to
        IntPtr hdcDest = GDI32.CreateCompatibleDC(hdcSrc);
        // create a bitmap we can copy it to,
        // using GetDeviceCaps to get the width/height
        IntPtr hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc, width, height);
        // select the bitmap object
        IntPtr hOld = GDI32.SelectObject(hdcDest, hBitmap);
        // bitblt over
        GDI32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, SRCCOPY);
        // restore selection
        GDI32.SelectObject(hdcDest, hOld);
        // clean up
        GDI32.DeleteDC(hdcDest);
        User32.ReleaseDC(handle, hdcSrc);

        // get a .NET image object for it
        Image img = Image.FromHbitmap(hBitmap);
        // free up the Bitmap object
        GDI32.DeleteObject(hBitmap);

        return img;
    } //CaptureWindow
    /// Captures a screen shot of a specific window, and saves it to a file
    public void CaptureWindowToFile(IntPtr handle, string filename, ImageFormat format)
    {
        Image img = CaptureWindow(handle);
        img.Save(filename, format);
    } //CaptureWindowToFile
    /// Captures a screen shot of a specific window, and saves it to a file
    public void CaptureWindowToPrinter(Form mfForm, ImageFormat format)
    {
        // Dim img As Image = CaptureScreen()

        Image img = CaptureWindow(mfForm.Handle);
        try
        {
            PicForm.Image = img;
            if (MessageBox.Show(“Press Yes to Print or No to Copy to your Clipboard (‘No’ will allow pasting into an email or Word document etc).”, “Print or Copy to Clipboard?”, MessageBoxButtons.YesNo) == DialogResult.Yes)
            {
                Pd.Print();
            }
            else
            {
                Clipboard.SetDataObject(img, true);
            }
        }
        catch (Exception ex)
        {
            string a = “vfdgsfg”;
        }
    } //CaptureWindowToPrinter
    private void pd_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
    {
        //—————————————————————
        // this procedure handles events raised by the printer object pd
        //—————————————————————
        e.Graphics.DrawImageUnscaled(PicForm.Image, 0, 0); //send image to printer – upper left position

        e.HasMorePages = false; //this is the last page to print

    }

    /// Captures a screen shot of the entire desktop, and saves it to a file
    public void CaptureScreenToFile(string filename, ImageFormat format)
    {
        Image img = CaptureScreen();
        img.Save(filename, format);
    } //CaptureScreenToFile
    public Bitmap CaptureDeskTopRectangle(Rectangle CapRect, int CapRectWidth, int CapRectHeight)
    {
        /// Returns BitMap of the region of the desktop, similar to CaptureWindow, but can be used to
        /// create a snapshot of the desktop when no handle is present, by passing in a rectangle
        /// Grabs snapshot of entire desktop, then crops it using the passed in rectangle’s coordinates
        clsScreenCapture SC = new clsScreenCapture();
        Bitmap bmpImage = new Bitmap(SC.CaptureScreen());
        Bitmap bmpCrop = new Bitmap(CapRectWidth, CapRectHeight, bmpImage.PixelFormat);
        Rectangle recCrop = new Rectangle(CapRect.X, CapRect.Y, CapRectWidth, CapRectHeight);
        Graphics gphCrop = Graphics.FromImage(bmpCrop);
        Rectangle recDest = new Rectangle(0, 0, CapRectWidth, CapRectHeight);
        gphCrop.DrawImage(bmpImage, recDest, recCrop.X, recCrop.Y, recCrop.Width, recCrop.Height, GraphicsUnit.Pixel);
        return bmpCrop;
    }
    /// Helper class containing Gdi32 API functions
    private class GDI32
    {
        public int SRCCOPY = 0xCC0020;
        // BitBlt dwRop parameter
        [System.Runtime.InteropServices.DllImport(“gdi32.dll”, EntryPoint=”BitBlt”, ExactSpelling=true, CharSet=System.Runtime.InteropServices.CharSet.Ansi, SetLastError=true)]
        public static extern Int32 BitBlt(IntPtr hDestDC, Int32 x, Int32 y, Int32 nWidth, Int32 nHeight, IntPtr hSrcDC, Int32 xSrc, Int32 ySrc, Int32 dwRop);

        [System.Runtime.InteropServices.DllImport(“gdi32.dll”, EntryPoint=”CreateCompatibleBitmap”, ExactSpelling=true, CharSet=System.Runtime.InteropServices.CharSet.Ansi, SetLastError=true)]
        public static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, Int32 nWidth, Int32 nHeight);

        [System.Runtime.InteropServices.DllImport(“gdi32.dll”, EntryPoint=”CreateCompatibleDC”, ExactSpelling=true, CharSet=System.Runtime.InteropServices.CharSet.Ansi, SetLastError=true)]
        public static extern IntPtr CreateCompatibleDC(IntPtr hdc);

        [System.Runtime.InteropServices.DllImport(“gdi32.dll”, EntryPoint=”DeleteDC”, ExactSpelling=true, CharSet=System.Runtime.InteropServices.CharSet.Ansi, SetLastError=true)]
        public static extern Int32 DeleteDC(IntPtr hdc);

        [System.Runtime.InteropServices.DllImport(“gdi32.dll”, EntryPoint=”DeleteObject”, ExactSpelling=true, CharSet=System.Runtime.InteropServices.CharSet.Ansi, SetLastError=true)]
        public static extern Int32 DeleteObject(IntPtr hObject);

        [System.Runtime.InteropServices.DllImport(“gdi32.dll”, EntryPoint=”SelectObject”, ExactSpelling=true, CharSet=System.Runtime.InteropServices.CharSet.Ansi, SetLastError=true)]
        public static extern IntPtr SelectObject(IntPtr hdc, IntPtr hObject);
    } //GDI32
    /// Helper class containing User32 API functions
    public class User32
    {
        [StructLayout(LayoutKind.Sequential)]
        public struct RECT
        {
            public int left;
            public int top;
            public int right;
            public int bottom;
        } //RECT

        [System.Runtime.InteropServices.DllImport(“user32.dll”, EntryPoint=”GetDesktopWindow”, ExactSpelling=true, CharSet=System.Runtime.InteropServices.CharSet.Ansi, SetLastError=true)]
        public static extern IntPtr GetDesktopWindow();

        [System.Runtime.InteropServices.DllImport(“user32.dll”, EntryPoint=”GetWindowDC”, ExactSpelling=true, CharSet=System.Runtime.InteropServices.CharSet.Ansi, SetLastError=true)]
        public static extern IntPtr GetWindowDC(IntPtr hwnd);

        [System.Runtime.InteropServices.DllImport(“user32.dll”, EntryPoint=”ReleaseDC”, ExactSpelling=true, CharSet=System.Runtime.InteropServices.CharSet.Ansi, SetLastError=true)]
        public static extern Int32 ReleaseDC(IntPtr hwnd, IntPtr hdc);

        [System.Runtime.InteropServices.DllImport(“user32.dll”, EntryPoint=”GetWindowRect”, ExactSpelling=true, CharSet=System.Runtime.InteropServices.CharSet.Ansi, SetLastError=true)]
        public static extern Int32 GetWindowRect(IntPtr hwnd, ref RECT lpRect);

    } //User32

    public clsScreenCapture()
    {
        SubscribeToEvents();
    }

// event handler wireups:
    private bool EventsSubscribed = false;
    private void SubscribeToEvents()
    {
        if (EventsSubscribed)
            return;
        else
            EventsSubscribed = true;

        Pd.PrintPage += pd_PrintPage;
    }

}


Join me on Facebook

, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,

Leave a comment

Encryption and Decryption of strings with C#

Well I am checking out the Beale Street Historic District for the first time in Memphis, TN tonight. I have heard a lot about it since my arrival here so am excited to get to go. I think it will be fun.

Of course this would come up. I had written this previously in vb.net and I had the opportunity to use it again today. Of course in doing so, I discovered a bad coding practice violation I had committed. I had failed to return a value in my function’s Catch block of my code. C# doesn’t let you off the hook so easily and will bug you till you fix it. As noted previously, topic is encryption and decryption of strings. It is straightforward but you might find it useful. Simply pass in the string you want to encrypt/decrypt and the key you want to use.

using System;
using System.IO;
using System.Text;
using System.Security.Cryptography;
public class Crypto
{
    private static TripleDESCryptoServiceProvider DES = new TripleDESCryptoServiceProvider();
    private static MD5CryptoServiceProvider MD5 = new MD5CryptoServiceProvider();
    public static byte[] MD5Hash(string value)
    {
        return MD5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(value));
    }
    public static string Encrypt(string stringToEncrypt, string key)
    {
        DES.Key = Crypto.MD5Hash(key);
        DES.Mode = CipherMode.ECB;
        byte[] Buffer = ASCIIEncoding.ASCII.GetBytes(stringToEncrypt);
        return Convert.ToBase64String(DES.CreateEncryptor().TransformFinalBlock(Buffer, 0, Buffer.Length));
    }
    public static string Decrypt(string encryptedString, string key)
    {
        try
        {
            DES.Key = Crypto.MD5Hash(key);
            DES.Mode = CipherMode.ECB;
            byte[] Buffer = Convert.FromBase64String(encryptedString);
            return ASCIIEncoding.ASCII.GetString(DES.CreateDecryptor().TransformFinalBlock(Buffer, 0, Buffer.Length));
        }
        catch (Exception ex)
        {
            MessageBox.Show(“Invalid Key”, “Decryption Failed”, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
        }
// Inserted the following ‘return’ since all code paths must return a value in C#:
        return null;
    }
}

And now it’s usage…..

public class Form1
{
    private void Button1_Click(object sender, System.EventArgs e)
    {
        string key = Microsoft.VisualBasic.Interaction.InputBox(“Enter a Key:”, “”, “”, -1, -1);
        Label1.Text = Crypto.Encrypt(TextBox1.Text, key);
        TextBox1.Clear();
    }
    private void Button2_Click(object sender, System.EventArgs e)
    {
        string key = Microsoft.VisualBasic.Interaction.InputBox(“Enter a Key:”, “”, “”, -1, -1);
        TextBox1.Text = Crypto.Decrypt(Label1.Text, key);
    }

    }


Join me on Facebook

, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,

3 Comments