I am trying to get the Unmanaged Export Basic sample working.
The steps I am following:
Create a new classlibrary project.
Add the UnmanagedExports with
nuget.
Change CPU target to x86.
Add the code from the tutorial I am following to the .cs file.
Build
The project is built sucesfully, but when I inspect my dll with DLL Export Viewer I can not see any of my functions.
I am using 32 bits OS and SharpDevelop 4.4 (I also have tried with other SharpDevelop versions and with 64bits OS with the same result).
My sln file:
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "test", "test\test.csproj", "{AFAA816C-65B2-4B58-9FB2-EB7482AA0F5F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x86 = Debug|x86
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{AFAA816C-65B2-4B58-9FB2-EB7482AA0F5F}.Debug|x86.ActiveCfg = Debug|x86
{AFAA816C-65B2-4B58-9FB2-EB7482AA0F5F}.Debug|x86.Build.0 = Debug|x86
{AFAA816C-65B2-4B58-9FB2-EB7482AA0F5F}.Release|x86.ActiveCfg = Release|x86
{AFAA816C-65B2-4B58-9FB2-EB7482AA0F5F}.Release|x86.Build.0 = Release|x86
EndGlobalSection
EndGlobal
My csproj file:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
<PropertyGroup>
<ProjectGuid>{AFAA816C-65B2-4B58-9FB2-EB7482AA0F5F}</ProjectGuid>
<ProjectTypeGuids>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<OutputType>Library</OutputType>
<RootNamespace>test</RootNamespace>
<AssemblyName>test</AssemblyName>
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
<AppDesignerFolder>Properties</AppDesignerFolder>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Platform)' == 'x86' ">
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<OutputPath>bin\Debug\</OutputPath>
<DebugSymbols>True</DebugSymbols>
<DebugType>Full</DebugType>
<Optimize>False</Optimize>
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
<DefineConstants>DEBUG;TRACE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<OutputPath>bin\Release\</OutputPath>
<DebugSymbols>False</DebugSymbols>
<DebugType>None</DebugType>
<Optimize>True</Optimize>
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
<DefineConstants>TRACE</DefineConstants>
</PropertyGroup>
<ItemGroup>
<Reference Include="RGiesecke.DllExport.Metadata">
<HintPath>..\packages\UnmanagedExports.1.2.7\lib\net\RGiesecke.DllExport.Metadata.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="MyClass.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
My cs file:
using System;
using System.Collections.Generic;
using System.Text;
using RGiesecke.DllExport;
using System.Runtime.InteropServices;
namespace Testme
{
class Test
{
[DllExport("Add", CallingConvention = CallingConvention.StdCall)]
public static int Add(int left, int right)
{
return left + right;
}
........
Dll Export Viewer of my dll
Dll Export Viewer of a working dll (downloaded from the tutorial web)
Both dlls (mine and the downloaded) have the same size for my OS but not for the DLL Export Viewer.
What I am missing??
I had the same problem and I solved it this way,
You need add the follow line below this line csproj file
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- Remove this comment and insert This line-->
<Import Project="packages/UnmanagedExports.1.2.7/tools/RGiesecke.DllExport.targets" Condition="Exists('packages/UnmanagedExports.1.2.7/tools/RGiesecke.DllExport.targets')"/>
Check file exist in your folder "packages/UnmanagedExports.1.2.7/tools/RGiesecke.DllExport.targets"
Related
I have a C# WPF project in Visual Studio 2019 that I'm trying to set the AssemblyVersion and AssemblyFileVersion of. The idea being that I am trying to set them to "0.Months since project started.Days since this month started.Minutes since midnight" to help with version control
I have a Text Template file with the code below
using System.Reflection;
[assembly: AssemblyVersion("<#= this.Release #>.<#= this.MonthsSinceProjectStarted #>.<#= this.DaysSinceMonthStarted #>.<#= this.MinutesSinceMidnight #>")]
[assembly: AssemblyFileVersion("<#= this.Release #>.<#= this.MonthsSinceProjectStarted #>.<#= this.DaysSinceMonthStarted #>.<#= this.MinutesSinceMidnight #>")]
<#+
int Release = 0;
static DateTime ProjectStartedDate = new DateTime(year: 2022, month: 5, day: 20);
int MonthsSinceProjectStarted = (int)((Int32.Parse(DateTime.Now.ToString("yyyy")) * 12) + Int32.Parse(DateTime.Now.ToString("MM"))) - ((ProjectStartedDate.Year * 12) ProjectStartedDate.Month);
int DaysSinceMonthStarted = (int)Int32.Parse(DateTime.Now.ToString("dd"));
int MinutesSinceMidnight = (int)DateTime.UtcNow.TimeOfDay.TotalMinutes;
#>
My .csproj file also looks like this
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net5.0-windows</TargetFramework>
<RootNamespace>LPG_Launcher</RootNamespace>
<UseWPF>true</UseWPF>
<Company>LowPoly Games</Company>
<Authors>LowPoly Games</Authors>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<PlatformTarget>x64</PlatformTarget>
<DebugType>none</DebugType>
<DebugSymbols>false</DebugSymbols>
<TransformOnBuild>true</TransformOnBuild>
<OverwriteReadOnlyOutputFiles>true</OverwriteReadOnlyOutputFiles>
<TransformOutOfDateOnly>false</TransformOutOfDateOnly>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<Optimize>true</Optimize>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<DebugType>full</DebugType>
<DebugSymbols>true</DebugSymbols>
<PlatformTarget>x64</PlatformTarget>
<TransformOnBuild>true</TransformOnBuild>
<OverwriteReadOnlyOutputFiles>true</OverwriteReadOnlyOutputFiles>
<TransformOutOfDateOnly>false</TransformOutOfDateOnly>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DebugType>full</DebugType>
<DebugSymbols>true</DebugSymbols>
<TransformOnBuild>true</TransformOnBuild>
<OverwriteReadOnlyOutputFiles>true</OverwriteReadOnlyOutputFiles>
<TransformOutOfDateOnly>false</TransformOutOfDateOnly>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<DebugType>none</DebugType>
<DebugSymbols>false</DebugSymbols>
<PlatformTarget>x64</PlatformTarget>
<TransformOnBuild>true</TransformOnBuild>
<OverwriteReadOnlyOutputFiles>true</OverwriteReadOnlyOutputFiles>
<TransformOutOfDateOnly>false</TransformOutOfDateOnly>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<Optimize>true</Optimize>
</PropertyGroup>
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="if $(ConfigurationName) == Release (
del /S *.pdb
)" />
</Target>
<PropertyGroup>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<TransformOnBuild>true</TransformOnBuild>
<OverwriteReadOnlyOutputFiles>true</OverwriteReadOnlyOutputFiles>
<TransformOutOfDateOnly>false</TransformOutOfDateOnly>
</PropertyGroup>
<ItemGroup>
<None Include="VersionAutoIncrementer.tt">
<Generator>TextTemplatingFileGenerator</Generator>
<LastGenOutput>VersionAutoIncrementer.txt</LastGenOutput>
</None>
</ItemGroup>
<ItemGroup>
<Service Include="{508349b6-6b84-4df5-91f0-309beebad82d}" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v16.0\TextTemplating\Microsoft.TextTemplating.targets" />
</Project>
When I clean and build my solution, it builds a .cs file with the below code in it
using System.Reflection;
[assembly: AssemblyVersion("0.0.20.673")]
[assembly: AssemblyFileVersion("0.0.20.673")]
But checking the properties of the "LPG Launcher.exe" thats built is showing the version numbers to be "0.0.0.0". Is this a suitable method of setting these values and if so, what am I doing incorrectly?
After checking from information given in the comments, I've determined that the .cs file being built by the Text Template wasn't being included in the build process. Thanks for the help everyone
Is there a simply way to load and call functions of a C# dll from F# both located in the same solution?
I've set up this very simple example:
My solution is called FSharpInterop and contains two project
One C# library called CSharpComm "CSharpComm\CSharpComm.csproj"
One F# project called FSharpInterop "FSharpInterop\FSharpInterop.fsproj"
The C# library provides this simple service:
using System;
namespace CSharpComm
{
public class CSharpService
{
public string Request()
{
return "Hello World provided by C#";
}
}
}
1st attempt: open command
After adding the C# project in the F# reference (right click on the References icon Add Reference... > Projects > Select CSharpComm), I tried to run this line in F#:
open CSharpComm
Error message: InteropHelloWorld.fsx(1,6): error FS0039: The namespace or module 'CSharpComm' is not defined.
2nd attempt: #r command
Tried to run:
#r "C:\src\FSharpInterop\CSharpComm\bin\Debug\CSharpComm.dll"
or
#r "C:\src\FSharpInterop\CSharpComm\bin\Debug\CSharpComm"
This ends up with the error message: Invalid directive. Expected '#r "<file-or-assembly>"'.
3rd attempt: Nuclear option
I've tried using the interop service library:
open System.Runtime.InteropServices
module InteropWithNative =
[<DllImport(#"C:\src\FSharpInterop\CSharpComm\bin\Debug\CSharpComm.dll", CallingConvention = CallingConvention.Cdecl)>]
extern void Request()
InteropWithNative.Request()
Error message: > System.EntryPointNotFoundException: Unable to find an entry point named 'Request' in DLL 'C:\src\FSharpInterop\CSharpComm\bin\Debug\CSharpComm.dll'. at FSI_0005.InteropWithNative.Request() at <StartupCode$FSI_0005>.$FSI_0005.main#()
Here I guess I need to instantiate a CSharpService object first but the Interop doesn't let me create a ctor in F#. Also, even if I manage to call the C# service that way, that looks a bit overkill for two technologies that supposes to cohabit easily.
Last attempt: Stack overflow
Following this question Import/open DLLs in F#, I tried to add an <ItemGroup> in my F# project but didn't find where and how I can do that (I thought Visual Studio would take care of that when adding the reference project).
Additional info on my solution
F# App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
</startup>
</configuration>
F# packages.config
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="FSharp.Core" version="5.0.1" targetFramework="net48" />
<package id="System.ValueTuple" version="4.5.0" targetFramework="net48" />
</packages>
[Edit] FSharpInterop.fsproj
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>425bd4f6-3577-4c20-9ceb-3f95609706d8</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>FSharpInterop</RootNamespace>
<AssemblyName>FSharpInterop</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<UseStandardResourceNames>true</UseStandardResourceNames>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<Tailcalls>false</Tailcalls>
<OutputPath>bin\$(Configuration)\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<WarningLevel>3</WarningLevel>
<PlatformTarget>AnyCPU</PlatformTarget>
<DocumentationFile>bin\$(Configuration)\$(AssemblyName).XML</DocumentationFile>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<Tailcalls>true</Tailcalls>
<OutputPath>bin\$(Configuration)\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<WarningLevel>3</WarningLevel>
<PlatformTarget>AnyCPU</PlatformTarget>
<DocumentationFile>bin\$(Configuration)\$(AssemblyName).XML</DocumentationFile>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup>
<MinimumVisualStudioVersion Condition="'$(MinimumVisualStudioVersion)' == ''">11</MinimumVisualStudioVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(FSharpTargetsPath)' == '' AND Exists('$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets') ">
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets</FSharpTargetsPath>
</PropertyGroup>
<Import Project="$(FSharpTargetsPath)" />
<ItemGroup>
<Compile Include="AssemblyInfo.fs" />
<Compile Include="Program.fs" />
<None Include="App.config" />
<Content Include="packages.config" />
<None Include="InteropHelloWorld.fsx" />
</ItemGroup>
<ItemGroup>
<Reference Include="FSharp.Core">
<HintPath>..\packages\FSharp.Core.5.0.1\lib\netstandard2.0\FSharp.Core.dll</HintPath>
</Reference>
<Reference Include="mscorlib" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Numerics" />
<Reference Include="System.ValueTuple">
<Private>True</Private>
</Reference>
<Reference Include="CSharpComm">
<HintPath>..\CSharpComm\bin\Debug\CSharpComm.dll</HintPath>
</Reference>
</ItemGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
Disclaimer: This is my first ever attempt at F#
Add a reference to the C# project from the F# project
Unsure why this "doesn't work" (reference the project, not the dll as #user1981 stated)
C# Library Project in Solution:
using System;
namespace SampleLibInCSharp
{
public class CsharpService
{
// a static function to do trivial test....
public static string Request()
{
return "Hello World provided by C#";
}
}
}
Trivial F# Console App (from VS 2019 template), set as startup app in VS: Program.fs
open System
open SampleLibInCSharp
// Define a function to construct a message to print
let from whom =
sprintf "from %s" whom
[<EntryPoint>]
let main argv =
let message = from "F#" // Call the function
printfn "Hello world %s" message
let cs = CsharpService.Request()
printfn "ola %s" cs
0 // return an integer exit code
Run the F# console app:
Hello world from F#
ola Hello World provided by C#
Note: I did see some odd red squiglies denoting some syntax error with the message you posted, but it seems more like a VS artifact or bug. Rebuilding and/or running is fine (as above).
As stated, this is a trivial F#/C# test only...
Hth...
I am using .Net 4.8 Console project with such NuGet packages
Microsoft.CodeAnalysis.CSharp.3.8.0
Microsoft.CodeAnalysis.CSharp.Workspaces.3.8.0
Microsoft.CodeAnalysis.Workspaces.MSBuild.3.8.0
Program.cs
MSBuildWorkspace workspace = MSBuildWorkspace.Create();
Solution currSolution = workspace.OpenSolutionAsync(#"C:\Users\***\source\repos\WpfApp5\WpfApp5.sln").Result;
OpenSolutionAsync throwing exception
Object reference not set to an instance of an object.
Stack trace
at Microsoft.Build.Shared.BuildEnvironmentHelper.get_Instance()
at Microsoft.Build.Utilities.Traits.get_Instance()
at Microsoft.Build.Evaluation.ProjectCollection..ctor(IDictionary`2 globalProperties, IEnumerable`1 loggers, IEnumerable`1 remoteLoggers, ToolsetDefinitionLocations toolsetDefinitionLocations, Int32 maxNodeCount, Boolean onlyLogCriticalEvents, Boolean loadProjectsReadOnly)
at Microsoft.CodeAnalysis.MSBuild.Build.ProjectBuildManager.StartBatchBuild(IDictionary`2 globalProperties)
at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.Worker.<LoadAsync>d__19.MoveNext()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.<LoadSolutionInfoAsync>d__21.MoveNext()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace.<OpenSolutionAsync>d__24.MoveNext()
I found only this issue and its looks like this error already not fixed for 5 years? Is there any solution or workaround that allows to open solution?
I was facing a similar issue in a console app (.NET framework 4.7.2). I followed the instructions listed in Using MSBuildWorkspace and it solved the issue for me.
The solution was to remove all Microsoft.Build.* references other than Microsoft.Build.Locator, and to add MSBuildLocator.RegisterDefaults(); before attempting to create a workspace.
This is what the code looks like:
using Microsoft.Build.Locator;
using Microsoft.CodeAnalysis.MSBuild;
...
MSBuildLocator.RegisterDefaults();
using (var workspace = MSBuildWorkspace.Create())
{
// Use MSBuildWorkspace...
}
Try and remove the packages as a .net framework 4.8 should not need them as it uses references to the framework, not NuGet
Update after comment.
When I create a new Console application with .net framework and unload it the following csproj file is shown, there is no need NuGet Packages.
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{F1E9931B-351C-41B2-AC30-18E41A244675}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>ConsoleApp2</RootNamespace>
<AssemblyName>ConsoleApp2</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
After validate you can get it back by right-clicking the solution again and select "reload"
It seems like the DebuggerDisplayAttribute is not having any effect in Visual Studio 2017 (15.9.4) with Resharper 2018.2.3.
Placing the attribute in AssemblyInfo.cs, or in Program.cs, has no discernible effect.
I am targeting .Net Framework 4.7.2. Changing the framework version also has no discernible effect.
I have verified that "Show raw structure of objects in variables windows" is unchecked in Tools -> Options -> Debugging -> General. I even checked it, closed VS, reopened VS, and unchecked it, just to be sure. No effect.
Placing the attribute on a custom class does have an effect. It seems that the attribute is only being ignored when at the assembly level.
This works as expected in VS 2015 (with the same version of Resharper).
Starting VS 2017 in safe mode (using devenv.exe /safemode) has no effect.
Updating VS 15.9.4 -> 15.9.7 has no effect.
Here is a very basic console application. Despite the attribute, the dt variable appears as {2/14/2019 10:35:38 AM} in my watch window.
[assembly: DebuggerDisplay("Foo", Target = typeof(DateTime))]
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
var dt = DateTime.Now;
Debugger.Break();
}
}
}
If I use ILSpy to decompile my console application, I can see these attributes applied:
[assembly: Debuggable(
DebuggableAttribute.DebuggingModes.Default |
DebuggableAttribute.DebuggingModes.DisableOptimizations |
DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints |
DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: DebuggerDisplay("Foo", Target = typeof(DateTime))]
Why isn't the attribute doing anything? How do I even begin to debug this?
Edit: Complete source files as requested.
ConsoleApp1.csproj
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{EBBA72C6-5087-4D8E-9F2C-B968ABD59EAA}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>ConsoleApp1</RootNamespace>
<AssemblyName>ConsoleApp1</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
app.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
</configuration>
AssemblyInfo.cs:
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle("ConsoleApp1")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ConsoleApp1")]
[assembly: AssemblyCopyright("Copyright © 2019")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
[assembly: Guid("ebba72c6-5087-4d8e-9f2c-b968abd59eaa")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
I've built the project from the sources you provided, and can't reproduce the problem:
This means that on the fresh installation of VS 2017 the feature must work. So your installation of Visual Studio must be somehow corrupt.
After investigation in comments I'd suggest to do an installation repair, it should fix the problems.
I have two .csproj projects, with the exact same source code:
using Newtonsoft.Json.Linq;
using System;
using System.Reflection;
class Program
{
static void Main(string[] args)
{
Assembly jsonAssembly = Assembly.LoadFrom(#"C:\path\to\Newtonsoft.Json.dll");
Type reflectionType = jsonAssembly.GetType("Newtonsoft.Json.Linq.JObject");
Console.Write("Types match: " + (reflectionType == typeof(JObject)));
Console.Write("Typenames match: " + (reflectionType.FullName == typeof(JObject).FullName));
JObject cast = (JObject)Activator.CreateInstance(reflectionType);
Console.Write("Success!");
}
}
Both .csproj files have an identical reference to Newtonsoft.Json:
<Reference Include="Newtonsoft.Json">
<HintPath>C:\path\to\Newtonsoft.Json.dll</HintPath>
</Reference>
The only difference between the two projects is that I created the first one using .NET Core 2.0, and the second one using .NET Framework 4.6.1.
Framework:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{A6D2C332-B60D-41F1-9983-DE10065973A1}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>ConsoleApp1</RootNamespace>
<AssemblyName>ConsoleApp1</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json">
<HintPath>C:\path\to\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
Core:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
</PropertyGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json">
<HintPath>C:\path\to\Newtonsoft.Json.dll</HintPath>
</Reference>
</ItemGroup>
</Project>
When I run the above code using .NET Core, I get the following response:
Types match: True
Typenames match: True
Success!
When I run the above code using .NET Framework, I get the following response:
Types match: False
Typenames match: True
Unhandled Exception: System.InvalidCastException: [A]Newtonsoft.Json.Linq.JObject cannot be cast to [B]Newtonsoft.Json.Linq.JObject
Why do .NET Framework and .NET Core work differently when loading assemblies via reflection?
The problem maybe is, that in .NET Framework you use 2 different assemblies (2 different files on disk). Try to run the .NET Framework project in debug mode and see where these types are coming from or add these lines.
Console.Write("Reflection type module: " + (reflectionType.Module.FullyQualifiedName));
Console.Write("Static type module: " + (typeof(JObject).Module.FullyQualifiedName));
Inspired by Walter Branson's answer, I did some research and found how some of the Load methods behave.
/* Loads closest assembly given by FullName loaded by default, in this case it is from the same location as executable */
Assembly jsonAssembly1 = Assembly.Load(#"Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed");
/* Loads assembly exaclty from the file specified by path */
Assembly jsonAssembly2 = Assembly.LoadFile($#"{pathToAssembly}\Newtonsoft.Json.dll");
/* In NET.Framework loads same assembly as LoadFrom, but in .NET Core loads same assembly as Load */
Assembly jsonAssembly3 = Assembly.LoadFrom($#"{pathToAssembly}\Newtonsoft.Json.dll");
I believe this is occurring because the reference compare fails for .NET. When you look at the objects there is a different handle in .NET. When you look at the objects in core they both have same handle.
I think this occurs because you are loading the assembly from file. Try loading the assembly by its fully qualified name.
Assembly jsonAssembly = Assebmly.Load("NewtonSoft.Json,Version=12.0.0.0,Culture=neutral,PublicKeyToken=30adfe6b2a6aeed")
.NET Framework one copies the .dll that you are referencing to its executable directory. So the loaded .dlls are actually different.
Try to change the path from "C:\path\to\Newtonsoft.Json.dll" in .NET Framework project to "Newtonsoft.Json.dll", the result will be the same as in .NET Core one.