Is it a bad practice to reference an exe file in C# project

Yes, this can be seen as a bad practice for the following reasons:

  • Bad Project Architecture
    If you need to call some logic from an .exe, then that logic is incorrectly placed there. Instead, you should put it in a separate dll and reference that same .dll from both the executable you reference currently, and the application that references the executable. As suggested in comments below, extracting the logic into a library can help you avoid some CPU architecture limitations, which I will describe in my next point, as the library can be built to target any CPU.

  • Architecture Limitations
    The referenced executable might have been built to address optimally 32 bit or 64 bit machines, or even specific CPUs (like Itanium). A library can be built without these specifications1 in order to be cross-CPU-compatible, and thus be referenced by any project later. If you reference an executable with specific architecture settings, you should use compatible settings to the referencing project. That I consider a limitation, as you would be unable to distribute the final product to certain platforms.

  • Making Unit-Testing Difficult.
    As hinted by Abel in the comments, your unit tests will go into their own DLL and they would need to reference the executable as well. It could be hard to test it if you do not expose some internal methods/fields using the InternalsVisibleTo attribute, or use reflection (which is the slow alternative) to check and assert some non-publicly visible state of your objects. The executables may not be build with the InternalsVisibleTo attribute set, and if you fallback to reflection, you could encounter .NET security issues preventing you to reflect members of the executable (because the test suite was executed within a more restrictive setup, for instance).

    You will also encounter the architecture limitations mentioned above, which will result in using the same architecture for your unit tests. It could be a problem if your test suites are executed on a remote machine, as part of an automated build (such as in TravisCI, Bamboo, TeamCity and etc). The CI agent must then comply with the CPU architecture of the executable and the test suite. If there is no suitable agents, no tests could be ran. In addition, if you are using a public CI platform for building your application and executing the tests, this could count as distribution of the executable in legal sense. You might well get into violating the executable's license -- see the next section for more details.

  • Potential Licensing Issues
    You should carefully distribute your application. If the referenced executable needs additional licenses or fees in order to be used, you will have to enforce the users to accept that executable's license alongside the one of your application (and pay for it if needed), otherwise you risk of making an illegal distribution of it with your software. This also implies that you have the right to reference the executable in the first place.

  • Unknown Consequences
    The executable will be copied within the bin folder and installed alongside your application. There is no telling what could happen if someone browses the bin folder and executes it. There are a few problems with that:

    • The executable crashes, or misbehaves because of improper input. Usually this happens if it does not have any GUI (for instance if a command-line program is double-clicked by user it will not get any input in the form of command-line arguments and thus crash, or misbehave).

    • The executable is not intended to be used by the owner of your program, as that would legally or logically contradict to what your software does.

Yet, there are some cases where referencing an executable can be justified, but those are rare enough:

  • The executable comes from a 3rd party, and no library with the same functionality exists, and there is no other way to link to that functionality. It also might be explicit requirement for your project established by your employer or client.
  • The executable is written in another language and you need to communicate with it via interop.

As long as the latter do not apply to you, and especially if you develop the executable that is referenced yourself, I would definitely recommend to extract the needed logic to a separate library.


1 In fact you can also build an executable to target any CPU, as mentioned by Dominic Kexel's comment. The opposite is also possible - to build a library for specific CPU, but it is less common, as the executable is usually the one being tailored to the hardware. So, to clarify my points, I had in mind referencing a 3rd party executable, or one that cannot be rebuilt for other reasons, and that executable is already optimized for some specific architecture. If you can rebuild and change that executables' targeted CPU, then you can definitely extract the needed logic into a dll.


If you are including an executable file as a resource in your project, then I suppose it's no big deal if it solves your problem and works (although in theory, it would seem more correct to extract common logic out into a separate .dll which could be used in several projects).

However: You might want to include that .exe as an embedded resource, so that it is not visible directly in the output directory when you build your project:

Right click the project node and select Add > Existing Item and find the .exe file. Now right click it in the Solution Explorer, select properties and set Build Action to Embedded Resource.

The file will be "baked into" your own .dll or .exe or whatever you are building, instead of simply be copied to your output directory.


.NET DLL or EXE, both are assemblies, you could use either exe or dll by referencing them. There is no problem in shipping exe with your code, until unless you don't want to get this exe executed separately.

Tags:

C#

.Net