Click here to Skip to main content
6,595,854 members and growing! (18,738 online)
Email Password   helpLost your password?
Languages » C# » General     Beginner License: The GNU General Public License (GPL)

Outlook Signatures Out of Active Directory Information

By cute-solutions

Generating Outlook signatures automatically using information of the Active Directory
C# 2.0, Windows, .NET 2.0VS2005, Dev
Posted:13 Mar 2007
Updated:24 Aug 2007
Views:15,161
Bookmarked:13 times
Announcements
Loading...
 
Search    
Advanced Search
Add to IE Search
printPrint   add Share
      Discuss Discuss   Broken Article?Report  
5 votes for this article.
Popularity: 2.15 Rating: 3.07 out of 5

1
1 vote, 20.0%
2
2 votes, 40.0%
3
2 votes, 40.0%
4

5

Watch www.cute-solutions.de

Screenshot - outlooksig.gif

Introduction

Outlooksignature is a simple Windows Console Application which generates Outlook signatures automatically using Information in the Active Directory. It makes it very easy to generate a huge number of signatures.

Background

The basic idea behind this application is to use a general signature in Enterprises. I was searching for some programs with this function, but there are only a few very expensive solutions.

Configure the Application using the OSG.INI

[DatabaseParams] 
SearchFilterpart1= 
SearchFilterpart2= 
SearchFilterpart3= 
SearchFilterpart4= 
SearchFilterpart5= 
SearchFilterpart6= 
Fields=samaccountname,... 

[SignatureParams] 
PathSignaturen= 
SignaturVorlPath= 
VorlagenDateien=signatur.txt,signatur.rtf,...

The key fields "SearchFilterpart1 to SearchFilterpart6" are for registering the LDAP search filter (e.g. (& (ObjectClass=user) (cn=Maier)) for all users called Maier). The finally used search consists of the 6 parts. Each individual part should not exceed the length of 160 characters.

The key field "Fields" defines which user information from the AD is selected. Here the account name MUST stand always in the first place! The name of the key field in the Active Directory should be the same string which should be replaced in the template (in the AD cn - in the template * ~cn~ *).

In the key field "PathSignaturen" is located the path in which the finished generated signatures are stored (this path must already exist).

In the field "SignaturVorlPath" is located the path in which the signature templates are.

IMPORTANT: Each path must be written instead of with \ with \ \.

The key field "VorlagenDateien" contains the file names of the templates (separated through , ). These file names must contain the string "signatur" - it is replaced by the accountname.

Using the Code

The method searchEntry()

The most important part in the application is the method searchEntry() in the class Program. This method searches for entries in the Active Directory. Therefore I use the System.DirectoryServices.

This following part initializes the DirectorySearcher. It also reads the filter string from the osg.ini.

public static void searchEntry()
{
DirectorySearcher ds = new DirectorySearcher();
ds.SearchRoot = new DirectoryEntry();

//read the search filter (osg.ini)
StringBuilder filter = new StringBuilder();
filter.Append(IniFile.a.IniReadValue("DatabaseParams", "SearchFilterpart1").ToString());
filter.Append(IniFile.a.IniReadValue("DatabaseParams", "SearchFilterpart2").ToString());
filter.Append(IniFile.a.IniReadValue("DatabaseParams", "SearchFilterpart3").ToString());
filter.Append(IniFile.a.IniReadValue("DatabaseParams", "SearchFilterpart4").ToString());
filter.Append(IniFile.a.IniReadValue("DatabaseParams", "SearchFilterpart5").ToString());
filter.Append(IniFile.a.IniReadValue("DatabaseParams", "SearchFilterpart6").ToString());

Now the filter string is given to the DirectorySearcher and the PropertyNamesOnly attribute is set to true.

//give the search filter to the Directory searcher
ds.Filter = filter.ToString();

ds.PropertyNamesOnly = true;

To know which information the DirectorySearcher must load, we must load the attributes from the getAttribute() method into the DS.

//read attributes
string[] attributes = getAttribute();
for (int i = 0; i < attributes.Length; i++)
{
//adds the fields which should be read out of the AD
ds.PropertiesToLoad.Add(attributes[i]);
}

Now the ReferralChasing attribute is turned off and the result of the Directory Searcher is saved in the SearchResultCollection src.

//referenced servers shouldn't be read
ds.ReferralChasing = ReferralChasingOption.None;
//start to search
SearchResultCollection src = ds.FindAll();

//shows the number of entries
data.global_count = System.Convert.ToInt32(src.Count);
output.log.WriteLine("Es wurden " + data.global_count + " Einträge gefunden");
Console.WriteLine("Es wurden " + data.global_count + " Einträge gefunden");

We now know how many entries we have found and so we can initialise the global_data array. After that, the attributes are written into the first row.

//initialise the global_data array
data.initData(data.global_attribute.Length, data.global_count + 1);

//writes the Attribute names into the [0] row in the array
for (int i = 0; i < data.global_attribute.Length; i++)
{
data.global_data[i, 0] = data.global_attribute[i];
}

//the counter to write the array
data.global_array_counter = 1;

After all, it writes the entries found in the Active Directory into the global_data array.

//for each entry in the SearchResultCollection
try
{
foreach (SearchResult sr in src)
//writes the LDAP entries into the array
data.globalDataWrite(sr.GetDirectoryEntry());
}
catch (Exception e)
{
Console.WriteLine(e.Message);
output.log.WriteLine(e.Message);
}

src.Dispose();
ds.Dispose();
}

The Method signatur(...)

Another important method is signatur(string vorlage, string vorlagePath). This generates the signatures using the Templates.

The first part looks at which extension the current template has. This is important if there are any characters like ä, ü, ö, ß in the template. So it is no problem if the template is a *.rtf or a *.htm file.

public static void signatur(string vorlage, string vorlagePath)
{
//looks which extension the current template has
string[] typearr = vorlage.Split('.');
string type = typearr[typearr.Length-1];

Now the SreamReader tr is initialised. It reads the template file row by row. The LinkedList list is to save the rows of the template file.

//Streamreader for opening the template
StreamReader tr = new StreamReader(vorlagePath+
	"\\"+vorlage,System.Text.Encoding.UTF7);
//a list in which each row of the template is saved
LinkedList<string> list = new LinkedList<string>();

It reads the template file row by row until the EndOfStream is reached and saves the rows inside the list. Then a temporary list temp is initialised.

//reads the lines of the template
while(!tr.EndOfStream)
{
list.AddLast(tr.ReadLine().ToString());
}
// close the stream
tr.Close();
//temporary list
LinkedList<string> temp; 

Defining the destination paths:

String Path = vorlagePath;
String Path1 = vorlage;

This part is done for each entry is the global_data array. First the string "signatur" in the destination path is replaced by the accountname (data.global_data[0,i]).
Then initialise a StreamWriter wr which writes into the destination file. Now copy the LinkedList list into temp.

//for each entry in data.global_data
for (int i = 1; i < data.global_array_counter; i++)
{
//the path in which the new signature should be written and replaces the signatur 
//by the accountname
Path1 = vorlage;
Path1 = Path1.Replace("signatur", data.global_data[0, i].ToString());
Path = data.PathSignaturen.ToString() + "\\" + Path1;

//StreamWriter th write the signature file
StreamWriter wr = new StreamWriter(Path);
log.WriteLine(Path1 + " wurde erfolgreich erzeugt");
//the list with the rows of the template is copied into the temp list
temp = new LinkedList<string>(list);

And now for each entry in the LinkedList temp. In each row search for the patterns which should be replaced by AD information and replace this:

//do while the temp list is empty
while (temp.Count > 0)
{
//define pivot row
String Zeile = temp.First.Value.ToString(); 
//searches for the fields in the row
for (int p = 0; p < data.global_attribute.Length; p++)
{
try
{
//if there are any (äöüß) in the text code for HTML and RTF
if (type == "htm")
{
//for html
Zeile = Zeile.Replace("÷", "&ouml;");
Zeile = Zeile.Replace("õ", "&auml;");
Zeile = Zeile.Replace("³", "&uuml;");
Zeile = Zeile.Replace("Í", "&Ouml;");
Zeile = Zeile.Replace("-", "&Auml;");
Zeile = Zeile.Replace("_", "&Uuml;");
Zeile = Zeile.Replace("¯", "&szlig;");
}
else if (type == "rtf")
{
//for rtf
Zeile = Zeile.Replace("÷", "\\'f6");
Zeile = Zeile.Replace("õ", "\\'e4");
Zeile = Zeile.Replace("³", "\\'fc");
Zeile = Zeile.Replace("Í", "\\'d6");
Zeile = Zeile.Replace("-", "\\'c4");
Zeile = Zeile.Replace("_", "\\'dc");
Zeile = Zeile.Replace("¯", "\\'df");
}
//define the string to replace
string reg = "*~" + data.global_data[p, 0].ToString() + "~*";
if (data.global_data[p, i].ToString() == null)
{

}
else
{
//replace it
Zeile = Zeile.Replace(reg, data.global_data[p, i].ToString());
}
}
catch(Exception w)
{
string reg = "*~" + data.global_data[p, 0].ToString() + "~*";
Zeile = Zeile.Replace(reg, "");
}
}

After replacing, write the line into the destination file and remove the first entry in the LinkedList temp. Then do it again with the next row.

//Zeile in Signaturdatei schreiben
wr.WriteLine(Zeile);
//Status Counter inc
data.global_state_counter++;
//remove firs element of the temp list
temp.RemoveFirst();

Close the StreamWriter wr and close the file.

}
//show status
data.statusFortschritt(data.global_array_counter, data.global_state_counter);
//close filestream of the signature file
wr.Close(); 
}
}

To read the other code, please download the source code.

A Possible Template

An example for a template is:

Regards

*~title~**~sn~* *~givenname~*
*~physicalDeliveryOfficeName~*


Liebherr-Hydraulikbagger GmbH
*~streetaddress~*
*~postalcode~* *~l~*
Tel.: *~telephonenumber~*
Fax.: *~facsimiletelephonenumber~*
E-Mail: *~mail~*

All the *~anything~* tags are replaced. These should be named the same way like the attribute in the Active Directory.

The application also supports *.html and *.rtf signatures.

Class Diagram

Screenshot - class_data.gif

Screenshot - class_output.gif

Screenshot - class_Program.gif

History

  • Version 1.0 (14.03.2007)

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPL)

About the Author

cute-solutions


Member

Occupation: Web Developer
Location: Germany Germany

Other popular C# articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
  (Refresh) 
-- There are no messages in this forum --

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 24 Aug 2007
Editor: Deeksha Shenoy
Copyright 2007 by cute-solutions
Everything else Copyright © CodeProject, 1999-2009
Web18 | Advertise on the Code Project