Category Archives: .NET

How to deploy a new MVC 4 or MVC 5 app to and older IIS 6 server

You can install newer MVC apps on an older Windows 2003 server (it can be done very easily). You must simply configure your Web.Config with a few settings (as shown below) and you may need to go into the Windows file explorer and grant the correct rights to your web user for the path you install to. Ignore the bit about the ASP.NET user (that’s for something unrelated to what I am showing you here):

Notice I added customErrors with the value, mode=”Off” and I added a whole section called system.codedom section.

You will also need to configure your project by right clicking on your project, and selecting “Add Deployable Dependencies…” and then check all the boxes in the dialog that follows.

Then, highlight and select all the references in your new _bin_deployableAssemblies and set the properties for all of the to either “Copy always” or “Copy if newer”

Finally, make sure that Global.asax is added to the list of files you can access. This is done under IIS under the Virtual directory you care about (where you installed your web site) or under the web site itself.

Programming by existence

If something is there, it has existence.

In C# this makes all the difference. I realized this morning that I don’t wire-up relationships, but the C# MVC system works on the basis of mere existence.

If a filename with a certain name exists, it is accessed by a controller. In the Data Entity Model, the existence of a table name is mapped to a class name. By existence. I don’t tell the C# system what to associate with what. I just create the item, and its existence makes it alive.

C# MVC programming is programming by existence.

It is also programming by name. When something exists, it must be named (a file name, a class name, a property name, etc.). If it exists, its name is how it relates to the system.

C# MVC programming is programming by existence with right naming.

This is eloquent.

Write a Windows Console Application in C# that uses Twitter (and do it in 30 minutes or less)

I decided to write a program called “microSpeak140″ that would be a Windows command-line tool to let me post Twitter updates. The reason for such a seemingly useless tool comes from an idea I had about subscription-based communication to unmanned devices, which naturally led to the thought about implementing an Erlange-like language distributed over Twitter. Hence I started down this path. But none of that is terribly relevant to this post, so I’ll skip all the “whys?” and go right to the “how?”

Step 1: Pick a name for your program (I picked “microSpeak140″).

Step 2: Go to Twitter developer’s site and register the name you picked: https://dev.twitter.com/apps/

If you are like me, you may want to skip this step and go right to the TCP/IP interface (thinking, “just tell me what port to connect to and I’ll start talking”). But it’s not like that. Twitter won’t let you near their servers so easily; there is no skipping this really simple step–it only takes a minute and it is free. So go register your program name at https://dev.twitter.com/apps/ and grab the ASCII strings they give you.

Namely, they will give you two string, the “Consumer key” and the “Consumer secret”. These are the two ASCII strings we need to complete the following steps (you will add them to the Speak140 object). You need them for Twitter to let your program talk to their servers, and you will put them into your C# code file (again, in this case, Speak140.cs).

Step 3: Download the .NET library, TweetSharp from TweetSharp (or use NuGet in Visual Studio).

Step 4: Create a new project in Visual Studio, a Visual C# > Windows > Console Application (give it the same name — in my case, again, this is microSpeak140.cs). Note, I also like to rename the default “program.cs” to “microSpeak140.cs”

Step 5: Add a ref to TweetSharp (which you downloaded in Step 3).

Step 6: Create your Main program as follows (inside program.cs or, in my case, microSpeak140.cs):

using System;
namespace microspeak140
{
    class microSpeak140
    {
        static void Main(string[] args)
        {

            int len = args.Length;
            int start = 0;
            string pw = string.Empty;

            
            if (len > 0 && args[start] == "-P")
            {
                if (args.Length > 1)
                {
                    pw = args[1];
                    start = 2;
                    len -= 2;
                }
            }

            if (len > 0 && len < 3)
            {
                Speak140 t = new Speak140();
                if (len == 2 && args[start] == "-W")
                    t.theirWall(args[start+1], 0, pw);
                else if (len == 1 && args[start] == "-F")
                    t.iFollow();
                else if (len == 1 && args[start] == "-M")
                    t.followMe();
                else if (len == 1 && args[start] == "-W")
                    t.myWall(0, pw);
                else if (len == 1) // they are leaving a comment.
                    t.Say(args[start], true, pw);
            }
            else
            {
                Console.WriteLine("Usage: microSpeak140 [-P password] <-F> | ");
                Console.WriteLine("            <-W [name of someone else]> | ");
                Console.WriteLine("            <\"message to send (max 140 character)\">");
                Console.WriteLine();
                Console.WriteLine("       -P   Pass in -P followed by a password if you want"); 
                Console.WriteLine("            to encrypt or decrypt messages.");
                Console.WriteLine("       -W   Show me what is on my wall, or [someone else]'s wall.");
                Console.WriteLine("       -F   List the people I follow.");
                Console.WriteLine("       -M   List the people that follow me.");
            }
        }
    }
}

Step 9: Include this object I created: Speak140.cs.
Speak140.cs is my own wrapper around the Twitter DLLs. I had a very narrow purpose for my console application, so this object helps me to zero-in on the narrow set of functions I really wanted to leverage, along with helping me with Twitter key management and encryption. I’ll have more to say about encryption below–by which I mean the option to encrypt the messages you post to Twitter.

Step 10: Build your program.
Note: you may need to go to Project->microSpeak140 properties->Application and set the target framework as .NET 3.0 (i.e., not the default 4.0). Then build it. Then switch it back to 4.0 and try again.

Step 11: Drop down to a command window, go to the build directory, and run it:

    microSpeak140  "At coffee house writing Twitter app in 30 minutes or less"

Step 12: Encrypt your comments
You will notice in the program that I provide a command-line option for a password. This allows you to encrypt your comments. But I will save the details about that for another post. [Indeed, read my later article here for a discussion of encrypting and decrypting messages using MicroSpeak140].

Step 13: What Next: Make it your own!
Maybe you will want to add your own reader functions to the Speak140 object. Or, it might be a good idea to add code to use the registry as opposed to files, and thus handle multiple twitter accounts. You have all the code, so enjoy it and make it your own.

Pipe Stdin to a C# program and filter out data

I need a program that will filter command line input, and strip out CR+LF from any line that has a certain text.

Solution (in C#):

http://www.mrrives.com/Programming/Filter/Filter.cs

And the EXE file:

http://www.mrrives.com/Programming/Filter/Filter.exe

Here is the code (simple):

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

namespace Filter
{
    class Filter
    {
        static void Main(string[] args)
        {
            if (args.Length == 0)
            {
                Console.WriteLine("FILTER: Parameter format not correct");
                return;
            }
            if (args[0] == "/?")
            {
                Console.WriteLine("Searches for a text string typed at the prompt or piped from another program");
                Console.WriteLine("");
                Console.WriteLine("FILTER \"string\"");
                Console.WriteLine("");
                Console.WriteLine("if string in a line, line is echoed without a CR+LF, otherwise it is.");
                return;
            }

            string s = string.Empty;
            try
            {
                while (System.Console.In.Peek() != -1)
                {
                    s = System.Console.In.ReadLine();
                    if (s.Contains(args[0]))
                        Console.Write(s);
                    else
                        Console.WriteLine(s);
                }
            }
            catch
            {

            }

        }
    }
}

Note, I was able to use the really nice web site, http://www.manoli.net/csharpformat/format.aspx to format my C# code into HTML

Part 1: Building an ActiveX Control in C# (with CAB file via CabArc)

I will show you how to write MyActiveX.cs, turn it into a DLL, place it on an HTML page and distribute it with a CAB file. But I will start in reverse order.

I will start with the HTML code and the CAB file. If you are going to build an ActiveX control in C#, then you need to be able to send it around (by the way, ActiveX controls only work in IE, not Chrome or Firefox, so you will only send it around to IE browsers).

When IE tries to access an ActiveX file (and it does not already have it on the hard drive), then the HTML code tells it to download a CAB and install it. For the sake of simplicity, let’s say your index.html file points to your ActiveX control this way:

<OBJECT id="MyActiveX" name="MyActiveX" 
classid="clsid:3026b51e-a3ff-4587-9ed2-36d7d527bbe6" VIEWASTEXT 
codebase="MyActiveX.cab#Version=1,0,2,0">

MyActiveX.cab is in the same folder as index.htm, and if the MyActiveX.dll is missing, then the CAB file is downloaded and installed. But you have to make that CAB file. To build the CAB file (which is like a ZIP file), you need to use the free CABARC program. You will pass it the name of the ActiveX, and a few support tools that will get stuffed in there with it. I will explain all the files in time, but here is the command line to create a CAB:

cabarc -s 6144 n MyActiveX.cab MyActiveX.dll RegNetX.exe setup.cmd MyActiveX.inf

(You can Download Microsoft’s cabarc.exe here).

This creates the CAB file, MyActiveX.cab, and inside it is the other four files. The final file, MyActiveX.inf, tells the CAB file what to do and what is inside it. It tells us that the ActiveX DLL will go to DestDir=11 (which is a secret Microsoft code meaning windows\sytem32). DestDir=11. Write it down. Use it. The -s command means to add on an extra 6144 bytes so that we can sign this CAB file when all is said and done (I will talk about signing CAB files in Part 2 or Part 3 — do not underestimate how important it is to sign your CAB file and ActiveX file if you want clients to be able to install and use your software).

Let’s look first at MyActiveX.inf (which tells the CAB file how to install on the client):


[Setup Hooks]
hook1=hook1

[hook1]
run=%EXTRACT_DIR%\setup.cmd

[version]
signature="$CHICAGO$"
AdvancedINF=2.0

[Add.Code]
MyActiveX.dll=MyActiveX.dll
MyActiveX.inf=MyActiveX.inf
setup.cmd=setup.cmd
RegNetX.exe=RegNetX.exe

[MyActiveX.dll]
file-win32-x86=thiscab
clsid={3026b51e-a3ff-4587-9ed2-36d7d527bbe6}
RegisterServer=no
FileVersion=1,0,2,0
DestDir=11

[MyActiveX.inf]
file=thiscab

[setup.cmd]
file=thiscab

[RegNetX.exe]
file=thiscab

If you inspect this file, you see that the CAB file will run setup.cmd as the install script when it arrives at a target machine. There is a good article on CAB files and hooks on the Microsoft web site, but that article fails to give you the extra steps required to release a .NET based ActiveX control. Still, go read it and get familiar with the subject, or keep moving along here and you’ll get the gist.

The reason you need all this specialty code for a .NET project, is because a CAB file uses RegSvr32 to register an ActiveX, and that won’t work for a .NET DLL. You need to use Microsoft’s RegAsm to register a .NET ActiveX, but CAB files don’t know about RegAsm. The install location of RegAasm is in your .NET directory. So Setup.cmd is called as the install program, and it handles the registration.

That’s the trick! Setup.cmd is the trick. And here is Setup.cmd


@echo off
set MyACTIVEX=%windir%\system32\MyActiveX.dll
copy MyActiveX.dll %MyACTIVEX%
RegNetX

You may be wondering: What is RegNetX?

It is a little install program I wrote. All it does is install my one ActiveX program. I compile the install program from the command line using csc (which comes free with .NET and is in your Framework directory):

csc RegNetX.cs

Here is the code:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Win32;
using System.Diagnostics;

namespace RegNetX
{
    class Program
    {
        static void Main(string[] args)
        {

	    string DLL = Environment.SystemDirectory + "\\MyActiveX.dll";

 	    Console.WriteLine("Usage: RegNetX [-u]");
 	    Console.WriteLine("    Will register " + DLL);
 	    Console.WriteLine("   -u unregisters it");

            // This is the location of the .Net Framework Registry Key
            string framworkRegPath = @"Software\Microsoft\.NetFramework";

            // Get a non-writable key from the registry
            RegistryKey netFramework = Registry.LocalMachine.OpenSubKey(framworkRegPath, false);

            // Retrieve the install root path for the framework
            string installRoot = netFramework.GetValue("InstallRoot").ToString();

            // Retrieve the version of the framework executing this program
            string version = string.Format(@"v{0}.{1}.{2}\",
              Environment.Version.Major,
              Environment.Version.Minor,
              Environment.Version.Build);

            // Return the path of the framework
            string path = System.IO.Path.Combine(installRoot, version);

            if (path == null)
                path = installRoot + version;

            try
            {
                Process regAsm = new Process();
                regAsm.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
                regAsm.StartInfo.CreateNoWindow = true;
                regAsm.StartInfo.WorkingDirectory = path;
                regAsm.StartInfo.FileName = "regasm.exe";
                if (args.Length == 0)
                  regAsm.StartInfo.Arguments = "/silent /codebase " + DLL;
                else
                  regAsm.StartInfo.Arguments = "/unregister " + DLL;
 		
		Console.WriteLine(path + "regasm.exe " + regAsm.StartInfo.Arguments );
                regAsm.Start();
                regAsm.WaitForExit(); // based on comboFusion's comment below (in the comment section of this blog)
            }
            catch
            {
                Console.WriteLine("Error running regasm.exe " + args[0]);
            }
        }
    }
}

RegNetX will find the .NET install and call RegAsm. And note well: I hard coded everything to install the ActiveX DLL into the windows\system32 directory. It makes life so much easier if you know that %windir% is a real environment variable that will exist on your target client. When your code is actually installing, it is in a free fall, and your scripts are operating mostly blind, as it were, so you need to try to land in some known fixed location. For that reason, I coded setup.cmd with a fixed install location with an environment variable that will most likely exist. And how nice that DestDir in the INF file is also pointing to %windir%\system32.

After writing this article, I realized that the CAB building tool, cabarc, is old. It is no longer distributed (though it was on my Windows 7 machine). There is another CAB building tool from Microsoft called “MakeCab”. In Part 2 (if I write Part 2), I will go deeper into all this and show the actual ActiveX control. If there is a Part 3, it may be about MakeCab. Given the positive feedback I have received so far, I may just write that second article.