CSE.exe assembly search while compiling - c#

I am using a batch file with the following commands to successfully compile a C# code on the fly, run the resulting exe and destry the exe.
start /wait C:\WINDOWS\Microsoft.NET\Framework\v3.5\csc.exe /out:PostillionOutgoing.exe PostillionOutgoing.cs /reference:AlexPilotti.FTPS.Client.dll
call SetupCI.bat
start /wait PostillionOutgoing.exe
del PostillionOutgoing.exe
It works exactly the way I wanted. File AlexPilotti.FTPS.Client.dll is present in the same folder as the .cs files are.
The assembly AlexPilotti.FTPS.Client.dll is also needed by a lot of other similar applications. My question is that is there any centralised place where I can keep this DLL so that all the above batch scripts will find it ? By this way I wont have to keep a copy of this DLL in all the separate folders.
I dont want to place the DLL in GAC. I tried in system32 folder also but it didnt work.

You can use the /lib command line to specify search folders for references
see msdn docs here http://msdn.microsoft.com/en-us/library/vstudio/s5bac5fx.aspx

As per the documentation, there is no fixed location that the runtime uses when probing for assemblies (i.e. when it looks into directories because it hasn't been able to locate the assembly already).
However, if your assembly is strongly named then you can use a <codeBase> configuration element in your app.config to direct the runtime to any path of your choosing.
If your assembly isn't strongly named and you don't want to use app.config then unfortunately you are out of options.

Related

Change or add a path to external .dll in Visual Studio 2010 using C#

I have written a C# application which uses an external .dll, which is loaded at runtime. The application works fine, if I copy this .dll to the bin directory of my application. Since also other applications use the external .dll I want to have it only once on the system, such that every application uses the same .dll.
So I added the corresponding path to the PATH-Environment variable.
When I delete the .dll from my bin directory and start the application I get a
System.TypeLoadException: Failed to resolve the Type
The way proposed in
Visual Studio: how to set path to dll? does not work
Adding the assembly location to the PATH variable won't make it available to your application because that's not how .NET assembly lookup is performed.
If you want the same assembly to be used by several applications, you'll need to add it to the Global Assembly Cache (GAC). You should note that in order to do that you'll need to sign your assembly. For more information on how to add your assembly to the GAC, you can have a look here.
If it is just your own machine there are a couple of ways if you don't want to use CopyLocal or GAC.
Create a symbolic link to the dll in the bin folder
MKLINK bin\mydll.dll C:\path\to\dlls\mydll.dll
Use the DEVPATH environment variable to specify where assemblies are located
Add the following to the config file (or machine.config if you want a global setting)
<configuration>
<runtime>
<developmentMode developerInstallation="true"/>
</runtime>
</configuration>
And then create the environment variable DEVPATH
SET DEVPATH=C:\path\to\dlls;C:\Path\to\somewhereelse
Just ensure DEVPATH contains at least one valid path. Otherwise all .Net programs will crash on startup with a strange error message.

Why my WPF program cannot run without Visual Studio?

I made a WPF program which uses SQLite. And by using Visual Studio 2012, it generates both Debug and Release version exe file. When I go to Debug or Release directory and run my exe file, e.g. MultiStart.exe, it can run normally.
But if I copy the MultiStart.exe to my Desktop and try to run it, it failed.
By several tests, I found that I also need to copy files MultiStart.exe.config and System.Data.SQLite.dll to my Desktop. And then it can run now.
But why? Do we have better solution so that I can make it run without addition files?
Thanks!
Why my WPF program cannot run without Visual Studio?
The question title is not really accurate since it's not really related Visual Studio. MultiStart.exe is dependent on configuration (MultiStart.exe.config) as well as other assemblies (System.Data.SQLite.dll). Without these dependencies the application cannot run (because that is how .NET works).
WPF doesn't necessarily need a config file to run so the question is what is in your config file that the application needs. It might be possible to move this configuration information into the code (e.g. connection string) and remove the app.config but then the values will be hard coded in the application.
In terms of dependent assemblies, instead of deploying them it is possible to embed them as resources and then use the AppDomain.AssemblyResolve Event to read the assembly from a resource (see Embedding assemblies inside another assembly for an example).
Another approach instead of embedding assemblies as resources is to merge them into one assembly. ILMerge is a popular choice for merging assemblies but I read that it can have issues with WPF assemblies (not sure if that applies to you). See Merging dlls into a single .exe with wpf for some other ideas for merging assemblies with WPF.
Note that setting PATH variables does not work because .NET does not use the PATH for resolving assemblies -- see How the Runtime Locates Assemblies for the details.
Another, option instead of copying the MultiStart.exe to the desktop is to use a shortcut on the desktop that links to the appropriate directory. Perhaps that is a simpler solution
You can also use ILMerge to merge all dependencies into single .exe file to simplify distributiuon of your application.
More detaiils on ILMerge can be found here: ILMerge on CodeProject
Example of usage: ilmerge /target:winexe /out:YourDestinationApp.exe
YourCurrentProgram.exe System.Data.SQLite.dll
Better solution that i used to do with my windows form apps is, Copy the entire folder, which contains supporting files. place it where you want. then create a shortcut of your .exe on your desktop. That always worked for me.
Because you are missing some dependency. You can open your config file and set the dependency...but I wouldn't recommend you to change config file manually.
You can also copy the dependent dll in system32 folder. ..but its only a trick because exe first search dlls in current folder than system 32 folder.
Because you're missing things from your PATH. Visual Studio is probably set to copy DLLs to the target directory on build.
You're almost certainly pulling in external libraries. Some of these are part of .NET, while others are packaged in libraries in specific folders. When you start your exe, it looks in your PATH and the current folder for everything (which includes all DLLs Visual Studio copied).
When you moved the exe to the desktop, suddenly it had no idea where those DLLs are. You haven't specifically added them to your PATH, and they are no longer in the current folder. This is why copying those DLLs to your desktop magically made them work.
Unless you stop use SQLite, there is not a way for you to not need that DLL (there are lots of ways to package/reference it though).

Unable to load dll: Module cannot be found

I am using a managed DLL that referencing an unmanaged dll.
I added the unmanaged dll under /External/foo/ directory, and i changed the "Copy To Output Directory" to always.
The problem is that the dlls are copied to the outputDir/External/foo dir and when the runtime tries to find it, it fails with this error: "Unable to load dll: Module cannot be found"
When i copy it directly to the output dir, everything works well.
How can i set the project runtime to search in the sub directories of the outut dir?
Thanks!
You don't want to do this, DLL Search Hell is something you want to avoid. Windows is pretty inflexible about where it looks for DLLs. Rightfully so, DLL Hell is nothing to mess with. The only good place for unmanaged DLLs is in the same directory as your EXE. If you don't want to store the DLLs in the project directory, so copying them is very easy, then you are going to need a post-build event that uses xcopy.exe to copy the DLL to the output directory.
The alternatives are not pretty. If this DLL is implicitly loaded then the only option is to use an installer to add the directory to the system's PATH environment variable. This is a Really Bad idea, way too easy for your program to break. If it is loaded explicitly, either with LoadLibrary or a pinvoke declaration then you have more attractive options since you can alter the search path in your Main() method before the DLL is needed. Either append the path to your local copy of the PATH environment variable by using Environment.SetEnvironmentVariable() or pinvoke SetDllDirectory(). Do beware that you have a deployment problem as well, somebody is going to have to create this subdirectory and copy the DLL there on the user's machine. All great reasons to not do this.
This is something we did in our last project. Write a batch file which copies this unmanaged dll to the output directory. Call the batch file every time the program compiles. You can control the calling of batch file also using a Config key. So it runs based on the config key value true/false. i hope this helps

Install app which uses .dll with IExpress Wizard

I have two applications which will be installed by a single executable. The problem I'm facing is that one of them uses a .dll. And whenever the IExpress package tries to run the first executable it says that the .dll could not be found, even tough I added the .dll inside and outside the package.
There is any way to make it work with IExpress, which has the required characteristics?
There is any alternative to my problem, as a similar software, for instance?
This sounds vaguely similar to this question:
Iexpress is extracting to %temp% folder... How do I prevent this?
As I mentioned in my answer, check: (1) is long file name (LFN) support enabled? and (2) is the .dll actually in the archive?
If checking those things doesn't resolve it, I would use Process Monitor to see which directories the executable is searching to locate the .dll file. It should ideally be looking in the extraction directory (eg %temp%\IXP000.TMP), since that's the current directory when the executable is running.
Of course there are several other utilities that do what IExpress does that you might try instead: 7-Zip, Inno Setup, NSIS, WinRAR, WiX – just to name a few.

How do I avoid copying 3rd party C++ dlls?

I have a solution with a C++ project and a c# project, which calls methods from the first one using Interop.
As I want to avoid any hard-coded path, I found a way to set the C++ dll's path in the app.config.
My problem is, that my C++ dll depends on other dlls, which I always have to copy into my bin/Release and bin/Debug folder. How can I avoid this?
It would be nice if I could set the path to the 3rd party dlls in the app.config.
I found this
<probing privatePath="bin\DLLs" />
but it seems to work for application subdirectories only.
Don't hard code location for the DLLs. Put the directories into the %PATH% variable. Assuming Windows as environment read Search path for loading DLLs.
EDIT:
%PATH% is an environment variable, so you can set it with Environment.SetEnvironmentVariables. I would read privatePath from the configuration file, and use the given method to append it to %PATH%. Reading from the configuration file could be done with the ConfigurationManager class.
I will Write folloing command in your post build event (So you need not to do the manual work)
xcopy /s c:\source\your_dll_folder c:\your_target_folder\bin\debug
xcopy /s c:\source\your_dll_folder c:\your_target_folder\bin\Release
Here is post build event location properties of your project

Categories

Resources