2

I have a project with a reference that may or may not exist. I have code that uses that reference and I'd like to compile it only if the assembly exists. I'm thinking something along the lines of:

#if ASSEMBLY_EXISTS
    AssemblyClass.DoSomething();
#endif

I could put a #define at the top and comment/uncomment as needed, but I'd prefer if it could just somehow know if it's there without my manual intervention, which leads me to believe that #if won't work for this situation. Is there another way to conditionally compile based on whether an assembly exists?

TTT
  • 22,611
  • 8
  • 63
  • 69
  • Try, Catch, Finally? I assume you would get an object ref. not set to an instance of an object exception so have a specific catch block to handle that etc. Not a very efficient approach but I don't know that this code is required to be fast. – j-u-s-t-i-n Dec 03 '15 at 16:58
  • @stuartd, isn't that link checking at runtime?? – TTT Dec 03 '15 at 16:59
  • There is no precompilation symbol that you can use for the existence of a referenced assembly. – Ron Beyer Dec 03 '15 at 16:59
  • @TTT oops, yes it is.. – stuartd Dec 03 '15 at 17:00
  • @j-u-s-t-i-n - the code won't compile if the assembly isn't there. – TTT Dec 03 '15 at 17:00
  • @RonBeyer - that's what I figured. So is there another way? – TTT Dec 03 '15 at 17:01
  • You could define your own symbol and use it, there just isn't anything built-in. There isn't a way to conditionally compile code based on references without doing a little bit of leg-work. You can also use [`ConditionalAttribute`](https://msdn.microsoft.com/en-us/library/system.diagnostics.conditionalattribute(v=vs.110).aspx) but it still requires you to define the symbol yourself, personally I'd use the `#if/#endif` because I'm not sure all compilers are required to abide by the attribute. – Ron Beyer Dec 03 '15 at 17:02
  • By the way, symbols `#define`d in a file are only valid for that file, you'd have to define them in every file in the project that uses the symbol. For this you can define global symbols in the properties which is a lot easier to maintain. – Ron Beyer Dec 03 '15 at 17:05
  • As an alternative you could load assembly type dynamically using Type.GetType( "TypeName,DllName" ) and if exists call its methods using reflection. – dmitry1100 Aug 20 '17 at 08:14
  • @GuidC0DE - that would functionally work, however, this question is specifically about compilation time checking rather than runtime. – TTT Aug 21 '17 at 13:05

2 Answers2

7

Maybe do it with a condition inside MSBUILD;

It would look something like it

<PropertyGroup>
     <DefineConstants Condition="Exists('my.dll') ">$(DefineConstants);DLLEXISTS</DefineConstants>
</PropertyGroup>

and should go quite far down in your .csproj file.

This reads, roughly, as "redefine the constants by appending DLLEXISTS, if my.dll exists"

Now you should be able to do

#if DLLEXISTS
    // your stuff here
#endif

You might need to fiddle around with the EXISTS expression to find an appropriate relative path.

Steve Cooper
  • 20,542
  • 15
  • 71
  • 88
  • This worked perfectly. For the Exists directory, since the reference is included in the project I just copied its path exactly. – TTT Dec 03 '15 at 18:50
  • Works good! MsBuild/.csproj file can be accessed by unloading project and right clicking it then click edit... http://doc.postsharp.net/configuration-msbuild – Zunair Jul 29 '16 at 04:31
1

No you cannot do this. You cannot define the result of a conditional compilation symbol at compile time.

If you want to get fancy you could write a new program which detects the missing assembly and modifies your source. You can then execute this program in the Pre-build event of your project.

The modification of the source could simply be the addition or removal of your suggested #define at the top of the source files.

CathalMF
  • 9,705
  • 6
  • 70
  • 106
  • 1
    I like your "get fancy" idea. This would obviously work and seems like a good fallback if there isn't an easier way. – TTT Dec 03 '15 at 17:24