I'm working with C code where the production compiler and CI runs in Linux but the development environment is Windows and VS. The test framework used is NUnit, which is written in C# and imported as a DLL via Nuget.
I'm used to C and writing target oriented CMake but VS solutions and .NET is unknown territory for me and the weird mix of C and C# doesn't make things easier. To complicate things further there is a tool generating a mock for the platform code which the C code is to run on (I think the platform Mock is written in C++).
So, I'm using CMake 3.15.3 and Visual Studio 2017, and the setup I need to get working is the following.
A top CMakeLists.txt like:
cmake_minimum_required(VERSION 3.3)
project(MyApplication)
include(SUTWrapper)
add_subdirectory(source)
add_subdirectory(suttest)
A CMakeLists.txt in ./source/ like:
find_package(PlatformInterface)
add_library(${CMAKE_PROJECT_NAME} STATIC
MyApplication.c)
target_link_libraries(${CMAKE_PROJECT_NAME}
PUBLIC
PlatformInterface)
A CmakeLists.txt in ./suttest/ like:
enable_language(CSharp)
add_executable(${CMAKE_PROJECT_NAME}_tests
MyApplication_suite1.cs
Program.cs
TestUtils.cs)
add_sut_wrapper()
add_test(
NAME
Test${CMAKE_PROJECT_NAME}
COMMAND
MyApplication_tests.exe
CONFIGURATIONS
Debug)
And in the cmake folder containing all the CMake modules, the file SUTWrapper.cmake:
function(add_sut_wrapper)
set(PATH_TO_WRAPPER path/to/wrapper/here)
add_library(${CMAKE_PROJECT_NAME}_wrapper STATIC
${PATH_TO_WRAPPER}/foo.cs
${PATH_TO_WRAPPER}/bar.cs
${PATH_TO_WRAPPER}/baz.cs)
set_property(
TARGET ${CMAKE_PROJECT_NAME}_wrapper
PROPERTY
VS_DOTNET_REFERENCES "System")
set_property(
TARGET ${CMAKE_PROJECT_NAME}_tests
PROPERTY
VS_PACKAGE_REFERENCES "NUnit_3.7.1;NUnitLite_3.7.2")
set(PATH_TO_PLATFORM_MOCK path/to/PlatformMock/here/)
add_library(${CMAKE_PROJECT_NAME}_Platform_Mock STATIC
${PATH_TO_PLATFORM_MOCK}/Swc_${CMAKE_PROJECT_NAME}.cpp)
add_library(${CMAKE_PROJECT_NAME}_shared SHARED
../source/MyApplication.c)
target_link_libraries(${CMAKE_PROJECT_NAME}_shared
PUBLIC
PlatformInterface
${CMAKE_PROJECT_NAME}_Platform_Mock)
target_link_libraries(${CMAKE_PROJECT_NAME}_tests
PUBLIC
${CMAKE_PROJECT_NAME}_shared)
endfunction()
Then there is another file in the cmake folder, FindPlatformInterface.cmake:
add_library(PlatformInterface INTERFACE)
target_include_directories(PlatformInterface
INTERFACE
path/to/PlatformInterface/headers/here
path/to/more/PlatformInterface/headers/here)
The unorthodox use of find_package for PlatformInterface is a temporary work around and the add_sut_wrapper function is a way to handle that a whole mountain of wrapper code is already generated before this CMake project is built. I'm working with plenty of legacy forcing some odd work arounds, sorry for the weirdness.
As I understand it the NUnit setup expects the test to be built as an executable linking to a DLL of the Application code (which in turn is linked with the PlatformInterface, PlatformMock).
This all generates a VS solution when running CMake, without any warnings, but when I try to build the solution in VS I get this error:
Error CS0246 The type or namespace name 'Vector' could not be found
(are you missing a using directive or an assembly
reference?) MyApplication_tests
Vector is a namespace in the static library called MyApplication_wrapper. So obviously I link the code containing Vector. I got a similar problem before, with the namespace System and with linking to NUnit, I solved that by adding
set_property(
TARGET ${CMAKE_PROJECT_NAME}_wrapper
PROPERTY
VS_DOTNET_REFERENCES "System")
set_property(
TARGET ${CMAKE_PROJECT_NAME}_tests
PROPERTY
VS_PACKAGE_REFERENCES "NUnit_3.7.1;NUnitLite_3.7.2")
to the function add_sut_wrapper. I just can't figure out how to add the assembly reference for Vector.
I'v had to obfuscate the names and paths a bit and I tried to remove some irrelevant details but I think the essentials are there.
If you want the Vector namespace to be accessible from your MyApplication_tests target, you have to link the wrapper library containing Vector to that target. Try changing your target_link_libraries() call to include MyApplication_tests.
Also, using STATIC C# targets in CMake is discouraged, and is not guaranteed to be supported in the future. The C# terminology doesn't really use the "static" and "shared" library terms used in C/C++; rather, "netmodule" and "assembly" are typically used (see this blog post). You should use assemblies (SHARED) when defining C# libraries using CMake:
add_library(${CMAKE_PROJECT_NAME}_wrapper SHARED
${PATH_TO_WRAPPER}/foo.cs
${PATH_TO_WRAPPER}/bar.cs
${PATH_TO_WRAPPER}/baz.cs)
...
target_link_libraries(${CMAKE_PROJECT_NAME}_tests
PUBLIC
${CMAKE_PROJECT_NAME}_wrapper
${CMAKE_PROJECT_NAME}_shared)
We have an app A that has a reference to an assembly B that contains some static methods. Assembly B is in the same Visual Studio solution as app A.
We want the users of our app A to be able to write plugins. They build the plugin (at present) by creating a new Class Library solution in Visual Studio, getting the Nuget Package for app A, and adding a reference in their plugin solution to assembly B, so that the plugin code compiles.
They do not need to test their plugin, which is why the code just needs to compile, although it would be nice if they could debug their code when running it in app A.
Once their code has compiled, the DLL for the plugin is put in a share and given to a different team (bureaucracy I know) who put it with the rest of app A's DLLs.
I would like the plugin DLL to use the assembly B DLL that is with all of app A's DLLs.
When I run app A, the Activator class picks up the plugin DLL and correctly creates an instance, but as soon as one of the static methods from assembly B is called, the plugin throws a MissingMethodException.
Things I have tried:
The plugin solution definitely works fine if you create it and compile it within application A's Visual Studio solution.
App A uses framework .Net 4.5, assembly B uses framework .Net 4.0, I have tried building the plugin with both frameworks without success.
The "Specific Version" of the reference to assembly B in the plugin solution was false in all cases tested.
I would welcome immediate solutions to this problem but also broader architectural suggestions on how to get these plugins to work. I apologise if there is a duplicate question of this, I couldn't find one.
For starters you can use "Dotpeek" to decompile dll and see if the method defination exactly matches.
It's a free software available to decompile dotnet libraries.
If you don't have access to .pdb file then i would recommend using "dotnet reflector",or "IL Spy" it will decompile without pdb files.
Also do make sure you are referencing project in visual studio not the output dll.
I managed to fix my problem as follows:
Although the plugin only directly used static methods in Assembly B, these static methods actually made a chain of calls to various OTHER assemblies.
Instead of just adding a reference to Assembly B in my plugin, I did a Nuget command:
Install-Package -Id AppA -ProjectName Plugin
And this downloaded the latest AppA to the packages folder and added a reference to EVERY dll of AppA.
Like before, it compiled, but this time when I dragged the plugin dll into the AppA bin folder, the plugin code ran without throwing an exception.
I have 2 windows machines:
Machine1 has Visual Studio 2010;
Machine2 has only .NET Framework 4.0 Client Profile without any Visual Studio or .NET Framework SDK.
Compiling one simple C# test (test.cs includes "using System.Data;"):
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe /target:exe test.cs
It works fine on Machine1.
But failed on Machine2 with:
test.cs(2,14): error CS0234: The type or namespace name 'Data' does not exist in
the namespace 'System' (are you missing an assembly reference?)
I copied the "C:\Windows\Microsoft.NET\Framework64\v4.0.30319\System.Data.dll" to the current directory but it still failed.
Added "/r:system.data.dll" when compiling will work:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe /r:system.data.dll /target:exe test.cs
Do you know the reason?
The compiler will attempt to automatically load a file named csc.rsp, a file that contains default compile options. Unless you compile with the /noconfig option. That file contains a bunch of /reference options for common .NET Framework assemblies, System.Data.dll is one of them.
There is a csc.rsp file on all my machines, it is located for example in C:\Windows\Microsoft.NET\Framework\v4.0.30319 on the one I'm using now.
So very high odds that you are using a machine that doesn't have that file. I don't know if that's specific to the Client profile, I've always avoided it. But a quick check with Windows Explorer will give you a hint.
The .NET Client Profile is a cut-down version of .NET intended for client (user interface) applications. Not all of the assemblies and classes provided in the full .NET exist in the Client Profile. If you wish to write and application that works on both, you will have to restrict yourself to just those classes and assemblies that exist in the Client Profile (as it is a subset).
You may find it more convenient to simply install the full .NET on machine 2.
Notice also that, as of .NET 4.5, the Client Profile no longer exists.
This question already has answers here:
Getting "type or namespace name could not be found" but everything seems ok?
(44 answers)
Closed 8 years ago.
I have a C# solution with several projects in Visual Studio 2010.
One is a test project (I'll call it "PrjTest"), the other is a Windows Forms Application project (I'll call it "PrjForm"). There is also a third project referenced by PrjForm, which it is able to reference and use successfully.
PrjForm references PrjTest, and PrjForm has a class with a using statement:
using PrjTest;
Reference has been correctly added
using statement is correctly in place
Spelling is correct
PrjTest builds successfully
PrjForm almost builds, but breaks on the using PrjTest; line with the error:
The type or namespace name 'PrjTest' could not be found (are you missing a using directive or an assembly reference?)
I've tried the following to resolve this:
Removed Resharper (since Resharper had no trouble recognizing the referenced project, I thought it might be worth a shot)
Removed and re-added the reference and using statement
Recreated PrjForm from scratch
PrjForm currently resides inside the PrjTest folder, I tried moving it to an outside folder
Loaded the solution on a different computer with a fresh copy of VS 2010
I have done my homework and spent far too long looking for an answer online, none of the solutions has helped yet.
What else could I try?
See this question.
Turns out this was a client profiling issue.
PrjForm was set to ".Net Framework 4 Client Profile"
I changed it to ".Net Framework 4", and now I have a successful build.
Thanks everyone!
I guess it figures that after all that time spent searching online, I find the solution minutes after posting, I guess the trick is knowing the right question to ask..
In my case I had:
Referenced DLL : .NET 4.5
Project : .NET 4.0
Because of the above mismatch, the 4.0 project couldn't see inside the namespace of the 4.5 .DLL. I recompiled the .DLL to target .NET 4.0 and I was fine.
PrjForm was set to ".Net Framework 4 Client Profile" I changed it to ".Net Framework 4", and now I have a successful build.
This worked for me too. Thanks a lot. I was trying an RDF example for dotNet where in I downloaded kit from dotnetrdf.
NET4 Client Profile:
Always target NET4 Client Profile for all your client desktop applications (including Windows Forms and WPF apps).
NET4 Full framework:
Target NET4 Full only if the features or assemblies that your app need are not included in the Client Profile. This includes:
If you are building Server apps, Such as:
ASP.Net apps
Server-side ASMX based web services
If you use legacy client scenarios, Such as:
o Use System.Data.OracleClient.dll which is deprecated in NET4 and not included in the Client Profile.
Use legacy Windows Workflow
Foundation 3.0 or 3.5 (WF3.0 , WF3.5)
If you targeting developer scenarios and need tool such as MSBuild or need access to design assemblies such as System.Design.dll
Another thing that can cause this error is having NuGet packages that have been built with a newer version of .NET.
The original error:
frmTestPlanSelector.cs(11,7): error CS0246: The type or namespace name 'DatabaseManager'
could not be found (are you missing a using directive or an assembly reference?)
Further up in the log I found this:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(1605,5): warning MSB3275: The primary reference "[redacted]\DatabaseManager\bin\Release\DatabaseManager.dll" could not be resolved because it has an indirect dependency on the assembly "System.Data.SQLite, Version=1.0.94.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139" which was built against the ".NETFramework,Version=v4.5" framework. This is a higher version than the currently targeted framework ".NETFramework,Version=v4.0".
The solution was to re-install the NuGet packages:
http://docs.nuget.org/docs/workflows/reinstalling-packages
I solved mine because the other project was coded with .NET 4.5 and the other one was coded 4.0
The using statement refers to a namespace, not a project.
Make sure that you have the appropriately named namespace in your referenced project:
namespace PrjTest
{
public class Foo
{
// etc...
}
}
Read more about namespaces on MSDN:
Using Namespaces
I encountered this issue it turned out to be.
Project B references Project A.
Project A compiled as A.dll (assembly name = A).
Project B compiled as A.dll (assembly name A).
Visual Studio 2010 wasn't catching this. Resharper was okay, but wouldn't compile. WinForms designer gave misleading error message saying likely resulting from incompatbile platform targets.
The solution, after a painful day, was to make sure assemblies don't have same name.
It is also possible, that the referenced projects targets .NET 4.0, while the Console App Project targets .NET 4.0 Client Library.
While it might not have been related to this particular case, I think someone else can find this information useful.
The compiled dll should have public Class.
I had the same issue. The target frameworks were fine for me. Still it was not working.
I installed VS2010 sp1, and did a "Rebuild" on the PrjTest. Then it started working for me.
Other problem that might be causing such behavior are build configurations.
I had two projects with configurations set to be built to specific folders.
Like Debug and Any CPU and in second it was Debug and x86.
What I did I went to Solution->Context menu->Properties->Configuration properties->Configuration and I set all my projects to use same configurations Debug and x86 and also checked Build tick mark.
Then projects started to build correctly and were able to see namespaces.
Changing the framework to
.NET Framework 4 Client Profile
did the job for me.
For COM/ActiveX references, VS 2012 will show this error right on using statement. Which is quite funny, since it's saying that may be you are missing a using statement.
To solve this: register the actual COM/ActiveX dll even if it's in the neighbor project, and add a reference through COM channel, not project channel. It will add Interop.ProjectName instead of ProjectName as a reference and this solves this strange bug.
If your project (PrjTest) does not expose any public types within the PrjTest namespace, it will cause that error.
Does the project (PrjTest) include any classes or types in the "PrjTest" namespace which are public?
just changed Application's target framework to ".Net Framework 4".
And error got Disappeared.
good luck;
:D
check your Project Properties, your Reference Paths should be empty like this:
Regards
I have a class library project which uses a namespace (e.g., "Cosmos.Creator.Util"). I then create a solution and windows forms application to test the library. From the windows form application, I add a reference to the library. So now I have two projects open in visual studio, a class library and a windows forms project. The forms project references the library.
When I edit my form's code, code autocompletion works correctly for the namespace that I use in the library. E.g., if I type "using Cosmos." I get autocomplete options like "Creator". But now if I build my solution, all of the "Cosmos" are red-underlined with the compile error: "The type or namespace name "Cosmos" could not be found (are you missing a using directive or an assembly reference?)".
For the purposes of the form application test, I placed my library code into a folder CosmosFormExample\Cosmos. When I check the reference from the form application, the reference is to CosmosFormExample\Cosmos\bin\Debug\Cosmos.dll, so that looks okay. I looked at the GUID referenced in the solution file and it matches the GUID of the project file Cosmos.csproj.
What has happened? How has the build caused my forms application to forget about the Cosmos namespace, despite the fact that it is still referencing the library project? Thanks much in advance.
Are you using VS2010 & .NET 4? If so you're probably using .NET 4 Client Profile instead of full fledged .NET 4. Go to project properties and check your Target Framework.
for more info: http://msdn.microsoft.com/en-us/library/cc656912.aspx
you need to check the framework you are using and the framework yout library was compiled for...