5,699,997 members and growing! (16,789 online)
Email Password   helpLost your password?
Languages » C# » General     Beginner

Outlook signatures out of Active Directory information

By cute-solutions

generating Outlook signatures automatically using information of the Active Directory
C# 2.0, C#, Windows, .NET, .NET 2.0VS2005, Visual Studio, Dev

Posted: 13 Mar 2007
Updated: 24 Aug 2007
Views: 11,958
Bookmarked: 10 times
Announcements
Loading...



Search    
Advanced Search
Sitemap
5 votes for this Article.
Popularity: 2.15 Rating: 3.07 out of 5
0 votes, 0.0%
1
1 vote, 20.0%
2
2 votes, 40.0%
3
2 votes, 40.0%
4
0 votes, 0.0%
5
Note: This is an unedited contribution. If this article is inappropriate, needs attention or copies someone else's work without reference then please Report This Article

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 Programms 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 schould be replaces in the template (in the AD cn - in the template * ~cn~ *).

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

In the field "SignaturVorlPath" is located the path in that 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 entrys in the Active Directory. Therefore i uses the System.DirectoryServices.

This following part initialises the DirectorySearcher. It also reads the filtersring 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 filterstring is given ti the DirectorySearcher. And the PropertyNamesOnly attribute is set true.

//give the search filter to the Directory searcher

ds.Filter = filter.ToString();

ds.PropertyNamesOnly = true;

To know which informatioan 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 schould be reded 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 entrys

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 much entrys we have fount and so we can initialise the global_data array. After that the attributes are written into the first row.

//initalise 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 entrys 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 entrys 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(...)

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


The first part looks 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 extention the current templte 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+"file:///">\\"+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 zhe 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 pathes.

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 accoutname (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 schould 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("÷", "file://%27f6/">\\'f6");

Zeile = Zeile.Replace("õ", "file://%27e4/">\\'e4");

Zeile = Zeile.Replace("³", "file://%27fc/">\\'fc");

Zeile = Zeile.Replace("Í", "file://%27d6/">\\'d6");

Zeile = Zeile.Replace("-", "file://%27c4/">\\'c4");

Zeile = Zeile.Replace("_", "file://%27dc/">\\'dc");

Zeile = Zeile.Replace("¯", "file://%27df/">\\'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 withe 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 th e signature file

wr.Close(); 
}
}

To read the other code please download the Download outlooksig_src.zip

A possible Template

An exemple 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 has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

cute-solutions



Occupation: Web Developer
Location: Germany Germany

Other popular C# articles:

Article Top
Sign Up to vote for this article
You must Sign In to use this message board.
FAQ FAQ Noise ToleranceSearch Search Messages 
 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:
Copyright 2007 by cute-solutions
Everything else Copyright © CodeProject, 1999-2008
Web11 | Advertise on the Code Project