VSIX package doesn't include localized resources of referenced assembly - visual-studio-2010

I'm creating a VS2010 extension (let's call it MyExtension). The UI for this extension is in a different assembly (MyExtension.UI), the extension project only contains boilerplate code to call the UI from the menu command.
MyExtension.UI contains localized resources (e.g. fr\MyExtensions.UI.resources.dll), but the VSIX package doesn't include these resources (although they are present in the bin\Debug directory).
How should I tell VS to include these resources in the VSIX package? I looked in the .vsixmanifest designer, but I can't find the appropriate option...

This is actually a bug that will be addressed in a future release. Fortunately, there is a simple workaround:
Select the Project Reference node to 'MyExtension.UI' in Solution Explorer and view the Properties (F4)
Change the value for "Output Groups Included in VSIX" to the following: BuiltProjectOutputGroup;BuiltProjectOutputGroupDependencies;GetCopyToOutputDirectoryItems;SatelliteDllsProjectOutputGroup

#JohnField - I ran into the same error - "Could not determine the Full Name of the Assembly at '...'" - and wanted to list the fix here, in case anyone else runs into the same problem.
My issue was that I had both a ProjectReference to the referenced assembly AND I listed the Assembly as an Asset in my .vsixmanifest file. When you add a 'Copy To Output Directory' item to the referenced assembly, the VS SDK gets confused because it thinks the Assembly Asset you added was only for the Assembly. It sees the extra CopyToOutputDirectory item, and thinks it is an assembly and tries to load it.
The fix was to remove the Assembly as an Asset in the .vsixmanifest. This is not needed because the project is already being referenced, which includes the assembly in the resulting .vsix. Actually, the poorly name AssetType “Microsoft.VisualStudio.Assembly” is actually for template wizards.

Related

How do you set Resource Logical Name in Visual Studio 2010?

I have a problem when migrating a solution from VS2008 to VS2010. The problem is that the managed resources are not found in some cases in runtime, since they are not embedded with the correct name:
"Could not find any resources appropriate for the specified culture or the neutral culture. Make sure "Production.ViewDocument.resources" was correctly embedded or linked into assembly "RSProcess" at compile time, or that all the satellite assemblies required are loadable and fully signed."
System.Resources.MissingManifestResourceException is typically thrown InitializeComponent in a call to ApplyResources on a resource that is created passing the type id. In my case the namespace is Production and the class name is ViewDocument. However, the resource generated (from the ViewDocument.resx) is named from the folder structure where the resx file is, in this case Production.folder1.folder2.ViewDocument.resources.
In VS2008 you could override the (default) logical name in in a setting on the .resx file, Managed Resources/General/Resource Logical Name. In VS2010 I cannot get this to work - it simply ignores this setting completly! Is there any ohter way of solving this?
One last resort would be to remove the current folder structure and move all files to the root project folder, but this seems to be quite a lot of work in my case.
Any suggestions?
I have found an answer to my own question!
A couple of things has changed in VS2010 that confused me. First, in VS2008 the names of the .resource files were affected by the project setting 'Resource Logical Name', in VS2010 the files are always named according to the root namespace of the project and the folder structure (extended namespace). Second, when migrating, these settings were blanked out, perhaps because we had used a macro $(InputFile) that has been replaced by %(Filename).
To fix this problem, I defined 'Resource Logical Name' on the project level (or you could use project property pages) to $(RootNamespace).%(Filename).resources. Note that the .resource files still get the extended names (defined by in which folder they reside). However, if you check the log file from MSBuild you can see that the logical name appears in the /ASSEMBLYRESOURCE swich to the linker in addition to the resource file name! After rebuilding, the ComponentResourceManager will now find the resources in 'InitializeComponent' using the type for the view, Rootnamespace.filename in this case. Also note that this assumes that your view classes are placed in files with the same name as the class!

Ambiguous dll parser error when trying to debug a project

I'm getting the following error when I try to debug my MVC solution:
Parser Error
Description: An error occurred during the parsing of a resource required to service this request. Please review the following specific parse error details and modify your source file appropriately.
Parser Error Message: The type 'HandiGamer.MvcApplication' is ambiguous: it could come from assembly 'C:\Users\Kevin\documents\visual studio 2010\Projects\HandiGamer\HandiGamer\bin\HandiGamer.DLL' or from assembly 'C:\Users\Kevin\documents\visual studio 2010\Projects\HandiGamer\HandiGamer\bin\HandiGamer.WebUI.DLL'. Please specify the assembly explicitly in the type name.
Source Error:
Line 1: <%# Application Codebehind="Global.asax.cs" Inherits="HandiGamer.MvcApplication" Language="C#" %>
Source File: /global.asax Line: 1
This is the first time I've encountered this error with my project. All I've changed since the last time I debugged it was a .master page, a view, and I added a couple ViewModel classes. My solution has two projects - HandiGamer.WebUI and HandiGamer.Domain - but I've never encountered an ambiguity issue with them before. Rebuilding my solution did nothing. I'm not sure what else to do.
Have you renamed you assembly recently? In this case it can be that the old DLL is still in your bin folder ...\Projects\HandiGamer\HandiGamer\bin and is being loaded on runtime. As the error message tells you, the DLLs
HandiGamer.DLL
HandiGamer.WebUI.DLL
both contain HandiGamer.MvcApplication so the parser cannot decide which of them to take and is getting a conflict when you try to run it (compiling usually works fine with no errors, the issue typically occurs during runtime).
To resolve this, delete them from the bin folder above manually, then rebuild the entire solution. Unfortunately, 'Clean Solution' does not always clean up everything correctly so you have to do it sometimes by yourself.
Hint: If you unload the project (in Visual Studio: right-click the project, then select "Unload..."), you can edit the project file afterwards in the text editor and then search for assemblies there (to do that, right-click again on the unloaded project, then select "Edit...").
It contains all the references you have specified - but be careful not to mess it up. After you have searched and found the information you were looking for, close it and re-load the project. This is usually much faster than going though all entries in the References section of your project.
It looks like the MvcApplication class is defined in both assemblies in the HandiGamer namespace. Try opening them with Reflector to confirm this by searching for this class name. Then remove the duplicate class by leaving it only in your ASP.NET MVC application assembly. The other project must be a class library, not a web application.

MSBuild doesn't copy references (DLL files) if using project dependencies in solution

I have four projects in my Visual Studio solution (everyone targeting .NET 3.5) - for my problem only these two are important:
MyBaseProject <- this class library references a third-party DLL file (elmah.dll)
MyWebProject1 <- this web application project has a reference to MyBaseProject
I added the elmah.dll reference to MyBaseProject in Visual studio 2008 by clicking "Add reference..." → "Browse" tab → selecting the "elmah.dll".
The Properties of the Elmah Reference are as follows:
Aliases - global
Copy local - true
Culture -
Description - Error Logging Modules and Handlers (ELMAH) for ASP.NET
File Type - Assembly
Path - D:\webs\otherfolder\_myPath\__tools\elmah\Elmah.dll
Resolved - True
Runtime version - v2.0.50727
Specified version - false
Strong Name - false
Version - 1.0.11211.0
In MyWebProject1 I added the reference to Project MyBaseProject by:
"Add reference..." → "Projects" tab → selecting the "MyBaseProject". The Properties of this reference are the same except the following members:
Description -
Path - D:\webs\CMS\MyBaseProject\bin\Debug\MyBaseProject.dll
Version - 1.0.0.0
If I run the build in Visual Studio the elmah.dll file is copied to my MyWebProject1's bin directory, along with MyBaseProject.dll!
However if I clean and run MSBuild for the solution (via D:\webs\CMS> C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe /t:ReBuild /p:Configuration=Debug MyProject.sln)
the elmah.dll is missing in MyWebProject1's bin directory - although the build itself contains no warning or errors!
I already made sure that the .csproj of MyBaseProject contains the private element with the value "true" (that should be an alias for "copy local" in Visual Studio):
<Reference Include="Elmah, Version=1.0.11211.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\mypath\__tools\elmah\Elmah.dll</HintPath>
**<Private>true</Private>**
</Reference>
(The private tag didn't appear in the .csproj's xml by default, although Visual Studio said "copy local" true. I switched "copy local" to false - saved - and set it back to true again - save!)
What is wrong with MSBuild? How do I get the (elmah.dll) reference copied to MyWebProject1's bin?
I do NOT want to add a postbuild copy action to every project's postbuild command! (Imagine I would have many projects depend on MyBaseProject!)
I just deal with it like this. Go to the properties of your reference and do this:
Set "Copy local = false"
Save
Set "Copy local = true"
Save
and that's it.
Visual Studio 2010 doesn't initially put:
<private>True</private> in the reference tag and setting "copy local" to false causes it to create the tag. Afterwards it will set it to true and false accordingly.
I'm not sure why it is different when building between Visual Studio and MsBuild, but here is what I have found when I've encountered this problem in MsBuild and Visual Studio.
Explanation
For a sample scenario let's say we have project X, assembly A, and assembly B. Assembly A references assembly B, so project X includes a reference to both A and B. Also, project X includes code that references assembly A (e.g. A.SomeFunction()). Now, you create a new project Y which references project X.
So the dependency chain looks like this: Y => X => A => B
Visual Studio / MSBuild tries to be smart and only bring references over into project Y that it detects as being required by project X; it does this to avoid reference pollution in project Y. The problem is, since project X doesn't actually contain any code that explicitly uses assembly B (e.g. B.SomeFunction()), VS/MSBuild doesn't detect that B is required by X, and thus doesn't copy it over into project Y's bin directory; it only copies the X and A assemblies.
Solution
You have two options to solve this problem, both of which will result in assembly B being copied to project Y's bin directory:
Add a reference to assembly B in project Y.
Add dummy code to a file in project X that uses assembly B.
Personally I prefer option 2 for a couple reasons.
If you add another project in the future that references project X, you won't have to remember to also include a reference to assembly B (like you would have to do with option 1).
You can have explicit comments saying why the dummy code needs to be there and not to remove it. So if somebody does delete the code by accident (say with a refactor tool that looks for unused code), you can easily see from source control that the code is required and to restore it. If you use option 1 and somebody uses a refactor tool to clean up unused references, you don't have any comments; you will just see that a reference was removed from the .csproj file.
Here is a sample of the "dummy code" that I typically add when I encounter this situation.
// DO NOT DELETE THIS CODE UNLESS WE NO LONGER REQUIRE ASSEMBLY A!!!
private void DummyFunctionToMakeSureReferencesGetCopiedProperly_DO_NOT_DELETE_THIS_CODE()
{
// Assembly A is used by this file, and that assembly depends on assembly B,
// but this project does not have any code that explicitly references assembly B. Therefore, when another project references
// this project, this project's assembly and the assembly A get copied to the project's bin directory, but not
// assembly B. So in order to get the required assembly B copied over, we add some dummy code here (that never
// gets called) that references assembly B; this will flag VS/MSBuild to copy the required assembly B over as well.
var dummyType = typeof(B.SomeClass);
Console.WriteLine(dummyType.FullName);
}
If you are not using the assembly directly in code then Visual Studio whilst trying to be helpful detects that it is not used and doesn't include it in the output. I'm not sure why you are seeing different behaviour between Visual Studio and MSBuild. You could try setting the build output to diagnostic for both and compare the results see where it diverges.
As for your elmah.dll reference if you are not referencing it directly in code you could add it as an item to your project and set the Build Action to Content and the Copy to Output Directory to Always.
Take a look at:
This MSBuild forum thread I started
You will find my temporary solution / workaround there!
(MyBaseProject needs some code that is referencing some classes (whatever) from the elmah.dll for elmah.dll being copied to MyWebProject1's bin!)
I had the same problem.
Check if the framework version of your project is the same of the framework version of the dll that you put on reference.
In my case, my client was compiled using "Framework 4 Client" and the DLL was in "Framework 4".
The issue I was facing was I have a project that is dependent on a library project. In order to build I was following these steps:
msbuild.exe myproject.vbproj /T:Rebuild
msbuild.exe myproject.vbproj /T:Package
That of course meant I was missing my library's dll files in bin and most importantly in the package zip file. I found this works perfectly:
msbuild.exe myproject.vbproj /T:Rebuild;Package
I have no idea why this work or why it didn't in the first place. But hope that helps.
I just had the exact same problem and it turned out to be caused by the fact that 2 projects in the same solution were referencing a different version of the 3rd party library.
Once I corrected all the references everything worked perfectly.
As Alex Burtsev mentioned in a comment anything that’s only used in a XAML resource dictionary, or in my case, anything that’s only used in XAML and not in code behind, isn't deemed to be 'in use' by MSBuild.
So simply new-ing up a dummy reference to a class/component in the assembly in some code behind was enough convince MSBuild that the assembly was actually in use.
Using deadlydog's scheme,
Y => X => A => B,
my problem was when I built Y, the assemblies (A and B, all 15 of them) from X were not showing up in Y's bin folder.
I got it resolved by removing the reference X from Y, save, build, then re-add X reference (a project reference), and save, build, and A and B started showing up in Y's bin folder.
Changing the target framework from .NET Framework 4 Client Profile to .NET Framework 4 fixed this problem for me.
So in your example: set the target framework on MyWebProject1 to .NET Framework 4
I had the same problem and the dll was a dynamically loaded reference.
To solve the problem I have added an "using" with the namespace of the dll.
Now the dll is copied in the output folder.
This requires adding a .targets file to your project and setting it to be included in the project's includes section.
See my answer here for the procedure.
Referencing assemblies that are not used during build is not the correct practice. You should augment your build file so it will copy the additional files. Either by using a post build event or by updating the property group.
Some examples can be found in other post
MSBuild to copy dynamically generated files as part of project dependency
VS2010 How to include files in project, to copy them to build output directory automatically during build or publish
Another scenario where this shows up is if you are using the older "Web Site" project type in Visual Studio. For that project type, it is unable to reference .dlls that are outside of it's own directory structure (current folder and down). So in the answer above, let's say your directory structure looks like this:
Where ProjectX and ProjectY are parent/child directories, and ProjectX references A.dll which in turn references B.dll, and B.dll is outside the directory structure, such as in a Nuget package on the root (Packages), then A.dll will be included, but B.dll will not.
I had a similar issue today, and this is most certainly not the answer to your question. But I'd like to inform everyone, and possibly provide a spark of insight.
I have a ASP.NET application. The build process is set to clean and then build.
I have two Jenkins CI scripts. One for production and one for staging. I deployed my application to staging and everything worked fine. Deployed to production and was missing a DLL file that was referenced. This DLL file was just in the root of the project. Not in any NuGet repository. The DLL was set to do not copy.
The CI script and the application was the same between the two deployments. Still after the clean and deploy in the staging environment the DLL file was replaced in the deploy location of the ASP.NET application (bin/). This was not the case for the production environment.
It turns out in a testing branch I had added a step to the build process to copy over this DLL file to the bin directory. Now the part that took a little while to figure out. The CI process was not cleaning itself. The DLL was left in the working directory and was being accidentally packaged with the ASP.NET .zip file. The production branch never had the DLL file copied in the same way and was never accidentally deploying this.
TLDR; Check and make sure you know what your build server is doing.
Make sure that both projects are in the same .net version also check copy local property but this should be true as default
Using Visual Studio 2015 adding the additional parameter
/deployonbuild=false
to the msbuild command line fixed the issue.
I just ran into a very similar issue. When compiling using Visual Studio 2010, the DLL file was included in the bin folder. But when compiling using MSBuild the third-party DLL file was not included.
Very frustrating. The way I solved it was to include the NuGet reference to the package in my web project even though I'm not using it directly there.
I dont think #deadlydog answer is valid with the current Nuget system. I recreated the scenario with Y => X => A => B in visual studio 2022 and all I had to do was run the command in terminal
msbuild -t:clean,rebuild,pack
Including all referenced DLL files from your projectreferences in the Website project is not always a good idea, especially when you're using dependency injection: your web project just want to add a reference to the interface DLL file/project, not any concrete implementation DLL file.
Because if you add a reference directly to an implementation DLL file/project, you can't prevent your developer from calling a "new" on concrete classes of the implementation DLL file/project instead of via the interface. It's also you've stated a "hardcode" in your website to use the implementation.

How to associate external files with an assembly

Let's say you have a class library project that has any number of supplemental files that also need to be included with the compiled assembly (e.g. simple text files or even a legacy unmanaged DLL that's wrapped by the assembly as an interop layer). While embedding the supplemental files into the assembly itself is relatively straightforward, we have situations where this is not possible or just undesirable. We need to have them as "sidecar" files (i.e. files alongside the assembly, potentially in subdirectories relative to the assembly)
Adding those files to the project with an appropriate value for "Copy to Output Directory" specified appears to be sufficient for projects that are completely self-contained within a solution. But if a separate project in another solution adds a reference to the assembly, it does not automatically pickup its sidecar files. Is there a way in the project to somehow mark the resulting assembly such that anything referencing the assembly will also know it needs to include the associated sidecar files? How do you do this?
You can use al.exe, but there also appears to be a C# compiler option. You want to create a multifile assembly using the /linkresource C# compiler option. Instructions are here, but the command is similar to this:
csc /linkresource:N.dll /t:library A.cs
Where N.dll is a native DLL that will go wherever the managed assembly goes (including into the GAC.) There's a very clear description at the link I provided.
Have you tried creating a setup for your solution ? There's an option of including sidecar files targeting to application installation directory.
Another option would be to include the sidecar files in the Assembly resources and un-wrap them to disk when run for the first time.
What if you create a merge module containing the library plus its dependencies? Your installer will then need to reference this module, but you will ensure all of the necessary files will be present.
Unfortunately there doesn't appear to be a lot of built-in support in Visual Studio for this, although I can definitely see the use case.
If you use Subversion for your source control, then you could link in an external reference as an externals definition. This would bring in the source code, and you'd be making a reference to the necessary assembly as a project reference instead of a DLL reference, and then the copy to output directory rules would come into play.
If that's not possible, another solution would be to include commands in the pre/post-build events of your in-solution project to copy the most up-to-date sidecar files from the remote assembly on a build. Of course this comes with the caveat that it doesn't set itself up automatically when you include the DLL in your project; you have to take manual steps to set it up.
I deal with this some time ago. Its a common problem.
You can create some postbuild actions:
http://www.codingday.com/execute-batch-commands-before-or-after-compilation-using-pre-build-or-post-build-events/
Hope this helps... :)
It appears to me that you're using the wrong type of reference. There are two types of references- Reference and ProjectReference. Reference is an explicit reference to a specific assembly. ProjectReference is a reference to another project (say .csproj).
What you're looking for is ProjectReference. VS and the default MSBuild targets are setup to do CopyLocal. If you set CopyToOutputPath true for your "sidecar" files, any ProjectReferences to this project now will also pull in the same files.
I'm not sure if you can to ProjectReferences across solutions in the IDE. I deal a lot with MSBuild where sln files are not relevant and this is how I deal with it.
What we did in our project is that we created as separate build file to do all those stuffs.
In your build file you can have tags to build your main solution, then add tags to copy files you need after build.
NAnt is also your option, but right now I'm happy using Rake as my build/debug automation.
Since this cannot be integrated within Visual Studio, what I'm doing is I create a task (either in MSBuild, NAnt or Rake), that executes vsjitdebugger.exe in the end to attach it to my Visual Studio when debugging.
These are just my styles for now, you can maybe create your own style.

How does visual studio determine what to copy to the output directory with multi-project solutions?

Let's say we have a solution with the following structure:
Project.DAL - Data access layer,
depends on a lower-level library,
e.g. Oracle.DataAccess w/copy local
= true
Project.BLL - Business logic layer, references Project.DAL as
project
Project.UI - UI layer,
compiles to executable, references
Project.BLL, default project
When Project.UI is compiled, VS is smart enough to copy Project.DAL.dll to the output directory, but it's not smart enough to figure out that I wanted Oracle.DataAccess to be copied to the output directory as well for distribution to clients.
Can anyone explain why this is so? Is it because it sees Oracle.DataAccess in the GAC and assumes that clients will have it in the GAC as well?
It's not that big of a deal, but it's kinda annoying that every time I add a new assembly reference, I have to remember to set it to copy local and add an item to copy it in my build script as well.
One more thing.
When you don't use the referenced DLL in your code at all, it will ignore the CopyLocal and won't copy it to your output directory.
Yes, Visual Studio will copy a DLL to the output path in any of the two conditions below:
The DLL is referenced explicitly with CopyLocal = true
The DLL is referenced without CopyLocal or implicitly through some other referenced DLL and is not in the GAC
The reason why it will not copy-local when the file is in GAC, is that when resolving assembly names the GAC has highest priority, i.e. even if you have a (different) local copy, the version from the GAC will be used.
I suggest you set up a library directory where you put all external assemblies that are referenced. Then you set up an automatic MSBuild script on a computer (or VM) that does not have the Oracle-file gac'ed (nor Visual Studio installed for that sake). That way, the file will be copied to the build, and you will have more control over what is done than when using VS.
I had a strange situation where even though the assembly was a project reference and was referenced with "Copy Local" showing up as "True" in the reference properties window, the DLL was not being copied to the output directory. I had an earlier version of the DLL in the GAC but I didn't see why this should prevent the DLL being copied.
I found that by unloading the project and manually editing the project reference XML as follows:
<ProjectReference Include="..\SomeProject.csproj">
<Project>{11111111-1111-1111-1111-111111111111}</Project>
<Name>Some Project Name</Name>
<Private>True</Private>
</ProjectReference>
The DLL was copied to the ouput directory as expected. I found that just setting Copy Local to True in the properties window meant the <Private> element was completely missing, but in the case of it being set to false it was present with a value of "False".
#RenniePet Here's a link to a blog which describes the method RenniePet described in a comment above (if you don't want to edit your project file manually as #Shaun suggested):
http://blogs.msdn.com/b/jjameson/archive/2009/11/18/the-copy-local-bug-in-visual-studio.aspx

Resources