I have a .Net 3.5 web site project which I am developing in VS2010 (recently moved form VS2008) and building/deploying with MSBuild and TeamCity. I am using Msbuild tools version 3.5. The web site project communicates with a couple of COM components via Interop-dlls. As I understand, these interops are generated by Visual Studio as a wrapper for the COM component. My problem is that when the application is built and deployed using Microsoft.WebDeployments.targets I get a runtime error message saying:
Could not load file or assembly
'Interop.cvvToolkitLib' or one of its
dependencies. An attempt was made to
load a program with an incorrect
format.
After googling for similar problems I have found alot of posts saying that building for "AnyCpu" should fix this problem, since the tool that is generating the interops defaults to x86.
So I opened my build script and tried to specify the platform as AnyCpu:
<Platform>AnyCPU</Platform>
Still same problem. More googling hinted that it might be "AnyCpu" or "Any CPU" instead, so I tried both. Still no luck. Other forum posts suggested something like this instead:
<ItemGroup>
<ConfigurationToBuild Include="Release|Any CPU">
<FlavorToBuild>Release</FlavorToBuild>
<PlatformToBuild>Any CPU</PlatformToBuild>
</ConfigurationToBuild>
</ItemGroup>
or
<PlatformTarget>AnyCPU</PlatformTarget>
The error remains the same. So my question to you stackoverflowers is: Am I doing something wrong in trying to make the web site build for Any CPU, or is the solution maybe lying somewhere else? Do I have to explicitly pass some arguments in to the <CallTarget Targets="Build"/> ?
I am not very experienced with MSbuild, so I may overlook something important. I have other web applications (not web sites) that are communicating with the same COM components without any issues, so it's only a problem for the web sites. The web applications are build like this:
<MSBuild
Projects="$(ProjectFile)"
StopOnFirstFailure="true"
Targets="ResolveReferences;_CopyWebApplication;_BuiltWebOutputGroupOutput"
Properties="...Platform=AnyCPU..." />
Here I pass the Platform as a property, so I am just guessing I need something similar for the web sites.
The problem was solved by using the 3.5 version of MSbuild. I was using the 4.0 version with 3.5 toolsversion. For some reason that caused the interop dlls to be built on the wrong platform. I have however no idea why it was causing this issue. I have been seeing several strange issues with using MSbuild 4.0 for 3.5-projects. If anyone can enlighten me to why these things happen, I will be happy.
Related
I have made a project in VS2019. I have the same project in .NET Core and .NET Framework. I use a COM reference in my project. I would like to migrate these projects to Pi4.
A simple Hello World project (.NET Core) is running successfully on the Pi4 machine. However, when I try to run my project (.NET core or .NET Framework) it does not run on the Pi4. It says COM is not supported.
I tried to build the project using MSBuild in my Windows environment after looking for solutions in Google. I also see a similar error here. The error is: error : MSB4803: The task "ResolveComReference" is not supported on the .NET Core version of MSBuild. Please use the .NET Framework version of MSBuild.
The .NET Framework project also gives a similar error.
error MSB4028: The "ResolveComReference" task's outputs could not be retrieved from the "ResolvedFiles" parameter. Object does not match target type.
Does anyone have similar issues?
https://github.com/microsoft/msbuild/issues/3986
According to the above link. The employee of Microsoft is saying they can not give solution in the near future.
Set the Projects to x86 for them to build the Interop, the Interop created still could not be used in x64 runtimes.
Add the COM Reference to the Core project, Build it and you will get an Interop.YourCom in the bin/x86/core/debug folder.
Remove the COM reference, and re-add the Interop, it will be put into the Assemblies Dependencies, and MSBuild will work.
My MSB4803 was from a WIXInstaller project, for ADOX, and Microsoft.Office.Interop.Access.Dao
I stumbled upon this question many times and I experienced the same several times in different projects. It doesn't matter if it is Visual Studio 2019 or 2022 and the version of the build, unless you are working with the old MSBuild in a legacy environment, the COM Reference doesn't work. It is always safe to build it in the command line to understand if anything in the VS environment works. I don't truly understand why Microsoft let you make those references in the Visual Studio environment when they will not work nearly anywhere else.
There are some workarounds that might or might not work but if your code is already pointing at a COM library there is no much to do. You can install the NuGet package which is going to pass the build stage and remove the COM reference.
Install-Package Microsoft.Office.Interop.Excel -Version 15.0.4795.1001
The NuGet package has some differences at the types level that you will need to fix (the COM reference allows you to get specific types instead of objects from the cells values)
In any case, you will need the COM installed in the server, there is no workaround that issue.
I wouldn't say I like this error message or the link it shows on how to fix it, to be polite.... ;-);
I figured it out and thought as there are a lot of answers that are not helpful to share mine. What I did is update your command to force the use of msbuild.
dotnet msbuild -v:normal "FullOrRelativePathTo\MyProject.csproj" -p:Configuration=RELEASE
If that fails, try:
"C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Current\Bin\msbuild.exe" "PathTo\Project.csproj" /p:Configuration=RELEASE
I know I'm late to the party, but here is a workaround working for me when I want to use Office Interop in .NET (Core):
Create an empty .net Console app (I'm using Rider and .NET 7)
Build it with the default MSBuild (17.0 in my case at the time of writing)
Add Interop references to the project file (I don't use Nuget, only generate these in a dummy .NET Framework project while adding COM references to Office libraries), eg.
<ItemGroup>
<COMReference Include="Excel">
<Guid>{00020813-0000-0000-C000-000000000046}</Guid>
<VersionMajor>1</VersionMajor>
<VersionMinor>9</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>tlbimp</WrapperTool>
<Isolated>False</Isolated>
<EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>
</ItemGroup>
Change the solution MSBuild version to 4.0
Try to build the solution, but the project will not even load properly due to an outdated MSBuild version
Revert the MSBuild version to the default one
Build the project - success! (this is the magic part, I can't explain it :P)
When encountering problems with resolving DLLs and assemblies in general with .Net fuslogvw gave you the ability to log the binding attempts so you could see exactly where it was looking and what was going on.
There is a github issue discussing this, but it's not exactly got very much detail on what COREHOST_TRACE actually provides, nor the best way to get the output, nor how to interpret the output.
So, is COREHOST_TRACE the best option?
If so how is it used?
If not, what's the better option?
I'd like to know the answer to this general question, because it's a useful tool to have and so has uses well beyond my current problem. However I am also trying to fix a specific problem, so I've included details of that below.
I'm using...
VS 15.7.2
asp.net core 2.0
The DLL in question is native, and is being accessed via DllImport.
Interestingly the DLL is resolved when I publish a release build, but fails running locally for development builds.
Exception: System.DllNotFoundException: Unable to load DLL 'libwkhtmltox': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
The DLL in question is beinging copied to the root of the output directory:
<ItemGroup>
<ContentWithTargetPath Include="Dependencies\wkhtmltox\v0.12.4\32 bit\libwkhtmltox.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<TargetPath>libwkhtmltox.dll</TargetPath>
</ContentWithTargetPath>
</ItemGroup>
It's a long time since the original question, but as of .NET 5, there is dotnet trace. See https://learn.microsoft.com/en-us/dotnet/core/dependency-loading/collect-details.
(I found this via https://github.com/dotnet/runtime/issues/12506#issuecomment-895192112.)
For Noda Time version 1.1, the main goal is to build a Portable Class Library flavour, primarily to support Windows Phone and Windows Store apps. This means losing some functionality, so we build a desktop configuration and a PCL configuration (for each of debug, release, and "signed release").
To avoid having to work with umpteen project files, all of the 6 configurations exist in the same project file. The project file is customized to generate a property called "Portability", which is set to either "PCL" or "Desktop", like this:
<!-- Set the custom Portability property based on configuration -->
<PropertyGroup>
<Portability Condition="'$(Configuration)' == 'Debug Portable'">PCL</Portability>
<Portability Condition="'$(Configuration)' == 'Release Portable'">PCL</Portability>
<Portability Condition="'$(Configuration)' == 'Signed Release Portable'">PCL</Portability>
<!-- Default to desktop if not explicitly set above -->
<Portability Condition="'$(Portability)' == ''">Desktop</Portability>
</PropertyGroup>
We then have separate property groups for portable vs desktop, based on the above property. This is what defines the project type as "class library" or "portable class library" (along with the OutputType of Library, which is shared):
<!-- Desktop-specific properties -->
<PropertyGroup Condition="'$(Portability)' == 'Desktop'">
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
</PropertyGroup>
<!-- PCL-specific properties -->
<PropertyGroup Condition="'$(Portability)' == 'PCL'">
<MinimumVisualStudioVersion>10.0</MinimumVisualStudioVersion>
<ProjectGuid>{c78f6992-28d7-45c9-a4c1-6eaa649f3247}</ProjectGuid>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkProfile>Profile2</TargetFrameworkProfile>
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
</PropertyGroup>
This generally works very well - I have the different solution configurations, so I can build and test everything at a moment's notice, and I only need to add each new .cs file to a single project file. So under Visual Studio 2012 Professional (which is what I use) I'm perfectly happy.
The problem comes when I try to load the solution in Visual Studio Express (either VS2010 or VS2012). While the solution is loading, it fails with an error to say that some projects can't be loaded, and the two projects which build PCL versions then have build output like this:
C:\Path\To\NodaTime.csproj : error :
The project file 'C:\Path\To\NodaTime.csproj' cannot be opened.
There is a missing project subtype.
Subtype: '{786C830F-07A1-408B-BD7F-6EE04809D6DB}'
is unsupported by this installation.
(Reformatted for clarity.) The two projects refuse to load, so you can't even browse the source code.
I had really hoped that even if Express users couldn't build the PCL versions, they'd still be able to load up the solution, browse the source, and build non-PCL versions. MSBuild works from the command line, but that's not as friendly.
I've tried removing the solution configurations which refer to the PCL project configurations, and that doesn't help. Weirdly enough, even commenting out the XML element, like this:
<!--
<ProjectTypeGuids>(Guids as before)</ProjectTypeGuids>
-->
doesn't help - although deleting the line does. It's as if Visual Studio isn't actually loading it as a real XML file. (I haven't tried loading the version with the commented out element into VS Pro.)
I could go down the route of generating separate PCL project files if I need to, but I'd really like to avoid it if possible - it would make normal development more painful. Likewise I could generate Express-only PCL and solution files, but again I'd rather not - it just feels wrong.
While ideally I'd like to support VS Express both 2010 and 2012, if there's a solution which only works for 2012, that would be a good start.
So, is there any way of persuading Visual Studio Express that it really can load a project despite a conditional property group (whose condition isn't met) referring to a project type it doesn't know about?
David Kean's comment here gave me the answer I'm using for the moment:
or remove the <ProjectTypeGuid> element entirely - this will opt you of "portable" enhancements, such as a UI for changing the target framework, etc
I've tried that, and it works like a dream. On machines which have everything appropriately installed, you can then even build the PCL version under Express! I've verified that the resulting binary really is a PCL, and it seems fine.
I wouldn't be surprised to find that I ran into some problems later on, but for the moment this works fine for me. I can easily live without the enhancements in Visual Studio - it was already confused by my project having very different build configurations, so I don't think I was getting much benefit anyway.
As answered here:
Visual Studio 2012 Express with Portable Class Library?
and here:
Share functionality using Portable Class Libraries
Portable Class library projects are not supported in the express
SKU...need a higher SKU for the full support. Of course the binary
(e.g., using it as a reference) is, just not the project/source
support.
I can imagine there is a simple reason for that - there are different types of VS2012 Express editions: for Windows Phone development, for Desktop apps, for Windows 8 apps... I bet the Windows Phone Express edition does not know about the Windows Phone project type and vice versa. This could be the simple reason why PCLs are not supported as well.
Although the idea of Portable Class Libraries is really nice, it's still quite limited in many ways, for instance you cannot use conditional compilation using #if xy as far as I know. If you really have to use Visual Studio Express for development, then it might be better to use projects for each platform with referenced source files and conditional compilation.
my scenario is the following (Win7, VS2010, .NET 4.0):
I have a .NET assembly from an external company compiled for "Any CPU" (verified with corflags.exe). This assembly loads a native dll also from the external company. This native dll exists in two versions - x86 and x64. I have both available.
When I create a console application, add the .NET assembly (while making sure one of the native DLLs can be found by the .NET assembly), create an instance of one of the classes from that .NET library and start the program everything is fine.
However when I follow the exact same steps within a WCF Service, I am getting a BadImageFormatException. Now the obvious thing is search for the error in the targeted platform (I tried "Any CPU", "x86", "x64") or trying to exchange the native DLL (I tried both x86 and x64), but that does not help. I tried all combinations btw...
Does anyone have an idea what the problem might be?
Lars
P.S.: I read BadImageFormatException encountered with WcfSvcHost and IIS WCF host and as the author states he solved a similar problem by corflagging WcfSvcHost.exe as 32BIT, but WcfSvcHost.exe is strong named so I can't resign it. Not sure how he got it to work...
You could drop the dependency on WcfSvcHost, and host/debug the service in a local IIS where you can explicitly set the AppPool to either 32 or 64 bit. That's what I'd do.
Has anyone had success making an msbuild file that will publish a Web Application, not the old 2.0 web site but a Web Application?
This is not what I am looking for:
<MSBuild Projects="eRx.Web.SecureSiteShell.csproj" Properties="Configuration=Debug;OutDir=$(OutputFolder)\$(OutputWeb)\bin\;WebProjectOutputDir=$(OutputFolder)\$(OutputWeb)\" Targets="ResolveReferences;_CopyWebApplication" />
I tried simply using 'targets:Publish' but I get : Skipping unpublishable project.
Apparently this just isn't possible. My first hint was getting absolutely no response from this site.
I began to look into making a web setup project but was unsatisfied at having to edit the installation dialogues to get a custom installation folder. All I really need is something that will copy the published output of a Web Application (not Web Site you 2.0 peeps).
I think I have cheated the system by creating a simple Windows Setup program. Surprisingly I am able to include the primary output of my web application which satisfies my need. I DO have to manually add each projects debug symbols if I want them so the process can be lengthly but doable.
Like I said, not completely satisfied because I wanted to get the files in a nice deploy folder for my QA group to work with but feeding them an MSI has its advantages I suppose.
I leave this for anyone to comment on. I still can't believe I can't do this from msBuild or any other tool.