Mapster.Tool fails generating mapper - c#

Mapster.Tool fails to generate any code.
The problem seems to be a class derived from CosmosClient - which i get from a nuget package.
I get this exception:
Cannot find library: Microsoft.Azure.Cosmos.Client
Unhandled exception. System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested types.
Could not load file or assembly 'Microsoft.Azure.Cosmos.Client, Version=3.16.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The system cannot find the file specified.
at system.Reflection.RuntimeModule.GetTypes(RuntimeModule module)
at System.Reflection.RuntimeModule.GetTypes()
at System.Reflection.Assembly.GetTypes()
at Mapster.Tool.Extensions.Scan(CodeGenerationConfig config, Assembly assembly) in D:\git\Mapster\src\Mapster.Tool\Extensions.cs:line 177
at Mapster.Tool.Program.GenerateModels(ModelOptions opt) in D:\git\Mapster\src\Mapster.Tool\Program.cs:line 123
at CommandLine.ParserResultExtensions.WithParsed[T](ParserResult`1 result, Action`1 action)
at Mapster.Tool.Program.Main(String[] args) in D:\git\Mapster\src\Mapster.Tool\Program.cs:line 17
System.IO.FileNotFoundException: Could not load file or assembly
'Microsoft.Azure.Cosmos.Client, Version=3.16.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The system cannot find the file specified.
File name: 'Microsoft.Azure.Cosmos.Client, Version=3.16.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'
Everything works fine when i disable the mapster build target.
Also, Microsoft.Azure.Cosmos.Client.dll exists in the target directory.
Soooo.. what am i doing wrong?
I dont understand why mapster cant load that assembly.
There also seems to be no way to make mapster ignore that class.
Heres the code.
using Mapster;
using Microsoft.Azure.Cosmos;
using System;
namespace MapsterTest
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
}
}
public class ApplicationDbClient : CosmosClient
{
public ApplicationDbClient() : base("ConnectinString")
{ }
}
[AdaptTo(typeof(MyModelDto)), GenerateMapper]
public class MyModel
{
public string SomeProperty { get; set; }
}
public class MyModelDto
{
public string SomeProperty { get; set; }
}
}
my csproj file:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Mapster" Version="7.1.5" />
<PackageReference Include="Microsoft.Azure.Cosmos" Version="3.16.0" />
</ItemGroup>
<Target Name="Mapster" AfterTargets="AfterBuild">
<Exec WorkingDirectory="$(ProjectDir)" Command="dotnet tool restore" />
<Exec WorkingDirectory="$(ProjectDir)" Command="dotnet mapster model -a "$(TargetDir)$(ProjectName).dll"" />
<Exec WorkingDirectory="$(ProjectDir)" Command="dotnet mapster extension -a "$(TargetDir)$(ProjectName).dll"" />
<Exec WorkingDirectory="$(ProjectDir)" Command="dotnet mapster mapper -a "$(TargetDir)$(ProjectName).dll"" />
</Target>
<ItemGroup>
<Generated Include="**\*.g.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="Models\" />
</ItemGroup>
<Target Name="CleanGenerated">
<Delete Files="#(Generated)" />
</Target>
</Project>

Turns out this was a problem with multiple runtime assemblies.
See this github issue.
This has been fixed with mapster.tool version 8.2.0

Related

How about building a C# unit test project in CMake?

I used the following methods, but I failed.
How to solve it? Or is there another way?
Looking forward to your reply. Thanks!!!
This is my CMake project:
dotnet_xunit_template.csproj.in
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<ProjectName>#PROJECT_NAME#</ProjectName>
<TargetFramework>netcoreapp2.1</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
<PackageReference Include="xunit" Version="2.4.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
</ItemGroup>
<ItemGroup>
#source_files_string#
</ItemGroup>
</Project>
UnitTest1.cs
using Xunit;
public class UnitTest1
{
[Fact]
public void Test1()
{
int i = 0;
i = 2;
}
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.8)
project(xunitproject)
set(source_files_string)
file(GLOB_RECURSE SRC_FILES ${CMAKE_CURRENT_LIST_DIR}/*.cs)
foreach(item ${SRC_FILES})
# <Compile Include="exe_test.cs" />
set(source_files_string
"${source_files_string}<Compile Include=\"${item}\" />
"
)
endforeach()
configure_file(dotnet_xunit_template.csproj.in ${PROJECT_NAME}.csproj #ONLY)
include_external_msproject(
${PROJECT_NAME} ${PROJECT_NAME}.csproj
)
Build the project into Visual Studio 2017, and the error message is as follows:
Your project does not reference ".NETFramework,Version=v4.0" framework. Add a reference to ".NETFramework,Version=v4.0" in the "TargetFrameworks" property of your project file and then re-run NuGet restore. ZERO_CHECK C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\Microsoft\NuGet\15.0\Microsoft.NuGet.targets 186

Visual Studio Code : Debugging unit tests works with net50 target framework but not with net48

I'm setting a test environment for a .net library using VS Code. I tried different configurations and after reading this article, I came up with this solution :
Project file :
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<IsPackable>false</IsPackable>
<GenerateProgramFile>false</GenerateProgramFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="nunit" Version="3.13.1" />
<PackageReference Include="NUnit3TestAdapter" Version="3.16.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
</ItemGroup>
</Project>
Program.cs
using System;
using DebugTest.App;
using DebugTest.Test;
namespace DebugTest
{
class Program
{
static void Main(string[] args)
{
UnitTests test = new UnitTests();
test.Setup();
test.TestAdd();
}
}
}
Pseudo lib
using System;
namespace DebugTest.App
{
public static class Calculator
{
public static double Add(double x, double y)
{
return x + y;
}
}
}
UnitTest.cs
using System;
using DebugTest.App;
using NUnit.Framework;
namespace DebugTest.Test
{
public class UnitTests
{
[SetUp]
public void Setup()
{
}
[Test]
public void TestAdd()
{
double x = 2d;
double y = 2d;
Assert.AreEqual(9999d, Calculator.Add(x, y));
}
}
}
With this configuration all works fine. I can :
dotnet build
dotnet test : starts the tests in terminal
launch with appropriate configuration in launch.json : If I set breakpoints, I can debug tests through main method
click on "Debug All Tests" or "Debug Test" lens in VSCode to debug tests.
Things got complicated when I tried to change the target framework from net5.0 to net48. I had to change my csproj this way :
New csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net48</TargetFramework>
<IsPackable>false</IsPackable>
<OutputType>exe</OutputType>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="nunit" Version="3.13.1" />
<PackageReference Include="NUnit3TestAdapter" Version="3.16.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
</ItemGroup>
</Project>
What still works :
dotnet build
dotnet test
What doesn't work anymore :
launch (I didn't forget to change the program path) : The program main is launched as I can see the exception for the failed test. In addition there are other warnings (The target process exited without raising CoreCLR...). If I set breakpoints in Program.cs or UnitTest.cs, they are not hit anymore
click on "Debug All Tests" or "Debug Test" lens : Raises an error in VSCode : Failed to start debugger with a stacktrace mentionning OmniSharp.
I tried many things (cleaning bin and obj folders, etc) and read many forums threads with similar problems but none of them were related to net48.
So, my question is : How can I achieve test debugging in a net48 project in VSCode ?

.NET Azure Functions - Dependency Injection Issue

On Startup.cs in my Azure Function v2 project:
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using MyCompany.MyLib.Contracts; //namespace from external library
[assembly: FunctionsStartup(typeof(Startup))]
namespace Test
{
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddTransient(typeof(Logging.ILogger<>), typeof(Logging.Logger<>));
builder.Services.AddTransient<IUserLogic, UserLogic>();
builder.Services.AddTransient<IBillingLogic, BillingLogic>(); //---> loads up from above referenced "MyCompany.MyLib.Contracts" namespace and this namespace is from externally referenced class library but with in same solution
}
}
}
The above code with my own custom classes within function app project like "EmailLogic", "Logger" works fine.
But the moment I added up custom classes to services container like "BillingLogic" from external C# library project which is added as reference project from the existing visual studio solution it throws up below issue:
"A host error has occurred during startup operation '945918c0-af3a-4d50-ab1d-ac405d4f1c7b'. [2/3/2020 2:11:02 PM] MyFunction.FunctionApp: Could not load file or assembly 'MyCompany.MyLib.Contracts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. Could not find or load a specific file. (Exception from HRESULT: 0x80131621). System.Private.CoreLib: Could not load file or assembly ''MyCompany.MyLib.Contracts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
If these lines from "referenced external projects" are removed,
using MyCompany.MyLib.Contracts;
builder.Services.AddTransient<IBillingLogic, BillingLogic>();
startup.cs works as expected but referring this external class from referenced project is must for my solution.
My Azure function csproj file:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<AzureFunctionsVersion>v2</AzureFunctionsVersion>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<AutoGenerateBindingRedirects>false</AutoGenerateBindingRedirects>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Azure.Functions.Extensions" Version="1.0.0" />
<PackageReference Include="Microsoft.Azure.Storage.Queue" Version="11.1.2" />
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Storage" Version="3.0.8" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.2.0" />
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="1.0.29" />
<PackageReference Include="NLog" Version="4.6.8" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="NLog.Extensions.AzureStorage" Version="1.1.4" />
<PackageReference Include="Microsoft.Azure.DocumentDB.Core" Version="2.9.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MyCSharpLib.DataStore\MyCSharpLib.DataStore.csproj">
<Private>true</Private>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToPublishDirectory>Always</CopyToPublishDirectory>
</None>
<None Update="host.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="local.settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
<None Update="nlog.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToPublishDirectory>Always</CopyToPublishDirectory>
</None>
</ItemGroup>
</Project>
MyCSharpLib.DataStore.csproj file:
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RuntimeIdentifier>win7-x64</RuntimeIdentifier>
<Platforms>x64</Platforms>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
<ItemGroup>
<PackageReference Include="Microsoft.Azure.Cosmos.Table" Version="1.0.6" />
<PackageReference Include="Microsoft.Azure.DocumentDB.Core" Version="2.9.2" />
<PackageReference Include="Microsoft.Azure.Storage.Blob" Version="11.1.1" />
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="Newtonsoft.Json.Bson" Version="1.0.1" />
<PackageReference Include="Polly" Version="5.3.1" />
<PackageReference Include="StackExchange.Redis" Version="1.2.6" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MyContractLib.Contracts\MyContractLib.Contracts.csproj" />
</ItemGroup>
</Project>
MyCSharpLib.DataStore
.\MyContractLib.Contracts\MyContractLib.Contracts.csproj
My Azure function csproj file:
<ProjectReference Include="..\MyCSharpLib.DataStore\MyCSharpLib.DataStore.csproj">
so
using MyCompany.MyLib.Contracts;
is coming through the ref to DataStore which then has ref to MyContractLib.Contracts
But it is not coping the dll as its silly, so either get Azure function csproj to ref MyLib.Contracts
or do this
How to set dependencies when I use .NET Standard 2.0 DLL libraries with a .NET Framework console application?
which is on all your std libs add
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
so on both your standard libs
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
</PropertyGroup>
if this does not work i will delete

Why do I have to go from x86 to msil back to x86 when I change signature of C# COM dll

I am trying to have a C# library expose it's classes/methods to a native C++ application via COM. I am using registration free com (i.e. with manifest files) so as to not have to register the COM library with Windows. I am running in to a problem where if I modify the C# library and do things like add a new class or change the name of a class then when that class is instantiated in the C++ application it throws a EETypeLoadException which my understanding means that the COM library doesn't match what the C++ app thinks it should look like. My projects are set to automatically generate the type library and manifest file for the C# library every time you build so that the C++ app will get the most recent version. To fix this error I have to modify the manifest file for the C++ app to say that the C# dll targets msil, build, then flip it back to x86 and build again. At that point the C++ program and C# program are in sync and throw no errors. I tried wiping out the output directory and obj directory to get rid of any possible cached files but this doesn't work, only toggling the manifest file back and forth.
Here is how I have my solution setup:
Create a new solution and add a C# Class Library (.Net Framework) called ExampleLib to it.
Add an interface that contains an arbitrary method:
namespace ExampleLib
{
public interface ITestClass
{
int Add(int a, int b);
}
}
Add a class with a guid attribute that uses that interface and implement the required method.
using System.Runtime.InteropServices;
namespace ExampleLib
{
[Guid("5054A38A-946A-4BB2-854B-E1A31633DD77")]
public class TestClass : ITestClass
{
public int Add(int a, int b)
{
return a + b;
}
}
}
Go in to the project properties. In the Application section click Assembly Information and check the Make assembly COM-Visible box. In the Build section set the platform target to x86 and change the Output Path to:
..\Debug\
In the Build Events section add the following to the Post-build event:
"C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.2 Tools\tlbexp.exe" "$(TargetPath)" /out:"$(TargetDir)$(TargetName).tlb"
"C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x86\mt.exe" -managedassemblyname:"$(TargetPath)" -out:"$(TargetName).manifest" -nodependency
If you have a different version of the Windows SDK installed or to a different location you will need to alter the above commands to match the locations for tblexp.exe and mt.exe.
Add a C++ Console app to the project called ExampleClient.
In the Source Files section add a stdafx.cpp file with the following code (this is boilerplate):
#include "stdafx.h"
In the ExampleClient.cpp file replace to default code from the template with the following:
#include "stdafx.h"
#include "atlbase.h"
#include <conio.h>
#ifdef DEBUG
#import "..\Debug\ExampleLib.tlb" raw_interfaces_only
#else
#import "..\Release\ExampleLib.tlb" raw_interfaces_only
#endif
using namespace ExampleLib;
int main()
{
HRESULT coInitResult = CoInitialize(0);
try
{
ITestClassPtr pTest(__uuidof(TestClass));
}
catch (_com_error _com_err)
{
wprintf(L"\n %s", _com_err.ErrorMessage());
auto _ = _getch();
}
CoUninitialize();
return 0;
}
Also in the Source Files section add ExampleClient.exe.manifest file with the following:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type="win32"
name="ExampleClient"
version="1.0.0.0">
</assemblyIdentity>
<dependency>
<dependentAssembly>
<assemblyIdentity name="ExampleLib" version="1.0.0.0" processorArchitecture="x86"/>
</dependentAssembly>
</dependency>
</assembly>
In the Header Files section add a stdafx.h file (boilerplate):
#pragma once
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
Also in the Header Files section add a targetver.h file (boilerplate):
#pragma once
#include <SDKDDKVer.h>
Right click on the C++ project and unload the project then edit the ExampleClient.vcxproj file. There are many changes to this file compared to what it currently is out of the box including precompiled header changes, not embedding the manifest, additional include directories, and copying the manifest to the output directory. To make reproducing simplier I will just include the entire file which should work fine
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<ProjectGuid>{32A23FFD-3FD3-4191-8799-3A8DD34DCB94}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>ExampleClient</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<EmbedManifest>false</EmbedManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<EmbedManifest>false</EmbedManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\$(Configuration)</AdditionalIncludeDirectories>
<AdditionalUsingDirectories>
</AdditionalUsingDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
</Link>
<PostBuildEvent>
<Command>xcopy $(ProjectName).exe.manifest ..\$(Configuration)\ /Y</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\$(Configuration)</AdditionalIncludeDirectories>
<AdditionalUsingDirectories>
</AdditionalUsingDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
</Link>
<PostBuildEvent>
<Command>
</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>Use</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
<PostBuildEvent>
<Command>xcopy $(ProjectName).exe.manifest ..\$(Configuration)\ /Y</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>Use</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="stdafx.h" />
<ClInclude Include="targetver.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="ExampleClient.cpp" />
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Manifest Include="ExampleClient.exe.manifest">
<SubType>Designer</SubType>
</Manifest>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
Now set the debugger to target x86, set your startup project to ExampleClient, and run the app. You can step through it and you will notice it runs without errors. Working as intended.
Now go in to TestClass.cs and change the class name to something like TestClass2 (doesnt matter what). And also go in to the ExampleClient.cpp and change the reference to TestClass to TestClass2. Rebuild the solution. When you step through the code you will get an error when trying to instantiate TestClass2. To fix it go to the ExampleClient.exe.manifest file and change the processorArchitecture to msil. Rebuild. Then change processorArchitecture back to x86. Rebuild. Now the app will work again.
You should be able to make changes to the C# library and as long as you change the C++ app to reflect the changes it should work. You shouldn't have to toggle processorArchitecture back and forth. There must be something getting cached somewhere but I can't figure out where.
On Windows 10, the OS seems to cache manifest loading. For an experiment I would try an experiment of "touch"-ing your exe and exe manifest files. If you don't have some kind of touch, this command line will work:
powershell (ls $1).LastWriteTime = Get-Date
where $1 is the name of the file. I have a doskey macro defined as
touch=powershell (ls $1).LastWriteTime = Get-Date
You might try just touching the exe or the manifest. On Windows 7, I used to be able to log off or restart the computer to clear the manifest cache, but Windows 10 seems to be harder to clear. So I use touch so that Windows ignores the manifest cache and loads from the new files.
(When I say "manifest cache", that's just a description of my deductions of what I think Windows is doing under the hood)

C# Winform with CefSharp app crash on publish version

I create an C# Winform application with CefSharp Project.
The application works great in the debug mode but when i try to publish it with VS2013 it's crash before the application start to run.
This is my program.cs file:
[STAThread]
static void Main()
{
AppDomain.CurrentDomain.AssemblyResolve += Resolver;
LoadApp();
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static void LoadApp()
{
var settings = new CefSettings();
settings.BrowserSubprocessPath = Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase,
Environment.Is64BitProcess ? "x64" : "x86",
"CefSharp.BrowserSubprocess.exe");
settings.CachePath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + #"\TelegramParser\CEF";
settings.IgnoreCertificateErrors = true;
settings.WindowlessRenderingEnabled = true;
settings.SetOffScreenRenderingBestPerformanceArgs();
Cef.Initialize(settings, performDependencyCheck: false, browserProcessHandler: null);
Application.Run(new Form1());
}
private static Assembly Resolver(object sender, ResolveEventArgs args)
{
if (args.Name.StartsWith("CefSharp"))
{
string assemblyName = args.Name.Split(new[] { ',' }, 2)[0] + ".dll";
string archSpecificPath = Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase,
Environment.Is64BitProcess ? "x64" : "x86",
assemblyName);
return File.Exists(archSpecificPath)
? Assembly.LoadFile(archSpecificPath)
: null;
}
return null;
}
When i checked the publish folder i only see this files:
And from the CefSharp Wiki i understand that there are couple of files that missing. Any idea what can be the problem?
I run and publish the project with Visual Studio 2013.
I'm using Any CPU for the compile.
EDIT
<ItemGroup>
<Content
Include="$(SolutionDir)packages\cef.redist.x86.3.3497.1841\CEF\**\*" Exclude="$(SolutionDir)packages\cef.redist.x86.3.3497.1841\CEF\x86\**\*;$(SolutionDir)packages\cef.redist.x86.3.2526.1362\CEF\locales\**\*.pak">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
<Visible>false</Visible>
</Content>
</ItemGroup>
<ItemGroup>
<Content Include="$(SolutionDir)packages\cef.redist.x86.3.3497.1841\CEF\**\en-GB.*;$(SolutionDir)packages\cef.redist.x86.3.3497.1841\CEF\**\en-US.*">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
<Visible>false</Visible>
</Content>
</ItemGroup>
<ItemGroup>
<Content Include="$(SolutionDir)packages\cef.redist.x86.3.3497.1841\CEF\x86\**\*">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
<Visible>false</Visible>
</Content>
</ItemGroup>
<ItemGroup>
<Content Include="$(SolutionDir)packages\CefSharp.Common.69.0.0\CefSharp\x86\**\CefSharp.BrowserSubprocess.*">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
<Visible>false</Visible>
</Content>
</ItemGroup>
<ItemGroup>
<Content
Include="$(SolutionDir)packages\cef.redist.x64.3.3497.1841\CEF\**\*" Exclude="$(SolutionDir)packages\cef.redist.x64.3.3497.1841\CEF\x64\**\*;$(SolutionDir)packages\cef.redist.x86.3.2526.1362\CEF\locales\**\*.pak">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
<Visible>false</Visible>
</Content>
</ItemGroup>
<ItemGroup>
<Content Include="$(SolutionDir)packages\cef.redist.x64.3.3497.1841\CEF\**\en-GB.*;$(SolutionDir)packages\cef.redist.x64.3.3497.1841\CEF\**\en-US.*">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
<Visible>false</Visible>
</Content>
</ItemGroup>
<ItemGroup>
<Content Include="$(SolutionDir)packages\cef.redist.x64.3.3497.1841\CEF\x64\**\*">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
<Visible>false</Visible>
</Content>
</ItemGroup>
<ItemGroup>
<Content Include="$(SolutionDir)packages\CefSharp.Common.69.0.0\CefSharp\x64\**\CefSharp.BrowserSubprocess.*">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
<Visible>false</Visible>
</Content>
</ItemGroup>
I added this and now the application crash with this error:
An unhandled exception of type 'System.IO.FileNotFoundException' occurred in App.exe
Additional information: Could not load file or assembly 'CefSharp.Core.dll' or one of its dependencies. The specified module could not be found.
Any CPU is the issue.
You can select either x64 or x86 platform.
Make sure you have added reference to CefSharp.Winforms nuget
Make sure that the platform of solution is set to x86 / x64 explicitly instead of Any CPU.
Add below runtime binding in the configuration file:
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="x86"/>
</assemblyBinding>
</runtime>
CSProj file should have below property set:
<CefSharpAnyCpuSupport>true</CefSharpAnyCpuSupport>
Refer this article - which explains step by step process of setting up CEFSharp browser in winforms.

Categories