RATCHET

RATCHET Labs

04/14/2011

Running Command Line Bat Files From a Web Page ASP.NET C#

We needed the ability to run some batch processes without having to remote to the server.   I put together a small  ASP.NET app that allowed us to do this.  Found some code for running standard command line application through .NET and modified/extended it to work through a web interface.

Here is the code that does the bulk of the of the work for running the bat files.

public static string ProcessBatFile(string batFile)
{
            string val = "";

            if (!File.Exists(batFile))
            {
                throw new Exception(batFile + " does not exists");
            }

            // Create the ProcessInfo object
            System.Diagnostics.ProcessStartInfo psi =
                    new System.Diagnostics.ProcessStartInfo("cmd.exe");
            psi.UseShellExecute = false;
            psi.RedirectStandardOutput = true;
            psi.RedirectStandardInput = true;
            psi.RedirectStandardError = true;

            // Start the process
            System.Diagnostics.Process proc =
                       System.Diagnostics.Process.Start(psi);

            // Open the batch file for reading
            System.IO.StreamReader strm = proc.StandardError;
            // Attach the output for reading
            System.IO.StreamReader sOut = proc.StandardOutput;

            // Attach the in for writing
            System.IO.StreamWriter sIn = proc.StandardInput;

            // Write each line of the batch file to standard input
            /*while(strm.Peek() != -1)
            {
                sIn.WriteLine(strm.ReadLine());
            }*/
            sIn.WriteLine(batFile);
            strm.Close();

            // Exit CMD.EXE
            string stEchoFmt = "# {0} run successfully. Exiting";

            sIn.WriteLine(String.Format(stEchoFmt, batFile));
            sIn.WriteLine("EXIT");

            // Close the process
            proc.Close();

            // Read the sOut to a string.
            string results = sOut.ReadToEnd().Trim();

            // Close the io Streams;
            sIn.Close();
            sOut.Close();

            val = results;

            return val;
}

I created CMD prompt in CSS to make it look legit. It just displays the captured output from the method above.

This can be extremely unsafe for a server. Your sys admin should question setting something like this up. Please let them know there are steps that can be taken to help make this a safe process such as requiring authentication to access this script and only allow the bat files to run from set directory.

  • Facebook
  • Twitter
  • Digg
  • Print
  • email

02/18/2011

JOIN in on the fun

I am not really sure why I never used this method but I just discovered it the other day.  It is the .NET String.Join() method.    It is clean and saves a few lines of code.  Whenever I needed to  take  a list if items and make a separated string out of it I would usually do something like:

String vals = "";
foreach (string s in list)
{
   if (String.IsNullOrEmpty(vals))
   {
     vals = s;
   }
   else
   {
     vals += "," + s;
   }
}

The String.Join() method makes above happen with one line of code.

string vals = String.Join(",",list.ToArray());

Try it and see how fun it can be.

  • Facebook
  • Twitter
  • Digg
  • Print
  • email

01/20/2011

MVC 3

Starting to write some .NET application using MVC 3 and the Razor engine. It has been a while since I used MVC pattern on web application. I think the last attempt at it was with ColdFusion and FuseBox. There is a learning curve and a different thought process behind it but its not bad.

Besides the unit testing inherently built in to the framework I see some other nice advantages:

- Front end developers will be able to start integrating with data sooner. Once the Model has been mocked up/defined, front end developers will be able to integrate and write more of the data integration code. Saving middle tier back end developers to work on building kick ass data objects using frameworks of there choice.

- Ditching the view state is plus for the most part. Not having to set the “enableviewstate” property and controlling the some of the state yourself gives you a lot more control.

- Developers coming from other frameworks or languages like ruby, Php(Zend), or Groovy should find this familiar but also get to see how nice the .NET framework is and how Visual Studio can be your best friend.

Check it out download a few test apps.

http://www.asp.net/mvc/mvc3

http://haacked.com/archive/2011/01/13/aspnetmvc3-released.aspx

  • Facebook
  • Twitter
  • Digg
  • Print
  • email

12/29/2010

Make your own Elf name generator

We had some fun making the Elf Name generator. If you have not seen it yet check it out at holiday.ratchet.com. Building  the name generator is actually a simple application and the logic could be be reused for more productive(work related) products.

The logic was straight forward

  1. Build a list of all possible combination’s.  For the elf name we  had 900 possible names(30 first and 30 last) and stored them in a SQL database.  Used a SQL query without the join to return all combination’s. This is otherwise known as a cartesian product.   I am sure most of you have seen this effect when you forgot to add a join or have a bad SQL statement
  2. Took the name entered in the text fields and converted each character to an ascii value
  3. Added up all the ascii values
  4. Used the sum from the  ascii values  as the seed for the random function

So if a user entered the same name in they would get the same  “random” elf name returned because the seed would be the same.

In C# here  are some code snippets

//helper method to get ascii sum
public static Int32 GetAsciiSumValue(string val)
{
     Int32 sum = 0;

    if (!string.IsNullOrEmpty(val))
    {
        foreach (char c in val)
        {
            sum += System.Convert.ToInt32(c);
        }
    }

    return sum;
}


public static string GetElfname(string name)
{
    string elfName = "";
    int count = 0;
    int seed = GetAsciiSumValue(name);
    DataSet ds = new DataSet();
	
    //DO LOGIC TO GET DATASET POPULATED WITH LIST AND ERROR CHECKING
		
    count = ds.Tables[0].Rows.Count;
    elfName = ds.Tables[0].Rows[new Random(seed).Next(count - 1)][0].ToString();
	
    return elfName;	
}

There are many variations to this you can do like convert the text entered into all upper or lower case if you wanted to ignore casing for the returned results.

Have fun with what ever name generation you want.

- Chip Sugarsocks

  • Facebook
  • Twitter
  • Digg
  • Print
  • email

12/14/2010

Help prevent spam bots from getting your email addresses

There is no full proof way of preventing companies from harvesting email addresses from websites.  There are few techniques that can be used to help minimize the spam.

There are several JavaScript approaches out there that work well.  They usually consist of breaking apart the address into components so there is no “name@somedomain.com” anywhere in the HTML.

For example:

<SCRIPT LANGUAGE="JavaScript">
var user = 'somename';
var site = 'ratchet.com';
document.write('<a href=\"mailto:' + user + '@' + site + '\">');
document.write(user + '@' + site + '</a>');
</SCRIPT> 

I tried a different approach with ratchet.com. I used a script to dynamically generate an image of any text with some logic to handle emails. There are several parameters that can be set to control , size, font, and colors.

These emails below are dynamically generated jpgs and demonstrates some of the display options. .NET has decent graphics libraries and there are many ways to build the image out.

The images above are generated by a URL with a query string in an img src tag like:

http://SOME_URL/controls/writetextasimage.ashx?text=daffy.twinkle&fontname=times&fontsize=12&forecolor=%230000ff&backcolor=%23ffffff&fontstyle=italic&isemail=true

By having a basic URL structure it makes it easy to integrate with existing website code.

The .NET server side code is basic. I found some code online and added more logic to it. There are many different directions you could go on the server side like web services, WCF, REST API, etc. There are many more options that could be added like output type (png, bmp, jpg, etc).

Bellow is the main guts of the code. There are several helper methods and properties to process the query string data.

public void ProcessRequest(HttpContext context)
        {

            context.Response.ContentType = "image/jpeg";

            // fake bitmap to get needed size
            Bitmap bitmap = new Bitmap(1, 1);

            int width = 0;
            int height = 0;

            // create font object with requested properties
            Font font = new Font(fontName,
                fontSize,
                fontStyle);

            // create the graphics object to measure text size and perform actual rendering
            Graphics graphics = Graphics.FromImage(bitmap);

            // get needed size to render the wanted text
            SizeF size = graphics.MeasureString(text, font);
            width = (int)size.Width;
            height = (int)size.Height;

            // release resources
            graphics.Dispose();
            bitmap.Dispose();

            // create the actual bitmap with final size
            bitmap = new Bitmap(width, height);

            // render text
            graphics = Graphics.FromImage(bitmap);
            graphics.Clear(backColor);
            graphics.TextRenderingHint = TextRenderingHint.AntiAlias;
            graphics.DrawString(text,
                font,
                new SolidBrush(foreColor),
                0,
                0);
            graphics.Flush();

            // create codec object for jpg format
            ImageCodecInfo jpegCodec = null;
            foreach (ImageCodecInfo codec in ImageCodecInfo.GetImageEncoders())
                if (codec.MimeType == "image/jpeg")
                {
                    jpegCodec = codec;
                    break;
                }

            // set codec quality
            EncoderParameters parameters = new EncoderParameters(1);
            parameters.Param[0] = new EncoderParameter(Encoder.Quality, (long)100);

            // output the binary data to the output stream
            bitmap.Save(context.Response.OutputStream, jpegCodec, parameters);

            // release resources
            graphics.Dispose();
            bitmap.Dispose();
        }

  • Facebook
  • Twitter
  • Digg
  • Print
  • email

11/10/2010

VS Tips and Tricks Tip#1 (Pasting)

If your like me, you do a lot of copy & pasting in Visual Studio.  I always hated having to recopy stuff because you copied something new to the clip board.  Well Try this.

Hold down Ctrl+Shift while repeatedly pushing the V key.  This will cycle though your clip board until you find a past snippit you would like to paste.

Cheer!

  • Facebook
  • Twitter
  • Digg
  • Print
  • email

11/08/2010

Version your CSS and JS File…DO IT!

As a developer working on web applications for the past 12 years I have always had to deal with the questions like “I did not see the change on my browser, was the code updated?”.  The quick response was to clear your browser cache and cookies and restart (maybe only worked about 50% of the time). After several years of going through this process I realized that the “normal” users probably do not know how to do that or what that means.  It would also be strange to have a message on your site after each code push saying “We have updated our site, please clear your browser cache for optimal experience”.  

A very basic way to avoid this issues is to create a new file path which will force the browser to download a new file.  You could rename your files for each code push  styles1-0.css and styles 1-1.css but this can be a pain to maintain. 

The way I have been doing this the last few years is to have the application automatically update the file paths every time the files have actually changed.  This way I do not have to worry about manually setting version with each code push.

Below is a .NET function that will return last modified data stamp of the physical file.  This date stamp becomes the version and gets tacked on at the end of the file with a query string.  I use built in .NET caching so the requests do not have to hit the file each time it loads.

public static string GetIncludeFileVersion(string file)
{
    //check if file exists and get date
    string version = "1.0";
    try
    {
        if (HttpContext.Current != null)
        {
            //always force cache
            if (HttpContext.Current.Cache[file] == null)
            {

                if (File.Exists(HttpContext.Current.Server.MapPath(file)))
                {
                    FileInfo fileInfo = new FileInfo(HttpContext.Current.Server.MapPath(file));
                    if (fileInfo != null)
                    {
                        version = fileInfo.LastWriteTime.ToString("MMddyyyhhss");
                        HttpContext.Current.Cache.Insert(file, version, null,
                        DateTime.Now.AddHours(1), TimeSpan.Zero);
                    }
                }
            }
            else
            {
                version = HttpContext.Current.Cache[file].ToString();
            }

        }
        
    }
    catch (Exception ex)
    {
     //silent for now
    }

    return version;

}

In the ASPX or ASCX or Front end files use the code below for all of your CSS/JS/Images and other include references. You may have to put this into a control depending on how your master/aspx files are setup.

<link type="text/css" href="/library/css/styles.css?<%=Ratchet.Framework.Helper.GetIncludeFileVersion("/library/css/styles.css")%>" rel="stylesheet" />

When your pages render you should see a timestamp version of it. something like

<link type="text/css" href="/library/css/styles.css?102120101114" rel="stylesheet" />

  • Facebook
  • Twitter
  • Digg
  • Print
  • email