Thursday, November 4, 2010

C Sharp Windows Task with SCHTASKS

I've had one of the most difficult times creating a simple windows task in C#. There isn't too many examples that work for what I was trying to do. But here's the jest of things.

The Task Name doesn't like spaces in its name. Your code will run and not generate an exception, but the console windows closes so quickly you can't see it.

Well here's how I solved it.

I created a console application and added the following to the class:

public static readonly string Constans = "SCHTASKS.exe";
static void Main(string[] args)
{
// Runs daily at 8:00 AM
CreateScheduleTask("DAILY", "08:00:00", "LMCListenerSysTrayApp2010", @"C:\program files\lmclistener\LMCListenerSysTrayApp2010.exe");
// Runs Every minute
//CreateScheduleTask("MINUTE", 1, "LMCListenerSysTrayApp2010", @"C:\program files\lmclistener\LMCListenerSysTrayApp2010.exe"); // Note the Task name hate spaces in the name
}

public static bool CreateProcess(string strProcessName, string strCommandLineParams)
{
// set process parameters and invoke the process
ProcessStartInfo processInfo = new ProcessStartInfo();
processInfo.WorkingDirectory = Directory.GetCurrentDirectory();
processInfo.Arguments = strCommandLineParams;
processInfo.FileName = strProcessName;
Process process = Process.Start(processInfo);
process.WaitForExit();
if (0 != process.ExitCode)
return false;
return true;
}
public static bool CreateScheduleTask(string strScheduleType, string intTimeInterval, string strTaskName, string strProgramPath)
{
StringBuilder commandLineParams = new StringBuilder();
commandLineParams.AppendFormat("/Create /RU SYSTEM /SC {0} /ST {1} /TN {2} /TR \"\\\"{3}\\\"", strScheduleType.ToUpper(), intTimeInterval, strTaskName, strProgramPath);
return CreateProcess(Constans, commandLineParams.ToString());
}


Tuesday, November 2, 2010

Beginning Programming: File Listener Application Part I

Today is 11/2/2010

At my job in 2006 or somewhere around there. Every election year during the primary and general election season, contribution reporting is required by candidates. The law states that contributions must be made public within 24 hour by our agency.

Well, three times a day I was told when the pdf file containing the contributions were ready to upload to the server. I would manually move the files from the file server over to the web server. After awhile I found this process disturbing. Not in the sense that the act was disturbing, but I'd get into programming large projects and in the middle of writing an algorithm I'm disrupted by someone asking me to post the new pdf documents.

I came up with a solution. Create a console app that runs and listens to the directory for me. It's a simple application that utilizes the .NET File System Watcher Event.

Basically what this event does is listen for changes in a given directory. You can drill down to specific file type or file name. I did both.

In my 2010 release, I was tired of manually launching the console application and seeing this large dos window on my machine. So in this version, which I will demonstrate here, I will create the same console application in a windows form.

The purpose of doing it that way is so that the application hides in the system tray and pops up a notification when an event fires in that directory. I will explain to you what's going on.

One of the things that I find less in the market of programming is learning to port your skills to multiple interfaces. A programmer needs to know how to write a console application and use the same skills to write a desktop and web application. I will show you how to do all three with very little code change.

The overall goal is to build a full blow application called a file listener, which listens to a directory and copy files from one location to another. We will do that only using two platforms, desktop and console. The web is a little more complicated because the user rights and file access is different than console and desktop. But they can be overcame by some modifications to the file systems permissions. But that's a different discussion.

The first thing you need to know is that programming is an iterative process. You build one piece, test it. Build the next piece, test it and then have all these pieces. The next step is connecting them together. Some programmers call them modules, classes, functions, methods, but they are all objects and really the name depends on the programmers environment. Once you know the theory behind how a function, method, class, object and etc works, then you will be able to reverse engineer any language.

The first step is to build the application in modules. Let's start.
Open Visual Studio.

You want to collect a couple of things before getting started:
You need 3 icons - after collecting them set them aside for the main application:
1. Application icon - for the system tray
2. About form icon - just looks good
3. Preferences form icon - same thing, looks good

You will also need to create a image about 175 width x 318 height: This will be for your About Form's System.Drawing.Bitmap on the left side of the about.cs form. You can leave the default provided by Microsoft, but that's no fun.

Okay!

I'm an educator, and I understand the importance of lowering learning curves to make sure a student learns. To make this simple we will build our application in modules and then create our main application bringing all the pieces together.

THE PROJECT:
Mod One: The Listener

The listener is the key piece of our application. We will first build the listener with no validation or extra code, such as, error handling so that you can see how the listener works.

1. Create a new console application called thelistener.
2. We need to add several using statements to the beginning of our form.

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Text;
using System.IO;
using System.Threading;

namespace thelistener
{
static class Program
{
static void Main()
{

}
}
}

FOR THOSE NEW TO CONSOLE APPS
You can skip this section if you already know how this works. If not read below:
A console application runs in a dos window. When the application is compiled, it is compiled as an exe application with a default icon that looks something like this:

The name of the compiled executable file will be named after your projects file name. However, once compiled, you can rename the file to any name you like. One of the problems that you will run into when coding console applications and testing them is if you do not have code written in your console application to stop the console window from disappearing after it has ran your program, it will go away.

This is pretty bad when you have data printing to the console window, such as error messages. To solve that problem we will put a Keyboard read method in the code, which will wait for any key to be pressed before continuing and then exiting.

Before we do that, I want to show you how quickly the console window appears and disappears. Run your program by pressing F5 on your keyboard.

Now lets stop the window from going away until a key is pressed.
Let's add a new function or method to our program called Run.

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Text;
using System.IO;
using System.Threading;

namespace thelistener
{
static class Program
{
static void Main()
{

}
public static void Run()
{

}
}
}


Okay, time to think like a programmer: When the application launches, it first looks for the Main() method. When it finds main, it looks between it's code block { } and executes any code there. Currently, there isn't any code. You can add functions or methods all day, if you never call them, your program is useless.

We added a function or method called Run(), then we need to tell main to call run by adding its method name to Main()

static void Main()
{
Run();
}

Currently the run methods code block looks like this:

public static void Run()
{

}

Which means it will not do anything because there is nothing there. So the console window will show and go away just as before. Our goal is for our application to stop until we press a key on our keyboard.

The Console has several methods to output text to the screen. A few of those is called Write(), WriteLine() and Read(). What makes them different? it depends on your needs. One keeps the cursor on the same line, while the other moves the cursor one line down and the last listens for keyboard strokes.

Add the following:

public static void Run()
{
Console.WriteLine("");
}

We just told the program to write to the console window the string "" of blank text and then move one line down. But the program still closes.

It wouldn't make sense in adding a string of text between the quote marks if we don't get a chance to see them. Let's stop the console window from closing first, then add some text.

Add the following:

public static void Run()
{
Console.WriteLine("Press q to quit the sample program");
Console.Read();
}
Now run the program and bam! You can see the line Press q to quit the sample program

SUMMARY
Let's recap. A console application straight out of the box, a new program, will not remain visible on the screen when first run. That's in any programming language. You need to tell the program to stop and wait for instructions. In C# there is a Console method called Read() that waits for a keyboard event. When they keyboard is pressed it will execute and continue running the program. If there is nothing to do, the console window will disappear.

There are two other methods we discussed, the Write and WriteLine methods which outputs text to the console window. Usage depends on your needs. Write doesn't move the cursor, it sits at the same line as your line execution. However, WriteLine, executes your line and moves the cursor one line down.

I will return tomorrow and show you how to do the same thing in a Windows form. 11/2/2010

Wednesday, March 10, 2010

Windows System Tray and Startup Applications

I created an application at work called LMC Listener. Its job is to listen to activities in a specified folder based on the current year. If there's activity, then delete the files from the copyto location and copy the files from the copyfrom location.

This tutorial is simple, I will show you how to run your app in the background at startup and in the system tray. You should have already built or compiled your app into an exe file.

1. The first step is add a Notifyicon control and a Context Menu control from the toolbox to your windows form.

2. Go to the properties of the Notifyicon control and set the properties of that control.

3. Go to the properties of the Context Menu control and Right click the control and choose Edit. Since this menu will appear when your right-click the icon in the system tray, you will want to add an Exit menu item.

4. Now that you have the Exit menu (button) double click to add the event to the forms code. Then add the following code to close the application.

Application.Exit();

5. Now let's control the Form. Set the following to the Form property window.

FormBorderSize: Fixed Tool Window
WindowState: Minimized
Opacity: 0%
ShowInTaskbar: False

Now that the application is configured for the system tray, rebuilt your app and run it. The application should show in the system tray. Note, the main form cannot be used as an application form. Create another form in your application and call that form, adding an additional item in the Context Menu to do other things.



Configuring the application to run at Windows startup

Now, let's configure the application to start when the user logs in.

To make an application run at every startup, create a shortcut to the application and place the shortcut in the Startup folder of the user who will log on or under the ALLUSERS Profile.

Click Start, Run and type:

%userprofile%\Start Menu\Programs\Startup

This opens the Startup folder of your user profile. Now, right-click the folder and choose New, Shortcut and type the path for the filename which you want to execute at startup. You can simply drag the application shortcut also. This affects only your user profile startup.

To have the application run at startup for every user who logon to the computer, place the shortcut in this path instead:

%allusersprofile%\Start Menu\Programs\Startup

Wednesday, February 24, 2010

Creating a C# Windows Service

Creating a Windows Service can be simple if you have all the right information. What I will show you today will teach you how to create a Windows Service and run that service on Windows XP.

Let's begin:
Launch Visual Studio





Step 1: Create a Skeleton Project

File > New > Project

A new project dialog box will appear giving you options for creating a new project.

Let's narrow down the project type.

From the tree view on the left side of the dialog box select Windows.

This will only display Templates for creating Windows projects. Select Windows Service





Step 2: Project Name & Settings

Give your windows project a name, then click OK to create your project.


Your project Window Window will look like this:



Set your ServiceName to your own name so that you will recognize it when you look at services in Computer Managerment under Services tree. I used LMCListener as my service name. It might be difficult to find the properties to do that. Here is what you do. When the project wizard is completely launched, the first window that appears is the Design View for Service1.cs. Your properies will most likely not display the Service Processes so, simply move your mouse to the Service1.cs tab at the top of your project winds, then in the Properties you will then see ServiceName at the bottom of the list.











Step 3: Adding code to the code view, right click on the gray area of the Service1.cs window and choose View Code

That will give you the following:







I've provided you with some sample code to help you create your first project. Here's the code below:


protected override void OnStart(string[] args)
{
FileStream fs = new FileStream(@"c:\temp\mcWindowsService.txt",
FileMode.OpenOrCreate, FileAccess.Write);
StreamWriter m_streamWriter = new StreamWriter(fs);
m_streamWriter.BaseStream.Seek(0, SeekOrigin.End);
m_streamWriter.WriteLine(" mcWindowsService: Service Started \n");
m_streamWriter.Flush();
m_streamWriter.Close();
}

protected override void OnStop()
{
FileStream fs = new FileStream(@"c:\temp\mcWindowsService.txt",
FileMode.OpenOrCreate, FileAccess.Write);
StreamWriter m_streamWriter = new StreamWriter(fs);
m_streamWriter.BaseStream.Seek(0, SeekOrigin.End);
m_streamWriter.WriteLine(" mcWindowsService: Service Stopped \n"); m_streamWriter.Flush();
m_streamWriter.Close();
}


Now Build your application which will produce an exe file located in the debug > bin folder of your project.



Step 4: The next step would be to Install and Run the Service.


You will do that using an install utility provided as part of the .NET Framework. But before we can install the service let's add some additional features to our service.

I'm not saying that our service is nonfunctional. It will work as is, but what if we want to have the service description and other things show up in our processes panel, or Services Panel. Here's the trick.



If you are not on the Service1.cs Design window, then go there. Now right click on the gray area of the window and choose Add Installer. The Installer objects will be added to your Design window at the top left corner.

There will be two files in that location: ServiceProcessInstaller1 and ServiceInstaller1, both will need their properties configured.

ServiceProcessInstaller1 - Account, this is the user account that the service will run under, set this to LocalSystem.


ServiceInstaller1 - Description, this is the description that will appear in the services admin tool. Set this to Empty Service Description

ServiceInstaller1 - Display Name, this is the service name that will appear in the services admin tool. Set this to Empty Service

ServiceInstaller1 - ServiceName, Set this to EmptyService.

ServiceInstaller1 - StartUpType, this determines whether the service will start automatically with windows, set this to Manual



Alright, thats it, you cannot run a service as you would a windows program. The .net framework has provided a tool that will install the service for you. The InstallUtil.exe program is located in the framework folder. From the command prompt type:

%Windir%\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe C:\YourServiceName .exe

where C:\YourServiceName .exe is the path to you service, to uninstall the service type:

%Windir%\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe /u C:\YourServiceName .exe

Once your service is installed you will find it in the Services admin tool by typing Services.msc at the run prompt:

Note make sure C:\YourServiceName contains the entire path to the exe file your created.

Monday, February 22, 2010

Fake A Call Palm WebOS Application

I developed my third Palm App which was published to the App Catalog. See _here: for a look at the app and its roadmap.

It had a rating of 5 on the 5th day of release. But today, someone posted but did not rate. It's so interesting to me that people would take the time out to destroy another persons reputation to promote their own interest.

Someone did the same thing with my first two applications by telling people, the app destroyed my phone or I downloaded this app several times and it doesn't work.

People are driven by perception and do think for themselves. Palm checks every application that comes through. If the application would destroy a mobile phone, then Palm would be liable and replace the phone and remove the application.

There are legal restrictions and such that we developers must abide by. The tactics of other developers who are competing, well God is watching. One thing that I know for sure, that Whom The Lord Blesses, no man can curse. God will turn their curse against them.

So, for those who are developers or non-developers who wish to harm another person at their own interest. You will suffer, it may not be financially, or something you see with your eyes. But you will not know true peace.

Think of it like this. If a chain is around your neck all your life and a free person came along and said that you are bound. Would you know it? Of course not, you've never known freedom. Some people in boundage will work to have freedom while still in chains. And will associate change as freedom.

Anyway, I'm gone for today. Hey, check out my church website too:

Notepad++ and XML Formatting

I downloaded Notepad++ to use as part of my development environment. I like the convenience of the app. It works a thousand times better than the regular notepad that comes with windows and it also does things that you would not expect from a name Notepad.

I guess when the mind thinks notepad, we think limited app.

Anyway, lately I've been working with lots of XML inside of a table. I've been copying xml files and pasting them into Visual Studio and working from their. But VS 2008 takes a long time to load and all I want to do is look at the XML file and code against it.

So I opened Notepad++. This is when I ran into a problem. The text pasted as one long string on line 1.

I searched for a method for formatting the xml. The web suggested Tidy. I downloaded the command line tidy.exe and that was out of scope. I didn't want to use two apps to accomplish formatting text, so I did additional searches and discovered that, in the new addition of Notepad++, tidy is included. That is version 5.6.6.

This is how to format your XML files.
In Notepad++ choose
> TextFX
> HTML Tidy
>Tidy Reindent XML

and the beauty of a thing is revealed.

Thursday, February 18, 2010

Palm WebOS

My experiences programming for Palm WebOS has been an interesting adventure. I'm enjoying this new path of programming for mobile devices. I've written several programs, off and on, for Windows mobile devices, but none that I sold to others. I wanted to code for the iPhone, but I like things to be simple and coding for the iPhone took lots of my time.

I already knew HTML, Javascript, JAVA, C#, CSS, ADO.NET, ASP.NET, AJAX, SQL, MYSQL, PHP, and some C and C++. So I needed a language that didn't require me to start over again.

Palm WebOS became exciting to me. I was one of the first developers to port my application to the Pre. It was difficult at first because I needed to learn the syntax of a few languages I've never encountered before.

SQLite, Mojo, JSON, Prototype! What in the world are these? One of the problems learning a new language when you know so many is that you have to almost become a child to learn the new, otherwise you will automatically try to solve the new development problems using the same language structure of the old.

Just like not knowing about coding, and learning a new language has its restraints and learning curve.

What I've learned about UI development for Palm WebOS has increased my UI development for desktop and web apps; I don't have words to express the appreciation.

Programming for the Pre and Pixie requires a UI developer to create an environment that is simple and yet communicates exactly what the user needs to know. Don't make me think.

If a person has to think about what they are doing, then the application is not working. I've purchased and downloaded free applications from the Palm Catalog and could not figure out what to do.

There was one gun application that tried to tell me to cock the rifle by holding the phone up and pushing forward. It didn't work. I couldn't figure it out. I read in detail, wrote it down and nothing worked. Either the app was broke or I was dumb.

Anyway, I've been developing UI and coding for more than 10 years and learned a great deal about what people want and how to speak to them with my applications. I am happy that Palm came out with such a great roadmap.

It doesn't take a lot of my time to develop a great application. I created my third application in 4 days. It's called Fake A Ring!

To all those who wish to learn and make money having fun. It's a great place to be.