• Facebook
  • RSS Feed
  • Instagram
  • LinkedIn
  • Twitter
Jul 032012
 

I built a little app over the last couple of days, and the first time I deployed to a real machine I saw :

Server Error in ‘/XYZ’ Application.


Configuration Error

Description: An error occurred during the processing of a configuration file required to service this request. Please review the specific error details below and modify your configuration file appropriately.

Parser Error Message: Unrecognized attribute ‘type’.

Source Error:

 

Line 6:  <configuration>

Line 7:    <configSections>

Line 8:      <sectionGroup name=”system.web.extensions” type=”System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BAC56DD364E35″>

Line 9:        <sectionGroup name=”scripting” type=”System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BAC56DD364E35″>

Line 10:         <section name=”scriptResourceHandler” type=”System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BAC56DD364E35″ requirePermission=”false” allowDefinition=”MachineToApplication”/>

Source File: C:\Program Files\MyProg\web.config    Line: 8


Version Information: Microsoft .NET Framework Version:1.1.4322.2379; ASP.NET Version:1.1.4322.2379

 

Distraught!

 

There is a clue though …  See the ASP.Net version information?  I changed that in IIS to 2.0, and refreshed my browser.. bingo.. my app … LIVES!

Oct 102011
 

I love writing tools.  I hate that I have 10 different versions of them on 8 different PC’s !  So, for quite some time I’ve been thinking of ways of automatically keeping them up to date.  The problem is that these tools run from all sorts of machines, with and without internet connectivity… and I want to keep it (and the tool) simple.

So I set off to think of ways of making things automatically keep up to date, whilst staying simple.

The prototype implementation of this is some assistance that I’ve provided to Paul Juster and Andrew Jones, who live with the DSS project.  This project aims to make some sense out of EV Deployment Scanner Output.  It shows some very valuable information, and is evolving all the time.

Most of the tools I have written, so far, are in VBScript, as is DSS.  I’ve not (yet) put the following in to practice on C++ or C# but it should still work I think.

The Plan
Have the version number stored in the file, as a variable.
Read the currently executing VBScript file, and get the version number by reading it line by line (until we encounter that version number mentioned above)
Download the file from the internet somewhere (Google code seems a good place to me)
Repeat the process of reading the file to find out the version information.

If they don’t match :
    Give the end user some information.
    Give them the option of updating.
    If they want to update then
        Rename the current file to filename.oldversion
        Rename the recently downloaded file to be the filename we’re executing
        Relaunch the file we’re executing with any appropriate command line parameters
       
Do whatever the tool needs to do

Run Through
So the first time through, when there is a mismatch, we update to the latest version, and relaunch.  On relaunch the files will match, so we will continue onwards with whatever the tool is doing.

From a Tool Point Of View
What it means from a tool point of view is that it needs to have stable versions stored out on the internet somewhere.  That’s okay.  It means that when you make a stable version you need to put it on that location out on the internet, and tidy up any other versions if need be.

From an Environment Point Of View
Lots of my VM’s don’t have connectivity to the internet.  This will, for the short term, have to change.   It is easy enough to add an additional NIC which is NAT’ed out of the VM environment.  So that’s also okay.

Summary
Hopefully the above is something that I can start incorporating (largely cut and paste) in to future tools that I develop for myself and others, and will stop me "losing" valuable changes that I make, and then can’t remember which VM I did them on (or worse still… losing the VM’s)

Oct 102011
 

After a fair amount more work, I’m now happy with what I’ve produced, it’ll help me enormously, I hope, when I am doing blog posts.  That’s what I’ve done it for.

As an update from the last post what I’ve done is :-

Added a tooltip – so when you hover over an image it shows you the full filename

Added a double click ability – by default this will copy the name of the file to the clipboard

Added a menu option to swap the double click ability – instead of the filename it’ll copy the actual image from the picture box to the clipboard (so you can paste it into a suitable app)

In more detail

ToolTip:

Inside the AddPictureBox function I now have :-

PictureBox pbox1 = new PictureBox();
pbox1.Location = new Point(xcoord, ycoord);
pbox1.Size = new System.Drawing.Size(imagewidth, imageheight);
pbox1.ImageLocation = file;
pbox1.SizeMode = PictureBoxSizeMode.StretchImage;
pbox1.BorderStyle = BorderStyle.FixedSingle;
           
pbox1.DoubleClick += new System.EventHandler(this.pbox1Double_Click);
        // Above we added our own double click event handler for this picture box

toolTip1.SetToolTip(pbox1, file); // when we hover over we get the filename
this.Controls.Add(pbox1);

This works by just dragging and dropping a tooltip control from the toolbox on to the form. Above, the line toolTip1.SetToolTip(pbox1, file) sets the tooltip for this control to be the filename.

DoubleClick:

Also in the above function you can see I added an event handler to the doubleclick event which calls this.pbox1Double_Click, which is this :

private void pbox1Double_Click(object sender, System.EventArgs e)
{
    // Add the filename of the picture to the clipboard
    PictureBox pboxtemp = (PictureBox)sender;

    if (CopyName)
      Clipboard.SetDataObject(pboxtemp.ImageLocation);
    else
      Clipboard.SetImage(pboxtemp.Image);
}

That’s the bit of code which copies either the filename or the image to the clipboard.

Change DoubleClick Behaviour:

I declare CopyName at the top of the class as a boolean, and the default value is true.  So by default, double clicking on image will copy the filename.

I’ve added a new menu item which does the following on the click event:

   var mi = (ToolStripMenuItem)sender;
            if (mi.Checked == true)
            {
                CopyName = true;
            }
            else
            {
                CopyName = false;
            }

Interestingly the actual ticking and unticking is handled by the control automatically.  I spent ages trying to flip the state of the item on the menu line, to discover it does it for you !

Finally

I updated things and have a Change Directory, and a Refresh menu item.

Change Directory allows you to switch to a different folder

private void changePathToolStripMenuItem_Click(object sender, EventArgs e)
{
    // Need to bring up a folder choose dialog, and set PathToScan afterwards
    this.folderBrowserDialog1 = new System.Windows.Forms.FolderBrowserDialog();

    // Set the help text description for the FolderBrowserDialog.
    this.folderBrowserDialog1.Description =
        "Select the directory that you want to use as the default.";

    // Do not allow the user to create new files via the FolderBrowserDialog.
    this.folderBrowserDialog1.ShowNewFolderButton = false;

    this.folderBrowserDialog1.RootFolder = Environment.SpecialFolder.MyComputer; 
            
    DialogResult result = folderBrowserDialog1.ShowDialog();

    if (result == DialogResult.OK)
    {
        PathToScan = folderBrowserDialog1.SelectedPath;
        scanFolder();
    }
}

Refresh clears just the picturebox controls off the form – otherwise all the menus disappear too!:

private void refreshToolStripMenuItem_Click(object sender, EventArgs e)
{
    //Remove all the current picturebox controls
    for (int i = this.Controls.Count - 1; i >= 0; i--)
    {
        var t = this.Controls[i];

        if (t.GetType().ToString() == "System.Windows.Forms.PictureBox")
            this.Controls.Remove(t);
    }
    scanFolder();
}
    There are still some things that I’d like to do to the app, but for now, this is getting parked as a SUCCESS.
    Look out for the next project, which will cover hidden messages – and a surprise.
    Time Spent So Far : 180 minutes
    References:
    Tooltip info:

http://support.microsoft.com/kb/810001

http://msdn.microsoft.com/en-us/library/system.windows.forms.tooltip.settooltip.aspx

    Refresh:

http://social.msdn.microsoft.com/Forums/en-SG/Vsexpressvcs/thread/A62EB64C-A31E-4372-BC1F-771FEC18149E

      Clipboard manipulation:

    http://msdn.microsoft.com/en-us/library/8x0f8th9(v=vs.80).aspx

    http://msdn.microsoft.com/en-us/library/system.windows.forms.clipboard.aspx

    Oct 092011
     

    I think I must deliberately not list steps in order.   In the last post I put :

    • Take as input a folder name
    • Scan that folder for image files (.png, .jpg, .jpeg, .tiff, .png – for now)
    • Add the picture boxes for each image found as I go along

    What I actually ended up doing just now was the second and third parts of that, and not the first !

    Here is what I modified the code with :-

    string file = "";
    
    int xcoord = startxpos;
    int ycoord = startypos;
    
    DirectoryInfo di = new DirectoryInfo(PathToScan);
    FileInfo[] rgFiles = di.GetFiles("*.jpg"); // Just jpg's for now
    foreach (FileInfo fi in rgFiles)
    {
           file = fi.FullName;
           AddPictureBox(xcoord, ycoord, imagewidth, imageheight, file); 
           xcoord = xcoord + imagewidth + buffer;
           if (xcoord + imagewidth > this.Width) // new row
            { 
               xcoord = startxpos;
               ycoord = ycoord + imageheight + buffer;
            }
    }

    So what this does it start at a particular path (PathToScan) looking for just JPG’s (for now)  and call the AddPictureBox function passing in the coordinates, and the full name of the file.

    Some of the other changes involved moving the sizes and coordinates to start from up into constants higher up.  In fact, I don’t need to pass imagewidth, and imageheight to the AddPictureBox function, as the values of those variables is a/ constant, and b/ visible throughout the class now.

    The AddPictureBox function hasn’t really changed, other than to take the parameter file, which is the full filename.

    So the next thing that I need to do is to truly take the path to start scanning at as a parameter. 

      Time Spent So Far : 120 minutes
      References:

    http://msdn.microsoft.com/en-us/library/system.io.fileinfo.aspx

    http://msdn.microsoft.com/en-us/library/system.io.directoryinfo.aspx

    Oct 072011
     

    A very slight change of tack …  I was going to dynamically work out how big to make the picture rectangles, and then add them all with the images that are in the folder.  Very hard, looking at the algorithms out there on the internet.  Maybe that’ll be saved for (another) rainy day.

    In the meantime I can see for now that image boxes 160 wide by 270 high seem to be a-okay.  (I should probably make that configurable and stored in a .exe.config at some point).  So what I decided to do was (as a first step for fully dynamic loading) add N images to the form.

    I do this as follows :

     

    const int imagewidth  = 160;
    const int imageheight = 270;
    const int startxpos = 20;
    const int startypos = 40;
    const int buffer = 5;
                
    int NumImages = 12; // temporary number for now !
    
    int xcoord = startxpos;
    int ycoord = startypos;
    
    for (int i = 1; i <= NumImages; i++)
        {
          AddPictureBox(xcoord, ycoord, imagewidth, imageheight);
           xcoord = xcoord + imagewidth + buffer;
           if (xcoord + imagewidth > this.Width) // Gone past the end; star new row
                    { 
                        xcoord = startxpos;
                        ycoord = ycoord + imageheight + buffer;
    
                        // Do something if we have now gone off the bottom 
                        // Autoscroll is on, on the form, so it's good
                    }
         }
                

    In there you can see I call a function AddPictureBox, that just does this :

    private void AddPictureBox(int xcoord, int ycoord, int imagewidth, int imageheight)
    {
       PictureBox pbox1 = new PictureBox();
       pbox1.Location = new Point(xcoord, ycoord);
       pbox1.Size = new System.Drawing.Size(imagewidth, imageheight);
       pbox1.ImageLocation =
           @"C:My Dropboxcode~CodingDocsBackgroundReadingPicture 2.jpg";
       pbox1.SizeMode = PictureBoxSizeMode.StretchImage;
       pbox1.BorderStyle = BorderStyle.FixedSingle;
       this.Controls.Add(pbox1);
    }

     

    I also changed the AutoResize property on the form in design mode to TRUE.  This means that if you try to add controls beyond the visible boundaries of the form, a scroll bar is automatically added.  My code controls the width, so we shouldn’t ever end up with a horizontal scrollbar, so it should just be height.

    I tested it with 8, and 38 as the number of images, and the scroll bar does correctly get added at the right time.

     

    All good so far.

     

    Modifying the plan somewhat, I think I now need to :-

    • Take as input a folder name
    • Scan that folder for image files (.png, .jpg, .jpeg, .tiff, .png – for now)
    • Add the picture boxes for each image found as I go along

    I’ll need to modify the function above to take as input the full path for a file that has been found in the folder that has been selected.. but largely it’s good to go.  Just need to do the scanning code next.

     

      Time Spent So Far : 90 minutes
      References: No new ones