SetMsiAssemblyNameFileVersion breaks the Strong Name of assemblies - wix

I use the “SetMsiAssemblyNameFileVersion” property in our MergeModules.
So I get a zero at the end of the assembly version.
This breaks the strong name for the assemblies.
In the result Visual Studio setup projects can no longer recognized the assemblies as dependencies.
The automatic adding of MSM’s is broken.
Is there a way to get around this?
regards
Kai
From Binder.cs Version 3.6
// there is a bug in fusion that requires the assembly's "version" attribute
// to be equal to or longer than the "fileVersion" in length when its present;
// the workaround is to prepend zeroes to the last version number in the assembly version

File a bug against Fusion to fix the root issue or file a bug against the Visual Studio Setup Projects to use the same work around so that packages with the fileVersion set will install correctly.

Related

'JsonConvert' is not declared - but Newtonsoft.Json IS referenced

I am working on a website project which includes several lines in one of the classes like this:
Dim asfPaymentInstalmentRequestJson As String = JsonConvert.SerializeObject(asfPaymentInstalmentRequest)
For some reason the JsonConvert part is underlined red and when I try to build the project I get this error:
BC30451 'JsonConvert' is not declared. It may be inaccessible due to its protection level.
According to the documentation JsonConvert is part of Newtonsoft.Json, and I have the Nuget package for version 13.0.1 installed. I have this imports statement:
Imports Newtonsoft.Json
I notice there is also a reference to WorldpayNewtonsoft.Json version 2.0.0.0 so i'm wondering if this could be causing some sort of conflict?
I didn't build this website but i'll need to make changes to it so I need to know how to fix this issue. Any ideas?
The website is built in VB.Net and I am using Visual Studio 2019
UPDATE
I found that there wasn't a Newtonsoft.Json.dll in the bin directory so I copied one in, but then I get errors like:
error BC30560: 'JsonPropertyAttribute' is ambiguous in the namespace 'Newtonsoft.Json'
and
error BC30661: Field or property 'PropertyName' is not found
So it seems the two versions of Newtonsoft.Json aren't playing nice with each other. Somehow this is working on our uat site so there must be a way to get these two to work together but I just can't seem to find it.

msbuild refuses to copy unsigned dll if it is of lower version than demanded by one of the project dependencies - is it by design?

I have the following situation:
All the involved dlls are unsigned
All the projects in the solution depend on version 1.0.21221.1 of Shared.dll
Some NuGet dependencies of some projects in the solution depend on version 1.0.21237.1 of the same dll.
When the web application is built (let us name it Api) it is expected to copy Shared.dll from $(OutDir) to the $(OutDir)_PublishedWebsites\Api\bin folder. The Shared.dll found in $(OutDir) has the version 1.0.21221.1.
The Shared.dll is NOT copied and the web application fails to run.
Here is the evidence from the binary log:
Exhibit A - The conflict of versions:
Exhibit B - ResolveAssemblyReference instructs NOT to copy Shared.dll:
I understand that msbuild does not like the idea of conflicting versions, but NOT copying the dll produces a downright bug, because the application fails to start.
I understand one can resolve it by adding an assembly binding redirect. But I thought it was unnecessary for unsigned assemblies. Am I understanding wrong or am I missing something?
EDIT 1
Here are my answers to the questions posted in the comments:
(Unfortunately I was asked to obfuscate some keywords, I do not know why)
How exactly does the Api project reference Shared.dll?
As we can see in the exhibit B Shared.dll is a transitive dependency of Api. Indeed, Api depends on Xyz.BusinessApi like this:
<Reference Include="Xyz.BusinessAPI" />
Now that DLL depends on Shared.dll through the respective NuGet dependency, here is a snippet from the project.assets.json file of Xyz.BusinessAPI:
What other projects reference Shared.dll and how?
There are a lot of projects referencing it as a NuGet package at version 1.0.21221.1. The problem is that some projects also reference two other NuGet packages which in turn depend on the version 1.0.21237.1 of the same NuGet package. This is indicated in the RAR output - see the exhibit A.
I would like to emphasize - no project references Shared.dll as a raw dll, only either as NuGet package or indirectly through other NuGets or projects or project dlls. Project dll is a dll of a project from a previously built solution - we do not allow project references to other solutions, so if a project is built in a previous solution, then it would be referenced as DLL in subsequent solutions.
What is the mechanism used to copy from OutDir to _PublishedWebsites\api\bin?
This is the standard web application publishing target _CopyFilesMarkedCopyLocal from C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VisualStudio\v16.0\WebApplications\Microsoft.WebApplication.targets:
<!-- copy any referenced assemblies to _PublishedWebsites\app\bin folder -->
<Copy SourceFiles="#(ReferenceCopyLocalPaths)"
DestinationFiles="#(ReferenceCopyLocalPaths->'$(WebProjectOutputDir)\bin\%(DestinationSubDirectory)%(Filename)%(Extension)')"
SkipUnchangedFiles="true"
Retries="$(CopyRetryCount)"
RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)"/>
How does Shared.dll end up in OutDir?
All of our code is built into the shared bin directory - we set OutDir to the same value for all the projects. Thus all the project binaries and their dependencies, including Shared.dll first end up there.
Are there any double-writes in the binlog?
Yes, but I do not think they are relevant:
The short answer is that your projects indirectly depend on two versions of Shared.dll: 1.0.21221.1 and 1.0.21237.1.
RAR (the MSBuild ResolveAssemblyReference task) inspected all the references of all .dlls and found these two versions. It reported a conflict:
Pay attention how it reported the found file path in square brackets for Shared.dll 21221 and reported [] (meaning no file of such version was found) for 21237.
It's useful to search for these using There was a conflict under($rar) or $warning under($rar).
Now, the OutDir only contains the Shared.dll 21221, so the Shared.dll with version 21237 couldn't be found anywhere.
The trick is to search for Shared.dll under($rar project(api.csproj)) You will find the relevant messages from RAR:
Considered "C:\Xyz\61\bin.link\Shared.dll",
but its name "Shared, Version=1.0.21221.1, Culture=neutral, PublicKeyToken=null"
didn't match the expected name "Shared, Version=1.0.21237.1, Culture=neutral, PublicKeyToken=null".
So, it saw a conflict, decided to unify on a later version (21237), but didn't find the file of that version. So the reference of 21221 was not CopyLocal because it didn't unify on that version, and the reference to 21237 was not resolved because a file of that version was not found.
To resolve this, I recommend adding an explicit reference to Shared.dll of the version 21237 (either via NuGet or via GeneratePathProperty metadata on the package reference: https://learn.microsoft.com/en-us/nuget/consume-packages/package-references-in-project-files#generatepathproperty). If you use GeneratePathProperty you can then reference the .dll directly using $(PkgFoo_Bar)\lib\net472\Shared.dll or similar. Also add a binding redirect from 21221 to 21237 to resolve the conflict. Once the correct version (21237) will be in your OutDir, it will get copied to output correctly.
Hope this clarifies.

Microsoft Visual Studio: How to find where a dll is loaded from?

A wrong version of a dll (MSVCR90d.dll instead of MSVCR90.dll) gets used for the delete operator, causing a crash. In the callstack, only the dll name is shown, not their path. How to see the path?
Edit: I'm building in Release mode, not in debug mode. So why does the debug dll get used? I have seen the same problem reported on many other websites, but could find no working solution.
Yesterday I found using Dependency Walker that the debug dll is getting picked up, so I renamed the dll, then the release version got picked up in the Dependency Walker, and also my program did not crash. I didn't change anything today, but the program has started crashing again. And when I see the dependency walker tree, it shows MSVCR90d.dll (the debug dll) with a question mark, saying it couldn't find it in the path. Why can't it pick up the release dll? Also I don't know from where the debug dll gets used by the runtime.
You can add them in your global PATH environment variable. Refer here
You can specify the dll manually by right clicking on the solution and selecting Add Reference, then browse to the particular dll.
You can add the path to the DLLs to the Executables files settings under Tools > Options > Projects and Solutions > VC++ Directories
For finding out the details of a dll, you might want to use DependencyWalker
However, in your case I think d is being appended to the name of dll, probably because you are creating a DEBUG build, and for that corresponding DEBUG versions of all dlls are loaded.
If you choose to create a RELEASE build, you would not have a d appended to MSVCR90.dll
You don't need to know Dll path, you need to understand why Debug version of delete operator is called. Maybe, _DEBUG constant is defined in Release configuration.

visual j# not working in .net 4

I tried to convert a project that relies on the vjs runtime to vs2010, but it errors out when trying to run.
It's giving the error that "Could not load file or assembly 'vjslib' or one of its dependencies. An attempt was made to load a program with an incorrect format."
I reinstalled the vjs runtime, but it didn't seem to help.
Is there any way to get get .net 4 to work with this?
Very simple solution - Calling J# code from .NET 4.0
You take control and load it first supplying an explicit path. Then next time it's needed, it already knows the path (or it's already loaded in the AppDomain).
You will need to use LoadLibrary function, so import the pinvoke reference:
[DllImport("kernel32", SetLastError = true)]
static extern IntPtr LoadLibrary(string lpFileName);
The on load (either Main function in Console/WinForms or in Global.asax Application_Start):
if (Environment.Version.Major >= 4)
{
string folder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), #"..\Microsoft.NET\Framework\v2.0.50727");
folder = Path.GetFullPath(folder);
LoadLibrary(Path.Combine(folder, "vjsnativ.dll"));
}
I have downloaded Microsoft Visual J# Version 2.0 Redistributable Package from http://www.microsoft.com/en-us/download/details.aspx?displaylang=en&id=4712 and installed it.The issue is resolved.
I got this to work by copying C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\vjsnativ.dll (for 64 bit Microsoft.NET\Framework64\v2.0.50727\vjsnativ.dll) to my application's debug/release directory.
I suspect Microsoft will need to release another j# redistributable package to work with .net 4.0. Meanwhile, this work-around does a fine job.
The only way I could get it to work was to copy the C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\vjsnativ.dll to the C:\Windows\Microsoft.NET\Framework\v4.0.30319 folder. See http://community.microfocus.com/borland/managetrack/starteam/w/knowledge_base/17108.error-unable-to-load-dll-vjsnativ-the-specified-module-could-not-be-found-exception-from-hresult-0x8007007e.aspx
To add to the existing answers, I found that the solutions didn't work for me.
First thing I did was to repair the Microsoft Visual J# 2.0 Redistributable Package -SE (x64) using Windows Control Panel (Just right click and click repair). This was in case I did any damage in my previous attempts to fix the problem.
I had already implemented the solution provided by David Thielen.
1 Extra step closed the deal for me (solved the problem):
Copy "vjscor.dll", "vjslib.dll" and "vjsnativ.dll" from C:\Windows\Microsoft.NET\Framework64\v2.0.50727 To C:\Windows\Microsoft.NET\Framework\v2.0.50727
So basically the Microsoft package placed the correct dlls into the 64-bit .NET framework and I had to manually move them into the 32-bit folder which is then copy-pasted into my solution folder by David Thielen's solution (above).

My DLLs are strong named, but WSPBuilder reports they are not

WSPBuilder
Version: 0.9.8.0830
Created by Carsten Keutmann
GPL License 2007
Install and deploying [MYDLL]
Unable to deploy solution
Inner exception(1): This solution contains one or more assemblies targeted for the global assembly cache. You should use a strong name for any assembly that will be in the global assembly cache.
I had the same issues but what worked for me was to delete all the files in the bin and obj folder and then rebuild the WSP.
In my case, I was getting some strange errors (can't remember the exact message) when using Delay sign only option for one project.
I have found the problem, but not the solution, it seems the project I have which is really a 12 hive, is also set to output a class library, this class library is getting included in the WSP.
So... I need to ensure the bin folder is really excluded from the build process.
I set the value in program files but no reaction yet...
Now going to restart the server...
Later: Ok - the fix is to restart the server, for some reason this helped
I'm experiencing the same issue, one solution, multiple projects, the one failing to compile is using an object from another project.
I've tried clearing the bin & obj folder, as well as restarting the server. I think I'll copy the files dll to the gac using gacutil instead.