I have quite odd scenario. I have external library like one below:
Now I need to use it in other solution but in quite unnatural way (but it needs to be like that :/). So it is included in such fashion:
As you noticed we have here new project named ExternalLib (just like the one we've created before in different solution). It contains only .dll of that library and we reference this project in Consumer (Add reference -> Project -> ExternalLib). Also I had to add one postbuild action for this 'proxy' ExternalLib copy /Y "$(ProjectDir)/ExternalLib.dll" "$(TargetDir)". It builds without errors. Only errors are displayed by Visual Studio text editor (as it is visible on screenshot above).
My question: is there any way to make visual know about that 'real' contents of that library? (I also do not own .pdb files) I know it is really odd way including external library but it is some constraint I can't avoid :/
Related
I am building a few different C# libraries that both depend on a single C# file we'll call Dep.cs, and these dll's need to be used together in a Unity project. I'd like to set up these projects in the following way:
The C# libraries can be built independently of one another using Visual Studio
C# libraries (i.e. dll's) can be imported into a Unity project without conflicting symbols
The C# library projects (i.e. the source code for each library via git submodule for example) can be imported into a Unity project without conflicting sources.
I've solved (1) by including Dep.cs in each library project that requires it, though this causes issue with (2). And I've solved (3) by putting the dependency in a folder like Dependencies~ so that Unity ignores the file (this way no duplicate classes are found).
I'm having trouble solving (2) however. I thought I'd be able to add Dep.cs as reference in the VS solution but This doesn't seem to work. I've heard of Assembly References but I am not sure if they do what I need.
You can use "Add File as Link" from Visual Studio "Add Existing File" screen. It also works well with git submodule, just place Dep.cs anywhere in a parent folder or in the solution's root directory.
To get the same result you can also directly edit the .csproj file and add a compile instruction:
<ItemGroup>
<Compile Include="..\..\Path\To\YourFile.cs" Link="YourFile.cs" />
</ItemGroup>
This method solves all the issues you mentioned.
To solve my problem I decided to modify the external scripts to be internal this way both dll's can compile with that source and not conflict with one another. The rest of the setup in my question remained the same so this solved (2) for me without compromising (1) and (3).
Ever since I've been using the (relatively) new .NET Standard Library project type in Visual Studio, I've been having some problems getting a complete set of DLL files that are required by my project.
The problem is usually limited to 3rd-party libraries which I reference as NuGet packages. I've noticed that these don't get copied to the output folder of my project when I build it. This didn't use to be the case in classic project types.
While I can appreciate the de-cluttering effect that this change has brought for .NET Standard projects, I'm now faced with a problem. I sometimes absolutely need to be able to get the entire list of all files that my project depends on!
I have several different cases, where I might require this list for one reason or another, but the one I believe is most crucial for me, is when I want to gather these files from the csproj itself, right after it's built. In there, I have a custom MSBuild <Target> which should take all the files from the output dir and zip them together for distribution. The problem is, I'm missing all the files that come from NuGet dependencies, because they're not there!
How can I solve this in a general (i.e. not project-specific) way?
UPDATE
There's this deps.json file that contains basically all I'm after and then some. It's just a matter of extracting the relevant information and find the files in the local NuGet cache. But that would involve writing a specialized app and calling it from my target. Before I start writing one myself... Is there something like this already out there somewhere?
I followed this answer and it sort of works.
The suggested thing was to include the following into my csproj:
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
My main concern is that it also outputs some other DLLs from the framework (such as System.Memory.dll and System.Buffers.dll, among others), which I didn't expect. But maybe that's a good thing. They do seem to be dependencies, just not direct ones. I'll see how it plays out.
If it turns out ok, my only wish would be that this directive was more prominently displayed in project settings (as a simple checkbox, maybe?) so I wouldn't have to hunt the web to find it.
I've got an C# Project in Visual Studio, which has Console Application as Output Type.
But I also need a Class Library of this project for another solution.
Right now I have to switch the output type every time, but I wonder if it's possible to generate exe and dll at the same build-event?
Is there a post-build-event for this?
To my knowledge there is no possibility to change the output type after compilation. That being said, if would be possible to have two projects like Console and Library in your solution, which would use the same source code files but have different output types. That way you would have different outputs without any duplication of code.
it is generally possible to reference a .net exe assembly as it would be a class-library.
So you can just stick in creating an exe file and reference the exe (sounds strange, but works) in your other project.
This is the dialog for browsing for references. As you see you can select exe files.
But as commented it really depends on what your usecase is.
I don't recommend to ship an exe with an entry point to your customer hoping that the customer does not discover the exe. But what you could do about that is to conditionaly compile your entry point.
For example
class Program {
// This is the entry point of the EXE
public static void Main() {
#if DEBUG
// Start Debug Application
...
#else
// Shipped to client - Entry point disabled
return;
#endif
}
}
If there is a relevant reason to have a shipped exe and a shipped class library, I would refactor your solution like this:
(A) complete application (.sln)
(B) console-application (.csproj) which has a reference to (C)
(C) class library project (.csproj)
With that it is perfectly clear to others that there is an application that uses the library and the library itself.
Console Application is the type of your project. You can not change it.
What you can -and must- do is, carry your logic into a Class Library project and use your class library from any type of project you want.
You should compile your project to become a dll and then use this dll in a console application.
A possibility to achieve what you want is to manually run the msbuild on your post-build event of your project.
See: How do i build a solution programatically in C#?
or Building C# Solution in Release mode using MsBuild.exe
The usual solution for this is using a Solution with two projects:
a Class Library with all the code (which builds into a DLL)
an Console Application referencing the library whose Main just calls some function(s).
For more information, check the MSDN page on Solutions.
Codor suggested manually adding the files to the Console project, but one downside is that build settings are not shared between both versions, so you might get some inconsistency there.
I'm not really sure why people think it's not possible but it actually is.
The easiest way would be renaming the exe to dll Sounds stupid, I know. But it works in many cases. Also, as "Peter I" said a .NET exe can be imported as assembly in other projects. So you might not actually need a dll anyways.
Another way would be using C# command line as stated here: /out (C# Compiler Options)
You can use command command line options in Pre/Post build events Pre-build Event/Post-build Event Command Line Dialog Box
I have a similar requirement and couldn't find any definite answer in this post or anywhere. I currently have a class library and would like to create a console application project without copying any code. Ideally speaking there should be two projects, one for creating a console application and another for creating a class library. And this is what the visual studio also suggests. When I tried to run the class library, I got the below message.
It clearly asks us to add an executable project to the solution and add the reference to the library project.
Below are the steps to do this.
Right click solution -> Add new project -> Console App -> choose name -> ok.
Right click on the console project -> add reference -> In reference manager, click on the projects tab and select the other project(In my case this is the class library project, In case it is not listed just click on browse and select the .csproj file) -> ok.
Now to use the classes in the other project, simple do using LibraryProjectNameSpace
There we are. Bingo!!!!
Also as mentioned in the other answers it is not possible to have the same project generate both .exe and .dll. But you can have the same solution generate these two guys by having two projects. In this way there is no need to switch the output of the project every time.
FYI, I use visual studio 2017
We have one master project that creates a single DLL with FEATURE_1, FEATURE_2 and FEATURE_3 as three conditional compilation symbols that enable those respective features.
MyLib.dll => has FEATURE_1, FEATURE_2 and FEATURE_3 compiled in
We now wish to have the same master project spit out 3 different DLLs as follows:
MyLib.1.dll => has only FEATURE_1 compiled in
MyLib.2.dll => has only FEATURE_2 compiled in
MyLib.3.dll => has only FEATURE_3 compiled in
At present we build within VS2013 and those compile constants are defined inside the .csproj file (within the <DefineConstants> </DefineConstants> tags), which hard-codes them.
Is it possible to pass them via a command line so we can still maintain one master csproj but build the 3 different flavors in the RELEASE configuration just by changing the command line (eg: gcc's -D<buildFlag> style) ? The solution has other projects and they're designed to work with the RELEASE configuration. I'm also open to any other technique that is easy to use and maintain.
We're really trying to avoid creating pseudo-projects or affecting other projects in the solution (21 projects in the solution) - seems like an overkill/hackish for something very simple.
I haven't done anything with the command line, but to solve similar problems, I created separate projects (that define the Framework Target and any conditional compilation symbols), and then add all the project files as LINKED files. In this way, I only have to modify a single set of source files, but each project compiles into its own DLL.
To add a file to a project as a linked
Right click the project and click Add Existing Item...
Select the file (or files) you want to Add.
Instead Of clicking the Add button, click the arrow next to the Add button, and click Add as Link.
I'm not sure if this will work for your case, but it sure has saved me lots of time when developing libraries for different .NET framework versions.
Is it possible that you have a complete turnaround?
Instead of defining all features in a single library and then disable some of them, you can create individual projects for each features, and then at packaging phase merge the smaller assemblies into a single one.
Microsoft has ILMerge, while ILRepack is an open source alternative,
https://www.nuget.org/packages/ilmerge
https://www.nuget.org/packages/ILRepack/
Then you are free of conditional compilation, which is too difficult to manage, and the complexity is moved to your packaging scripts, which can be easily managed and checked into source code management.
I was given a project in which I am supposed to debug a problem in a Windows Forms application. I found where the problem is located but it is within a Class Library which is included as a component of my Windows Forms application solution.
How can I add/modify code in the Class Library project and actually run it live so that I can debug it? If I make any changes to the Class Library as is, the application ignores the changes and resorts to the original source code.
The only things contained in the Class Library's folder are plain source code files, some settings files, and a .vbproj. I just want to make changes to the Class Library and actually be able to debug them. If anyone could please explain what I have to do, it would be greatly appreciated!
Your application is not loading the assembly produced by compiling the class library. It is loading another copy from somewhere.
One quick way to find out where is to start the application from Visual Studio, break into the debugger and then bring up the Modules windows (Debug>Windows>Modules). Look for the class library in the Name column and check the Path.
If it is under C:\Windows\Microsoft.NET\assembly... then there is an older version being loading from the GAC. If it's another location, you will need to ensure the class library project output is going to that location.
Does the startup project have a project reference to the class library in the solution? You could always remove and re-add the reference to the class library in the startup application project and ensure you add it as a project reference.
Be careful though, there may be a good reason why this wasn't the case originally.
EDIT
A full explanation of how assemblies are located is way beyond the scope of an SO post - you'll need to study How the Runtime Locates Assemblies.
With no changes made to typical solution defaults, a library is most likely to be loaded from the same folder where the start-up executable is located. Setting a project reference to a library causes it to be compiled and copied to that project's bin folder - so make sure the startup project has a project reference to your class library project. (Right-click startup project and check Add References... dialog. The reference should come from the Solution section).
You'll need to examine the project property pages to see if something special has been configured.
99.99% of the time, building the WHOLE solution and hitting run should work. If it doesn't work, something is messed up in the solution and/or there is some kind of custom deployment set up.
There are simply so many ways to deviate from the default deployment that I just can't give specific guidance here; you best bet is to get someone knowledgeable who can take a look in person, or to whom you can send the source for inspection.
I just went to Project Properties ....Project Dependencies and checked(ticked ) the class /assembly(.dll) name... It worked for me. Now i dont need to run the class project for the changes to reflect in the Startup Project ..