Error copying files from one project to another - c#

I've created a *.dll file in C++ to be used in a C# program. The native DLL resides in my managed DLL wrapper. From there, I physically copied my the native DLLs (NativeDll.dll for debug and release) into my C# console application's debug and release folders. When I run the C# program, it runs as expected creating objects and displaying values.
The problem comes when I changed a default value of a variable in my native library (C++). When I run the program again, the changes to the variable (the with of a box) still holds the last value. From what I've searched for, I've found that I could copy the dll from one project into my C# project by this means in the project's Build Events/Post-build event command line:
copy "$(SolutionDir)ManagedDll\bin\$(Configuration)\NativeDll.dll"
"$(SolutionDir)TestDLLConsole\bin\$(Configuration)"
When I run the program again, I get an error stating "exited with code 9009."
The only way around this is to manually re-copy my NativeDll.dll files and overwrite the existing one whenever I make changes.
The 4 projects I have in my solution are with next build depending on the previous:
NativeLib (static library)
NativeDll
ManagedDll
TestDLLConsole (where I test to see if the dll works).
How do I get the Dlls to be copied into/overwritten every TestDLLConsole is compiled?

Maybe you are trying to overwrite the last dll that you copy with the last post build event. You can try:
copy /Y "$(SolutionDir)ManagedDll\bin\$(Configuration)\NativeDll.dll"
"$(SolutionDir)TestDLLConsole\bin\$(Configuration)"
The /Y parameter suppresses prompting to confirm you want to overwrite an existing destination file.

Related

Visual studio: Build action=Content causes error for dll file

I am trying to build a project in C# which uses some unmanaged dll files (MSVCRT.DLL, DFORRT.DLL, ...). There is no direct reference to the MSVCRT.DLL file in the project(this file is referenced by another dll and not directly by my program)
I want this dlls to be copied to bin directory. if i set build action to Content i get this error on run time:
The procedure entry point _wcstoui64 could not be located in dynamic link library msvcrt.dll.
Which is weird. I cant use other build actions because i want my dlls to be published too(Build action=None wont cause any error but doesn't let me to publish my dlls)
If i completely remove all references to all the dlls and treat them like data files, or pictures(files that are not used in code but should be copied to the output) again i get the same error.
What is causing the problem? how can i publish my dlls?

Can I require (the simpler way) to copy the resultant config-file of my dll instead of post-build event using?

My solution contains two projects. One of them is console application, but second is dll. Each of them has own output directory. Both projects contains App.config files. Their names in the output directories are MyConsoleApp.exe.config and MyLibrary.dll.config. Console application has the reference to the second project (its Copy Local property is True).
But compilation result of console application not contains the config-file of my dll in the console application output directory. Therefore I copy it through the post-build event of my console application.
Can I require (the simpler way) to copy the resultant config-file of my dll instead of post-build event using?
No, there is not. Application configuration files are not seen as a dependency of another project. Hence, they are not copied.
I am not sure if you really need that file, but if you do, you could keep your current post-build action. Another option would be to create it from your application if it doesn't exist and default the setting values from there.

How do i add dll file to my project forever? [duplicate]

This question already exists:
Embed .net dll in c# .exe [duplicate]
Closed 9 years ago.
I have this code in constructor:
InitializeComponent();
textBox3_text_valid = 0;
label8.Visible = false;
label8.Visible = false;
Logger.exist();
I added to my project a reference dll OpenHardwareMonitor.dll
The problem is that the dll is in my debug directory.
But when i Rebuild Solution and Save All
And then send the project exe file only to my brother or running this program in my pc after i deleted the debug directory im getting error that the OpenHardwareMonitor.dll is missing.
In the properties in my project under reference on openhardwaremonitor.dll i see:
Aliases : Global
Copy Local : True
Ember Interop : False
How can i add the dll to the project to the exe file or something so i wont need to send it to my brother the dll ?
And if i must send my brother the dll file where should he put it ? He dosent have the Debug directory.
The problem is that the dll is in my debug directory.
Don't do that then. I would suggest you create a lib directory or something like that, and add a reference to the library from there. By default, that will copy it when you build (i.e. Copy Local will be true).
In general, you should never be manually copying things into your output directories - you should assume they can be wiped at any time by the build process. Instead, put things into directories which you "own" and let the build process copy them.
Also, where possible you could use nuget for third party libraries - that makes managing them somewhat simpler.
you should create a folder in your solution or your project , then copy your dll into this folder. right click on your project and select properties, go to the reference paths tab, select path of this folder and then click add folder button.

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

msbuild and visual studio project configuration problem

I have a solution containing a lot of projects and installer projects. One project uses a third party package. The package comes with a native DLL and a .net wrapper DLL. In order for the code to work, the .net wrapper DLL needs to find the native DLL in runtime. But the code never directly refers to the native DLL in compile time (the code talks to .net wrapper DLL in compile time).
Now I have to choose proper way to deploy the native DLL, during compile time on a programmer's machine and during installing time on a user machine.
Basically I have two options, either to put the native DLL to Windows System folder or to put the native DLL in the local folder containing the exe file.
To put the native DLL to system folder, I need a post-build script to xcopy the file to the directory after building the solution. I also need to create a System Folder output in installer project for installer to work on a client machine. I don't know whether copying files to system folder is a good idea or not. For this solution, every time someone (else in the big team) creates a new installer, he or she has to remember to create System Folder output and add the native DLL under the configuration otherwise his or her installer will not install a workable piece of software on a user machine.
To put the native DLL to local folder, I have the following two ways:
1. Use a post-build script. This solution, I have to find out every executable project in my big solution that has a reference to the project using the native DLL and link the post-build script to every such executable project. In the future, when someone (else in the big team) creates a new executable project with the same kind, he or she has to remember to link the same post-build script otherwise the executable wouldn't be able to find the native DLL. This is what I really don't like, people tend to forget.
I can add the native DLL to the project that uses it and in the DLL's property configuration, set it to "Copy If Newer". This way, the native DLL will be copied to the project's output folder and to every project that refers to the project. This way, I don't have to remember anything. The native DLL will be copied to the local folder of every dependent project.
This seems a good solution. But msbuild command seems not being able to handle this situation cleverly. For example, suppose project A directly uses native DLL and I add the native DLL to project A. Project B refers to project A and project C refers to project B and project A. if using msbuild to build the solution, the native DLL will be copied repeatedly to the output folder of project C 3 times, one for reference to project A, one for reference to project B, one for reference of project B to project A. In my big solution, towards the end of the dependency link, the native DLL will be copied exponentially many times to the same output folder, regardless of the "Copy If Newer" setting. This takes up tremendous amount of time to build the whole solution.
Now I totally have no idea what is the best solution for my situation. For anyone who uses native DLLs, how do you deploy the DLL so 1. it is convenient for both deploying on developer machine (compile and run) and on user machine (install and run), 2. developers in big team don't have to remember anything when he or she adds new project/installer to the solution, 3. smart enough build manner that avoids unnecessary redundant actions. Thank you for any hint, tutorial on Web, suggestion or clever teach in advance.
What we've done in general is to make all \bin directories into symlinks to a common directory. This avoids all the transitive copies that VS does for all references, and can speed up a clean build of a large solution up to a factor of 10-20.
We use the following powershell script to set up the symlinks:
param($linkTarget={throw "Link target must be specified"}, $rootDir=".")
ls $rootDir -Recurse -Include *.csproj | % { $_.DirectoryName } | % { Join-Path $_ -ChildPath "bin" } | % {
Write-Host "Creating link from $_ to $linkTarget"
if (Test-Path $_)
{
Remove-Item -Force -Recurse $_
cmd /c rd $_
}
cmd /c mklink /D $_ $linkTarget
}
Symbolic links require Vista or Win7; if on XP, junctions can be used instead by replacing the call to mklink with a call to junction.exe.
By default, this must be run as administrator.
For starters, avoid using post build events unless there's no other choice. Post build events unmanaged nature tend to fail builds and have low maintainability.
"Copy If Newer" flag may have lame effectiveness, but it will assure you that: 1) the required dependencies will be copied to output 2) it won't fail the build 3) has virtually no maintainability.
Secondly, you can reduce redundant copying by setting only the last project in the build chain with the "Copy If Newer" flag, e.g.: project A directly refers the DLL but does not copy it to output, project C refers indirectly to project A through project B, and has dummy reference to the DLL with "Copy If Newer" enabled.
Steve,
I add native dlls to my projects all the time and I haven't had a problem with adding the dll as content to the project. You can actually add the necessary dll as a project link rather than actual content. This way, the dll will not be copied into the project folder as well as into the target folder.
Here's an explanation from devx:
To add a shared file, open the dialog
to select an existing file with the
Project | Add Existing Item menu item
and select the file you want to
include. Then, instead of clicking the
Open button, click the arrow on the
left of that button, and click Link
File from the list that drops down.
This way you link to the original
file, not to a local copy of it.
Do you build all the projects into a common solution target directory, i.e. ..\bin\debug? This may curtail unnecessary copies.
Adding the project link to the dll is definitely easier to maintain than copying in a build event.
There must be something "dodgy" in your project setup (like a circular reference) to cause an infinite copy loop - but finding it could be tricky and/or time consuming.
Two things I would try:
Turn off the "newer" flag and see if it has any effect on your problem. Copying a single dll is unlikely to impact build times very much, and problems can come about with this option when file datestamps get confused. (I wouldn't expect this to cause repeated copy attempts though)
Try using a post-build event with xcopy to copy the file instead of relying on the automatic system. Then you'll be in full control of a simple system instead of wondering why a clever system doesn't work.
Personally, I'd treat the native DLL and assembly DLL as one entity. Adding a Link to the file is one way. Alternatively, you could have a separate main build script that massages your project and installer.
For instance, I have a Library.msbuild file that runs a MsBuild task of a source .csproj as my Build target. My Deploy target uses a copy task to copy the dlls from source\library\LibraryName\bin\Configuration*.dll to library\LibraryName. I have one library location for all the source files I need to build and the other is all the bins that my main project references.
Here's the entire Library.msbuild script:`
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Release</Configuration>
<ProjectDirectory>library\AspNetMvc\DataAnnotationsModelBinder\src</ProjectDirectory>
<LibraryDirectory>..\library\AspNetMvc</LibraryDirectory>
</PropertyGroup>
<ItemGroup>
<CompiledBinaries Include="$(ProjectDirectory)\bin\$(Configuration)\*.dll" />
</ItemGroup>
<Target Name="Clean">
<MSBuild Projects="$(ProjectDirectory)\Microsoft.Web.Mvc.DataAnnotations.csproj"
Targets="Clean" Properties="Configuration=$(Configuration)" />
</Target>
<Target Name="PreBuild" DependsOnTargets="Clean">
</Target>
<Target Name="Build" DependsOnTargets="PreBuild">
<MSBuild Projects="$(ProjectDirectory)\Microsoft.Web.Mvc.DataAnnotations.csproj"
Targets="Build" Properties="Configuration=$(Configuration)" />
</Target>
<Target Name="Deploy" DependsOnTargets="Build">
<Copy SourceFiles="#(CompiledBinaries)" DestinationFolder="$(LibraryDirectory)"/>
</Target>
</Project>
`
In your instance, I would move the Deploy copy task to PreBuild or remove it entirely to depend on the Add Existing method copying the dll. The goal is that when you run\debug your project that everything will be bin relative. You could even have bin\win32 if you're separating native from .NET DLLs.
Every build is now done from a .build.cmd batch file (1-click build) that is simply this: C:\Windows\Microsoft.NET\Framework\v3.5\MSBuild Library.msbuild /t:Deploy. You're free to add more targets in the chain like test after build but before deploy.
If you are using WiX or any other type of installer, you should be able to use relative paths for the files themselves. I have a top-level staging\ directory that I have no problem getting into from source\install\ (..\..\staging\ icky, yes but works). Worst case you can place your staging directory somewhere inside the install path.
In most instances you can get away with not having to abstract MsBuild further than your .csproj or .wixproj files. There's a very low ceiling that Before/AfterBuild runs into but I find myself opting for this approach in almost every situation now.
See this post: http://blog.alexyakunin.com/2009/09/making-msbuild-visual-studio-to.html
It explains how to automatize copying of N-th level dependencies into Bin folder.
If you have some assembly, that isn't referenced even indirectly, you can create another one (e.g. MyProject.ThirdPartyMagnet), reference this assembly from this project and reference MyProject.ThirdPartyMagnet from the project you need to copy all the assemblies to.

Categories

Resources