Click to See Complete Forum and Search --> : [RESOLVED] Pragmas for different Progam Compilation ?


JonnyPoet
June 26th, 2009, 06:53 AM
Hi friends !
I have made a pogram which runs using office 2003 (word and Excel) mostly but I need to do an additional one for Office 2000 which only will be a few copies.

The amount of methods that change are more o less the opening and closing methods as well as the Save methods.
In the moment I have done two different .cs files one which contains all the office methods for Office 2000 and one which contains the same for office 2000. This are basically two classes which do the word and excel data exchange, so I have two vesions of that classes. all the other program code is the same in both versions. In the moment this are two diffeent PC's one with office 2000 installed and one with office 2003 installed and all what is done in one of the programs needs to be done on the other too.
So I would like to have a vesion whee I can have both office versions in my code and simple setting a pragma which allows me to switch between 'using Excel' and 'using Microsoft.Office.Interrop.Excel' ( and the same for word )
and the code which is different.

Also the question is, if it would be possible to have a sort of pragma depending references sections so I would be able to only set the pragma and would get my Office 2000 version and if PragmaConstant isn't set it would compile fo Office 2003

darwen
June 27th, 2009, 06:19 AM
Preprocessor support in C# is very limited. However even in C++ I wouldn't do what you require using pragmas and #ifdef-s.

I'd write an interface with all the methods you require for office access. Then instansiate different concrete classes, one for office 2000 and the other for office 2003.

e.g.


public interface IOffice
{
void CreateFile(string filename);
}

public class MSOffice2000 : IOffice
{
}

public class MSOffice2003 : IOffice
{
}


If one interface starts getting too large, then you can start breaking things up into different interfaces e.g.


public interface IOfficeTextWriter
{
void WriteText(string text);
}

public interface IOffice
{
IOfficeTextWriter TextWriter { get; }
}


Get the idea ? This is a pretty standard way of doing things in object oriented languages.

It also has the advantage that if you wanted an Office2007 version you just write an additional class.

Providing that all your office needs are fulfilled with your interfaces and that all concrete classes are created from a single concrete class (so you only 'new' an MSOffice2000 or MSOffice2003 class and from that point onwards your code just uses methods in the interface) then this would be my preferred approach.

It also has the nice feature that it's abstracting what you're doing with office, not what office is capable of doing. It could then be modified to address other file types.

If you want an example of such a framework have a look at my C# FTP server (http://www.codeguru.com/Csharp/Csharp/cs_network/sockets/article.php/c7409/) which has a replacable file system object.

Darwen.

MadHatter
June 27th, 2009, 09:14 AM
you can still do conditional compilation using the #if #elif #else #endif preprocessor directives. you would need to define symbols under the build section of the property pages to define which build you'll be building.

you can also define symbols at a code level too:

// OFFICE2000 can also be added to additional symbols in
//your property pages so you don't have to put them on every file
#define OFFICE2000
public class Foo {

#if OFFICE2000
public void Save() { ... }
#elif OFFICE2003
public void Save() { ... }
#else
public void Save() { ... }
#endif
}

JonnyPoet
June 27th, 2009, 04:28 PM
Preprocessor support in C# is very limited. However even in C++ I wouldn't do what you require using pragmas and #ifdef-s.

I'd write an interface with all the methods you require for office access. Then instansiate different concrete classes, one for office 2000 and the other for office 2003.

e.g.


public interface IOffice
{
void CreateFile(string filename);
}

public class MSOffice2000 : IOffice
{
}

public class MSOffice2003 : IOffice
{
}


If one interface starts getting too large, then you can start breaking things up into different interfaces e.g.


public interface IOfficeTextWriter
{
void WriteText(string text);
}

public interface IOffice
{
IOfficeTextWriter TextWriter { get; }
}


Get the idea ? This is a pretty standard way of doing things in object oriented languages.

It also has the advantage that if you wanted an Office2007 version you just write an additional class.

Great idea. So I would do all the needed office stuff in a separated class which allows me to access office and using the interface for my main programs access methods. All the references tothe needed office version then are done in that separated library
and depending if I'm binding my 2000 or my 2003 or 2007 library module I would get the needed result without using any pragmas on ly by binding the needed library to my program. Great idea. I'll do this tomorrow. Thx a lot:wave:

JonnyPoet
June 27th, 2009, 04:36 PM
you can still do conditional compilation using the #if #elif #else #endif preprocessor directives. you would need to define symbols under the build section of the property pages to define which build you'll be building.

you can also define symbols at a code level too:

// OFFICE2000 can also be added to additional symbols in
//your property pages so you don't have to put them on every file
#define OFFICE2000
public class Foo {

#if OFFICE2000
public void Save() { ... }
#elif OFFICE2003
public void Save() { ... }
#else
public void Save() { ... }
#endif
}Thx for that great information too.:D It would solve my program issue per sure and was what I originally asked for.

But in the moment I think darwen for my purposes has pointed me to the easier handling, because this way I would simple do that word and excel stuff in separate library dlls, one for 2000 one for 2003 and maybe one for 2007 and this dlls will adapt and provide all my needed Word and Excel access. Depending on what I'm binding to my program I'll get the needed result and I would nor have to deal with changing references and setting my pragma and the code will be clean, easy to read and reuseability would also be easy. Additional this way I can use my dll's for other programs too.

So thx both and greetings from Vienna

-----edited ----
I used Darwens idea because its famuilar to me to use interfaces and the job is already done. Such easy. I'm just a bit angry about myself that I havn't had that simple idea myself :D