Organizing Dependencies - visual-studio

I'm trying to organize my unmanaged .dll dependencies in my Visual Studio solution but unless the DLLs are strewn about the top level of my solution they do not get built into the application's directory and then the application fails to run. I have done a lot of Googling on the subject and there seems to be a solution in the form of an app.config setting:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<runtime>
<assemblybinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatepath="lib" />
</assemblybinding>
</runtime>
</configuration>
I have a folder in my solution called "lib" and Copy Local is set to true for all files in the folder but the application is still unable to run. How can I keep my Visual Studio solution organized without breaking my application?

The only way I have found to solve this issue is through windows .bat files.
If there is a way to encode extra search paths into an unmanaged executable, I would like to know!
Here is an example of what I do:
SET PATH=$~dp0plugins\MY_PLUGIN\Debug;%PATH%
vcvars32.bat
devenv build\MY_PROJECT.sln
The first line adds the path of where I want visual studio to find my dll's in.
The second line ensures that the 'right' visual studio will open up. IE: if I have my environment set for VS2010, I dont want VS2012 to open up by default.
The last line invokes the IDE to open up my sln file.
The visual studio that opens up now has a path to the Debug folder of one of my plugins. When I debug my application, the correct dll will be found, loaded, and debugged with no issue - I verify this under the Debug->Windows->Modules panel.
This only works for the Debug configuration. If I want to run the release configuration, I change the .bat file to say 'Release', close Visual Studio and re-run the .bat file.
I apply this same pattern to running my executable. Set up the environment of where I want my dll's to come from and then execute my executable:
SET PATH=$~dp0plugins\Debug;%PATH%
... Repeat for other dll locations
"%~dp0Debug\MY_EXECUTABLE.exe" %*
SS64 is an invaluable resource to figure out what you can do in .bat files

Related

How do I compile a single source file within an MSVC project from the command line?

I'm about to start doing some benchmarking/testing of our builds, and I'd like to drive the whole thing from a command line. I am aware of DevEnv but am not convinced it can do what I want.
If I could have a single file built within a single project, I'd be happy.
Can this be done?
The magical incantation is as follows. Note that this has only been tested with VS 2010 - I have heard this is the first version of Visual Studio with this capability:
The Incantation
<msbuild> <project> <settings> <file>
Where
msbuild is a path to MSBuild.exe. Usually this should be set up for you by the VS2010 bat file so the right one will end up in your PATH, but if not I found one at C:\Windows\Microsoft.NET\Framework64\v4.0.30319\msbuild.exe
project is the path to the vcxproj file within which your source file resides.
settings include the following:
/p:Configuration="Debug" // or whatever your Configuration is
/p:Platform=x64 // or x86
/t:ClCompile // to specify specifically you're looking to compile the file
file is actually another setting:
/p:SelectedFiles="path_to_file"
Notes
For <project> I had to specify a project (vcxproj) file instead of a solution (sln) file. The sln I would have used has multiple projects within it, so there would have been extra work to go that route anyhow (if it can even be done).
For the /p:Platform=x64 setting, there are several environment variables that pivot on what platform you are targeting (x64 v. x86) so make sure you set those up properly via Visual Studio's vcvarsall.bat.
Regarding path_to_file in the SelectedFiles parameter, this path must be the path as specified in the project file. If the path does not match the path used in the project file to reference the source, it doesn't seem to work.

Visual Studio: DLL locations for release

I have a project that I am working on that references a "Common Library (DLL)". In the DevEnv it works fine, however if I build and try to organize my files it doesn't work. Basically if I have things setup like so:
C:\Program Files\MyApp\MyApp.exe
C:\Program Files\MyApp\Common\WPF Commons.dll
C:\Program Files\MyApp\Modules\SomeModule.dll
etc
MyApp.exe doesn't work. It tries to look only in the current directory for the DLL files. So how do I set it up in Visual Studio so that when I build the application knows to look for the DLLs in those other folders?
Oh, and I realize that it does work in Dev because all the DLLs are put in the same folder. I don't want to do that for release though :-/
What you need to do is add a private probing path into the application configuration file. This tells the CLR which directories to look in for extra assemblies.
http://msdn.microsoft.com/en-us/library/823z9h8w.aspx
Sample app.config
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="Common;Modules"/>
</assemblyBinding>
</runtime>
</configuration>

Anyone else notice that $(SolutionDir) resolves to ProjectDir when loading Wix projects into Vs2010?

I'm using Vs2010 and Wix 3.6.0917.0, for the record. I use the $(SolutionDir) property quite a bit in my .wixproj file, since I only ever build the installer as part of a solution build or as part of a team build, and never by itself. However, while building from the command line works just fine (both from cmd on the desktop and when building on build agents), when I attempt to reload the .wixproj file into the IDE, I get errors because all the $(SolutionDir) variables are resolving to the project directory, not the solution directory. Consider:
C:\workspace\projectCollection\teamProject\branch\solution.sln
C:\workspace\projectCollection\teamProject\branch\source\installer\installer.wixproj
and assume a shared custom targets file:
C:\workspace\projectCollection\teamProject\branch\build\shared.targets
which is referenced inside installer.wixproj with:
<Import Project="$(SolutionDir)build\shared.targets">
Command line builds work fine...
C:\workspace\projectCollection\teamProject\branch\> MSBuild /t:build /property:Platform=x64;Configuration=Debug solution.sln
0 Errors
0 Warnings
Build succeeded!
But load into vs2010 and you see...
The imported project
"C:\workspace\projectCollection\teamProject\branch\source\installer\build\shared.targets" was not found.
Confirm that the path in the <Import> declaration is correct, and that the file exists on disk.
C:\workspace\projectCollection\teamProject\branch\source\installer\installer.wixproj
You can see here that the resolved result of $(SolutionDir)build\shared.targets is getting the project directory and not the solution directory. What gives?
My guess would be that $(SolutionDir) resolves to nothing when the wixproj is being loaded into VS2010. In this case the imported file becomes "build\shared.targets". Since the path is relative it is assumed to be relative to the project directory. Using ".." or some other path could get you around the problem.
I verified this failed with WiX 3.5.2222.0 in VS2010. A C# console application project (csproj) worked as expected.
Have you filed a bug against WiX for this?
I looked at the WiX vs2010 addin code a little bit and the Solution properties are only created when doing a build and not when the project is loaded.

VSTS 2010 SGEN : error : Could not load file or assembly (Exception from HRESULT: 0x80131515)

I am experiencing a strange issue with VS2010. We use TFS to build our API dlls and we used to reference them in our projects usign a mapped network drive that was fully trusted. We have been working like that for at least two years and everything worked perfectly.
Today, I converted a webapp to vs2010 and when I compile it in Release, it's giving me:
SGEN : error : Could not load file or
assembly 'file:///L:\Api\Release
API_20100521.1\Release\CS.API.Exceptions.dll' or one of its dependencies. Operation
is not supported. (Exception from
HRESULT: 0x80131515)
The strange thing is that it's working when it's under the Debug profile...
I tried adding the
<runtime>
<loadFromRemoteSources enabled="true" />
</runtime>
into app.config and still no luck (See http://social.msdn.microsoft.com/Forums/en/msbuild/thread/d12f6301-85bf-4b9e-8e34-a06398a60df0 and http://msdn.microsoft.com/en-us/library/dd409252(VS.100).aspx)
I am pretty sure that this issue is from visual studio or msbuild, as our code won't run from a network share when in prod because all the referenced dll's are copied into the bin folder.
If anyone has an solution (or just an idea for a search path) please let me know !
Edit : It turns out that it was working in Debug mode because generation of serialisation assemblies was turned Off. As the title say, it's really a SGEN problem since it is this utility that says that the path is not trusted...
I was able to fix this error by finding the assembly DLL in Windows Explorer, right clicking, choosing Properties, and then pressing the "unblock" button. The DLL has a stream that is marking it as an external file - and by clicking unblock you remove that designation.
I just had the same/similar issue on a TFS build server where a build was referencing dll's from a network share.
The problems is that the CLR v4 security policy model has changed since previous versions and are not sandboxing assemblies as before.
To fix your issue just find the location of sgen.exe and create a sgen.exe.config in the same folder with following contents:
<configuration>
<runtime>
<loadFromRemoteSources enabled="true" />
</runtime>
</configuration>
sgen.exe is usually at
"C:\Program Files\Microsoft SDKs\Windows\v[current version]\bin\NETFX 4.0 Tools"
You can read about some of the changes around CAS policies in .NET 4.0 in this blogpost: Link
Had the same problem and the config change didnt work. Only when i set Generate Serialization Assembly to off in the project properties did it work.
I had the same error and found my DLL was "blocked". Open up the DLL in explorer, right click -> properties -> press 'Unblock'.
http://cantgrokwontgrok.blogspot.com/2009/10/visual-studio-unknown-build-error.html
I had this exact same problem and fixed it by adding the sgen.exe.config under C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools
with this simple config as others have said
<?xml version ="1.0"?>
<configuration>
<runtime>
<loadFromRemoteSources enabled="true" />
</runtime>
</configuration>
For those of you running a 64bit version of the TFS build service, I had to create the config file in the following path:
C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools\x64
And the file contents:
<?xml version ="1.0"?>
<configuration>
<runtime>
<loadFromRemoteSources enabled="true" />
</runtime>
</configuration>
I had the same issue, loaded the assembly in the GAC and worked
Adding the snippet below to the app.config file worked in my case. I'm Running Windows XP, with VS2010 service pack 1.
<configuration>
<runtime>
<loadFromRemoteSources enabled="true" />
</runtime>
</configuration>
In my case bunch of dlls were blocked.
To unblock all files in folder I used power shell with following command
dir -Path [directory path] -Recurse | Unblock-File
Just as an FYI if you are running Windows 7 the sgen.exe file can be found at:
C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools
I had to create a sgen.exe.config and place it there and then this problem went away.
Neither the unblock nor the config worked for me.
What did the trick for me was this tip about caspol.
I ran
%windir%\Microsoft.NET\Framework\v2.0.50727\CasPol.exe -m -ag 1.2 -url file://UncPathName/UncSubPath/* FullTrust
And I was ready to go, not even a VisualStudio restart required.
I got a similar problem and I finally got over with it by removing the licenses.licx file in the Properties folder of the solution.
Just in case like me, Unblock was not a solution, as Unblock does not appear on my dll file properties. Kept looking and ended up closing my solution file and re-opening using the local C: copy instead of network UNC path to project sln file. Was able to publish after going this route.

How do I Compile and Deploy an assembly into a custom path using visual studio?

I've been searching this for a long while and i could find anything. I have 2 projects. One called ConsoleApp and other called ConsoleLib. ConsoleApp has a reference to ConsoleLib.
How can i Tell visual studio to copy the assembly into a custom path instead of the app path?
What i want to mean is that when i build the solution i want to get this folder structure
AppPath\ConsoleApp.exe
AppPath\Lib\
AppPath\Lib\ConsoleLib.dll
In your ConsoleApp project refer the ConsolLib project which will receive the ConsolLib.dll in ConsolApp\Bin.
Now in the ConsoleApp project goto PostBuild commands there you can sepcify the operations you may wnat to execute after the build and there you can have it copied to ConsoleApp\Lib.
You need to use a postbuild command in the application project to create the lib directory and copy the library file into it.
If you decide to do this (which I wouldn't recommend unless you have lots of dlls and feel an overwhelming urge to organise them) you also need to add a probing path element to your app.config file that will tell it where to look for the libraries. See here.
Use a postbuild command (I'm using subdir "release" in output)
mkdir "$(TargetDir)release\"
mkdir "$(TargetDir)release\bin\"
copy "$(TargetDir)*.*" "$(TargetDir)release\"
copy "$(TargetDir)*.dll" "$(TargetDir)release\bin\"
copy "$(TargetDir)*.pdb" "$(TargetDir)release\bin\"
del "$(TargetDir)release\*.pdb"
del "$(TargetDir)release\*.dll"
del "$(TargetDir)release\*vshost*.*"
In app.config then :
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="bin"/>
</assemblyBinding>
</runtime>
Hope this helps

Resources