Thursday, April 23, 2009

Creating Needed Installer for Windows Services

This is not the actual "installer". This code is needed for the service to operate correctly. We will get to installing and deployment latter..

Add The Installer Code

From Service1 designer, right click in the gray area and choose Add Installer.

Another file will be added to your Solution Explorer, called ProjectInstaller. On this class will be two components in the designer, ServiceProccessInstaller1 and ServiceInstaller1.

Let's configure the Installer: Click on the listed component and alter the following properties:


  • Account = LocalSystem (will cause service to run under local service account)
  • ServiceName = NewService
  • StartType = Automatic (wether your service will auto start after reboot)
  • DisplayName = NewService
Now we Build and Install the service to test it out.

Well, that's it for today. We'll continue with next lesson in another time.


Tuesday, March 17, 2009

Creating Services with Visual Studio 2008

A Windows service is an aplication that runs in the background. Here's an example on how to make one. It's for Visual Studio 2008, but it would work with Visual Studio 2005 as well.

Create the Service

From Visual Studio Start Page, choose create project... Select Windows Service and give a name of NewService.

First we will do is add a timer to the Service. DO NOT USE THE TIMER IN THE TOOLBOX. The Timer for Windows Forms won't work for Services. We will have to the System.Timers.Timer component by right clicking on the Toolbox, and Choose Items.

Find the one that matches below:

Click OK. This will put the Timer into the Printing section of the Toolbar for some reason.

From The Service1 designer. Click on Timer1, and set the interval to 10000 (10 seconds). Then Double-click to open Code View for Timer1_Elapsed.

Add the Following Code to the Timer1_Elapsed:

Dim MyLog As New EventLog()
' Create a new event log
' Check if the Event Log Exists
If Not MyLog.SourceExists("NewService") Then
MyLog.CreateEventSource("NewService", "NewService_Log") ' Create Log
End If

MyLog.Source = "NewService" ' Write to the Log
MyLog.WriteEntry("NewService_Log", "Service is running", EventLogEntryType.Information)

End Sub

And for OnStart():

Protected Overrides Sub OnStart(ByVal args() As String)
' Add code here to start your service. This method should set things
' in motion so your service can do its work.

Timer1.Enabled = True

End Sub

Now is normally where you would hit Run to start and debug your App. This is not the case with Windows Services. We have to add a few thing called Installers to make them work correctly.

We will discuss it in the next part of this tutorial.

Tuesday, January 13, 2009

Linked Server SQL Syntax for SQL Server

Here they are some examples how to use linked server to execute SELECT, INSERT, UPDATE and DELETE statements. Run these statements in either Query Analyzer for SQL Server 7 / 2000 or in New Query field for SQL Server 2005 / 2008. These examples assume following conditions:

  1. "MYLINKEDSERVER" as the name for a linked server that connect to PostgresSQL Database using pgsqlODBC.
  2. BOOKS is a table in a schema named LIBRARY, and AUTHOR is a column in BOOKS table.

SELECT Statement




INSERT Statement



VALUES ('Shaun Walker')

UPDATE Statement



AUTHOR='Bill Gates' WHERE AUTHOR='Shaun Walker'

DELETE Statement



WHERE AUTHOR='Shaun Walker'


To perform DELETE or UPDATE operations, the target table must have a unique index. For more information, please refer to the section titled UPDATE and DELETE Requirements for OLE DB Providers in the SQL Server Books Online.

Monday, January 12, 2009

How to make Linked Server between MS SQL Server 2008 64 bit and PostgreSQL 8.3

If however you had a SQL Server 2008 64-bit server and wished to create a linked server to a PostgreSQL server. You ran into 2 very annoying obstacles.

Obstacle 1:
There for a long-time was no 64-bit ODBC driver nor native driver for PostgreSQL. This obstacle was somewhat alleviated when Fuurin Kazanbai made experimental compiled 64-bit PostgreSQL ODBC drivers available which work for AMD and Intel based processors.

Obstacle 2:
All looked good in the world until you tried this in SQL Server 2005 64-bit and low and behold - you needed a 64-bit OLEDB provider for ODBC to use it in SQL Server 2005 64-bit. Yes we waited patiently for years for this piece to be available. We still love you Microsoft. Then as Jeff Crumbley pointed out - Microsoft released an OLEDB 64-bit provider for ODBC in early April 2008.

Below are the steps to get a PostgreSQL linked server working in SQL Server 2008 64-bit:

  1. Run WindowsServer2003.WindowsXP-KB948459-v2-x64-ENU.exe - (Available as of 4/4/2008 from:
  2. Make the folder C:\Program Files\PostgreSQL\8.1\AMD64bin (you can try the 8.3 if you are running that) and place the dlls from psqlodbc_AMD64 available from
  3. Run the psqlodbcwAMD64.reg file.
  4. Create a System DSN in the 64-bit Data Source (ODBC).
  5. Create a Linked Server in SQL Server to PostgreSQL (I'll explain it in detail below).

OK, now here are the steps to configure a Linked Server in SQL Server 2008:

  1. Launch the SQL Server 2008 Management Studio.
  2. Under the Server Objects folder, right click on Linked Servers and select New Linked Server.
  3. Enter a name for the Linked Server and choose "Other Data Source". Do not use any spaces or special characters in the Linked Server's name.
  4. Select "Microsoft OLE DB Provider for ODBC Drivers" from the Provider dropdown list. Enter MSDASQL for the Product Name.
  5. In the "Data Source" field, enter the name of the ODBC System data source you wish to use. Note that you have to use exact same name as it shown in the ODBC Data Source Administrator.
  6. In the Security page, select the "Be made using this security context". Enter a valid remote user/login (user ID) and password for the remote host.
  7. Leave the remaining fields blank and click OK to save the linked server configuration.

Now it's time for testing our configuration. If an error occures, review the error and make changes to the linked server configuration as necessary.

In the Management Studio, expand the linked server node and then expand the Catalogs node. Click on the node for the linked server and expand the Tables to view a table list.

That's it, and you've make a Linked Server between MS SQL Server 2008 64 bit and PostgreSQL 8.3. Congratulation. In the next posting, I'll explain how to use the linked server to manipulate the data in the remote server.

Thursday, January 8, 2009

Create MySQL User Account from Command Line

Follow these steps to create new user for MySQL in command line. Note this instruction assume that you have already setup MySQL.

1. Open a terminal and login to MySQL as root

mysql --user="root" --password="your_root_password"

2. Create new user and password with following command

CREATE USER 'new_username'@'localhost'
IDENTIFIED BY 'password_for_new_user';

3. Assign privileges to the new user

GRANT ALL ON *.* TO 'new_username'@'localhost';

4. Exit MySQL interface



The above instructions will create a new user account on "localhost" and grant the user all privileges. While this is safe for my development environment, you would obviously want to grant only the necessary permissions in a production environment.

For more information including the MySQL manual references, visit here.

Tuesday, December 30, 2008

Allowing application servers to relay off Exchange Server 2007

by: Scott Landry

From time to time, you need to allow an application server to relay off of your Exchange server. You might need to do this if you have a SharePoint, a CRM application like Dynamics, or a web site that sends emails to your employees or customers.

You might need to do this if you are getting the SMTP error message "550 5.7.1 Unable to relay"

The top rule is that you want to keep relay restricted as tightly as possible, even on servers that are not connected to the Internet. Usually this is done with authentication and/or restricting by IP address. Exchange 2003 provides the following relay restrictions on the SMTP VS:

Here are the equivalent options for how to configure this in Exchange 2007.

Allow all computers which successfully authenticate to relay, regardless of the list above

Like its predecessor, Exchange 2007 is configured to accept and relay email from hosts that authenticate by default. Both the "Default" and "Client" receive connectors are configured this way out of the box. Authenticating is the simplest method to submit messages, and preferred in many cases.

The Permissions Group that allows authenticated users to submit and relay is the "ExchangeUsers" group. The permissions that are granted with this permissions group are:

NT AUTHORITY\Authenticated Users {ms-Exch-SMTP-Submit}NT
AUTHORITY\Authenticated Users {ms-Exch-Accept-Headers-Routing}NT
AUTHORITY\Authenticated Users {ms-Exch-Bypass-Anti-Spam}NT
AUTHORITY\Authenticated Users {ms-Exch-SMTP-Accept-Any-Recipient}

The specific ACL that controls relay is the ms-Exch-SMTP-Accept-Any-Recipient.

Only the list below (specify IP address)

This option is for those who cannot authenticate with Exchange. The most common example of this is an application server that needs to be able to relay messages through Exchange.

First, start with a new custom receive connector. You can think of receive connectors as protocol listeners. The closest equivalent to Exchange 2003 is an SMTP Virtual Server. You must create a new one because you will want to scope the remote IP Address(es) that you will allow.

The next screen you must pay particular attention to is the "Remote Network settings". This is where you will specify the IP ranges of servers that will be allowed to submit mail. You definitely want to restrict this range down as much as you can. In this case, I want my two web servers, & to be allowed to relay.

The next step is to create the connector, and open the properties. Now you have two options, which I will present. The first option will probably be the most common.

Option 1: Make your new scoped connector an Externally Secured connector

This option is the most common option, and preferred in most situations where the application that is submitting will be submitting email to your internal users as well as relaying to the outside world.

Before you can perform this step, it is required that you enable the Exchange Servers permission group. Once in the properties, go to the Permissions Groups tab and select Exchange servers.

Next, continue to the authentication mechanisms page and add the "Externally secured" mechanism. What this means is that you have complete trust that the previously designated IP addresses will be trusted by your organization.

Caveat: If you do not perform these two steps in order, the GUI blocks you from continuing.

Do not use this setting lightly. You will be granting several rights including the ability to send on behalf of users in your organization, the ability to ResolveP2 (that is, make it so that the messages appear to be sent from within the organization rather than anonymously), bypass anti-spam, and bypass size limits. The default "Externally Secured" permissions are as follows:

MS Exchange\Externally Secured Servers {ms-Exch-SMTP-Accept-Authoritative-Domain}MS Exchange\Externally Secured Servers {ms-Exch-Bypass-Anti-Spam}

MS Exchange\Externally Secured Servers {ms-Exch-Bypass-Message-Size-Limit}

MS Exchange\Externally Secured Servers {ms-Exch-SMTP-Accept-Exch50}

MS Exchange\Externally Secured Servers {ms-Exch-Accept-Headers-Routing}

MS Exchange\Externally Secured Servers {ms-Exch-SMTP-Submit}

MS Exchange\Externally Secured Servers {ms-Exch-SMTP-Accept-Any-Recipient}

MS Exchange\Externally Secured Servers {ms-Exch-SMTP-Accept-Authentication-Flag}

MS Exchange\Externally Secured Servers {ms-Exch-SMTP-Accept-Any-Sender}

Basically you are telling Exchange to ignore internal security checks because you trust these servers. The nice thing about this option is that it is simple and grants the common rights that most people probably want.

Option 2: Grant the relay permission to Anonymous on your new scoped connector

This option grants the minimum amount of required privileges to the submitting application.
Taking the new scoped connector that you created, you have another option. You can simply grant the ms-Exch-SMTP-Accept-Any-Recipient permission to the anonymous account. Do this by first adding the Anonymous Permissions Group to the connector.

This grants the most common permissions to the anonymous account, but it does not grant the relay permission. This step must be done through the Exchange shell:

Get-ReceiveConnector "CRM Application" Add-ADPermission -User "NT
AUTHORITY\ANONYMOUS LOGON" -ExtendedRights "ms-Exch-SMTP-Accept-Any-Recipient"

In addition to being more difficult to complete, this step does not allow the anonymous account to bypass anti-spam, or ResolveP2.

Although it is completely different from the Exchange 2003 way of doing things, hopefully you find the new SMTP permissions model to be sensible.