Mono autoloading or auto namespace / class referencing - c#

I am new to Mono, just freshly installed and am trying to get the basic setup up.
Hello.cs:
using System;
using Customz;
public class Hello
{
public static int Main(string[] args)
{
Console.WriteLine( "Hello world! Customz.Beko.Wally = " + Beko.Wally() );
Console.ReadKey();
return 0;
}
}
Customz/Beko.cs:
namespace Customz
{
public class Beko
{
public static int Wally()
{
return 15;
}
}
}
Basicly, I have been working with C# previously in Unity3D's adaption of MonoDevelop and Visual Studio.
I remember, that upon compilation, all the classes / namespaces get auto referenced when they are requested. Plus, they are looked up no matter how deep they dwell within the project directory / subdirectories.
Compiling this with:
mcs "C:\Users\psycketom\Desktop\Mono-C#\test\Hello.cs"
Results in:
C:\Users\psycketom\Desktop\Mono-C#\test\Hello.cs(2,7): error CS0246: The type or namespace name `Customz' could not be found. Are you missing a using directive or an assembly reference?
Compilation failed: 1 error(s), 0 warnings
Well, I know that I am not missing a using directive, but I have a feeling that I am missing an assembly reference.
How can I fix this and achieve the Visual Studio like behavior?
Update:
I managed to compile everything in a directory by issuing:
mcs -out:app.exe "C:\Users\psycketom\Desktop\Mono-C#\test\*.cs"
While it works, it does include only files within the folder, not taking into account any subfolders residing in the folder.
How do I make it select all the files, including those residing in subfolders? (I'm starting to think that I may need a bash script or something)

You'll probably want to be using make, NAnt or some other build system rather than the raw command line. The problem is this:
Your project folder has a few files and few folders. So you have
Foo.cs
Bar.cs
Biz/Test.cs
Biz/Foobar,cs
When you use mcs -out:app.exe "C:\Users\psycketom\Desktop\Mono-C#\test\*.cs" the command line shell (NOT the compiler) will expand the * wildcard for you. So, it expands to
Foo.cs
Bar.cs
Most shells don't go recursive(maybe without a special directive?) because it's much more expensive and generally unexpected behavior.
If you're really determined to use the command line, you'll have to do something like this:
mcs -out:app.exe "C:\Users\psycketom\Desktop\Mono-C#\test*.cs" "C:\Users\psycketom\Desktop\Mono-C#\test\Biz*.cs"
Also, if you're that determined to use the command line, you'll probably want to give something like Cygwin a try. It's a million times easier to use than cmd.exe (and it seems to work well with Mono)
One more idea that I've used in the past: You can also use something like MonoDevelop to manage a solution and project files, which basically will link everything up in your program and tell the compiler what needs to be included. Outside of that though, you can easily build from the command line by using the xbuild tool and the solution file that MonoDevelop made

Related

error CS0234: The type or namespace name 'Devices' does not exist in the namespace 'Microsoft.VisualBasic' (are you missing an assembly reference?)

I am trying to go through this tutorial for on making sounds with waves using C#:
https://www.codeguru.com/dotnet/making-sounds-with-waves-using-c/
The first sample code it has you run is this, which is supposed to play a .wav file:
using Microsoft.VisualBasic;
using Microsoft.VisualBasic.Devices;
namespace MyApp
{
class Program
{
static Audio myAudio = new Audio();
static void Main()
{
myAudio.Play("m:\\crooner2.wav",
AudioPlayMode.WaitToComplete);
}
}
}
In my code, the filepath and name of the .wav file was replaced with a different one, but otherwise the code is identical. However, I get an error regarding the second line of code: error CS0234: The type or namespace name 'Devices' does not exist in the namespace 'Microsoft.VisualBasic' (are you missing an assembly reference?)
Without the Microsoft.VisualBasic.Devices call working, I have no way of running even the first exercise in the tutorial, and definitely no way of further progressing in using C# for sound manipulation.
I was expecting the code to run and play the .wav file. However, I got the error message instead.
As part of debugging, I came across this post on the Microsoft website:
https://learn.microsoft.com/en-us/dotnet/core/compatibility/visualbasic#types-in-microsoftvisualbasicdevices-namespace-not-available
I'm not sure what to make of it. It seems like it's saying it could be solved by upgrading to .Net 5 or higher, but I'm already using .Net 5. It also seems like it saying that Microsoft.VisualBasic.Devices was made obsolete with .Net Core 3.0, so I'm not sure how upgrading would make it easier to use something that was made obsolete.
It also says that certain functionality in Microsoft.VisualBasic.Devices has equivalent functionality that can be called by other means. It gives specific replacement calls for Microsoft.VisualBasic.Devices.Clock and Microsoft.VisualBasic.Devices.Ports, but nothing for Microsoft.VisualBasic.Devices.Audio, which is what I want to use in my code.
I have tried this in both Visual Studio and Visual Studio Code and get the same errors either way.
With .NET Core, you generally add references via NuGet packages. There is no NuGet package for Microsoft.VisualBasic.Forms.dll, which the documentation clearly states that type is declared in. To get that assembly reference, I believe that you need to replace this line in your project file:
<TargetFramework>net5.0</TargetFramework>
with these lines:
<TargetFramework>net5.0-windows</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>
After doing that, you should see Microsoft.WindowsDesktop.App.WindowsForms added under Dependencies -> Frameworks in the Solution Explorer and the relevant assembly is listed under that.
You have to use reference to "Microsoft.VisualBasic" in your project.
You have two way for do that :
1st way :
Right click on project references, select "Assemblys" => "Framework" and you can search (at top right) "basic" keyword, and select "Microsoft.VisualBasic" item.
After that you can compile your project and normally its works !
Screen for add references
2nd way :
Comment or delete "using Microsoft.VisualBasic.Devices;" instruction.
The class "Audio" should be underline to red, hover with your mouse and you have option by IDE which let you "using Microsoft.VisualBasic.Devices;".
References should be automatically added in project.
And now you can compile your project.

How to set assembly references for Visual Studio solution using CMake?

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)

How to compile ZipFile class (C#) in command line

Before I start describing my problem I wanna say I did everything what I supposed to do in order to make ZipFile class functional. I mean, my target framework is .Net 4.5, I added references ( System.IO.Compression.FileSystem.dll and System.IO.Compression.dll ).
I can build the project within the Visual Studio without problem, no error. BUT when I try to compile the project using Command line that's when it gets interesting. I get everytime a error "error CS0103: the name ZipFile class does not exist in the current context".
The command for compiling in the CMD is: csc /define:DEBUG /optimize /out:tbuild.exe *.cs
Does anybody come across similar or even the same problem and knows solution for it, please?
First off, +1 on the msbuild suggestion, or you could look at something like Fake
You specify the reference to System.IO.Compression.FileSystem.dll etc... in your visual studio project. Then you proceed to build your exe using only *.cs files.
I think you should specify any references other than System.dll on the command line as well like this

The type or namespace name 'Cecil' does not exist in the namespace 'Mono'

I am new to C# programming .
I am trying to a compile a C# program which requires mono cecil
This is the code i am trying to compile
I dono how to add reference ...can someone help me out in this?
using System;
using Mono.Cecil;
using Mono;
public class Program {
public static void Main() {
string infile = "in.exe";
string outfile = "out.exe";
Guid guid = Guid.Parse("12345678-1234-1234-1234-1234567890ab");
AssemblyDefinition asm = AssemblyDefinition.ReadAssembly(infile);
ModuleDefinition mod = asm.MainModule;
mod.Mvid = guid;
asm.Write(outfile);
}
}
I get the following error when i compile the program using mcs
error CS0234: The type or namespace name 'Cecil' does not exist in the namespace 'Mono'.Are you missing an assembly reference?
I couldnt find Mono.Cecil.dll in /usr/lib/mono/4.0 & /usr/lib/mono/2.0.
Mono.Cecil.dll is present only in /usr/lib/monodevelop/bin/
Kindly let me know if i am missing anything? and how do i get rid of this error ???
Regards
Puliyan
You need to tell the compiler with the -r, -pkg, or -lib options where to find Mono.Cecil.dll.
A solution that always works is building the .dll from source:
git clone https://github.com/mono/cecil.git
cd cecil
xbuild /property:Configuration=net_4_0_Release
You can also use other configurations (e.g., net_4_0_Debug). Check the .sln or .csproj file for values. You'll find Mono.Cecil.dll in the obj subdirectory. You can then copy that library to whatever location you want and compile with -r:/path/to/Mono.Cecil.dll, -lib:/path/to/libdirectory -r:Mono.Cecil.dll, or if you're using MonoDevelop, add a reference to the library (in MonoDevelop, you should also be able to reference the project directly).
Cecil should normally also be available via the pkg-config mechanism; however, the cecil.pc file seems to be misconfigured. Normally, just using -pkg:cecil should suffice, but that appears to be broken and instead you have to use something like:
dmcs -r:`pkg-config --variable=Libraries`
in order to get the full path to Mono.Cecil.dll in the GAC.
Also, because mono is split up in a number of packages under Debian, you may have to install additional libraries if the above doesn't work (I don't know at the moment whether Cecil is part of the core package or not).

compiler build error : The call is ambiguous between the following methods or properties

I am experiencing a strange compiler error with extension methods. I have an assembly which has an extension method like
public static class MyClass
{
public static Bar GetBar(this Foo foo)
{
return new Bar();
}
}
And elsewhere in the same assembly i do something like this
Foo foo = new Foo();
var bar = foo.GetBar();
When i clean and compile everything is OK. BUT once i make a small change (like an extra whitespace) in the assembly and build again I get an error like this:
Error 973 The call is ambiguous between the following methods or properties: 'MyNameSpace.MyClass.GetBar(Foo)' and 'MyNameSpace.MyClass.GetBar(Foo)'
Only after i clean the project I can build again. Is this a problem in the compiler using an old version of the assembly? Only work around I see now is to replace my extension methods with normal static methods.
Took me a while to figure this one out but Gluips comment is the right one, I'll add it here for easy reference:
That's it! Somehow the project was directly referencing itself.
Removing the reference probably fixes the problem. Thanks!
This fixed it for me.
Ok having done a bit of playing round I can reproduce a similar situation to this by adding a file reference to the output file - the first time round it builds successflly (as the reference is not used - you simply get a "reference not resolved" warning), however from this point on I see the "The call is ambiguous" error appear in the code editor.
For me however this doesn't prevent me from building the solution (I'm testing this using Visual Studio 2010), however the error does appear - maybe under slighly different circumstances, such as a different Visual Studio version, this would stop the project from compiling.
You could also engineer this same situation with post-build steps that copy the output assembly.
I can't explain such behavior, but you should implement such method as a static directly in Foo class.
I've had this behavior upon compiling with MSBuild v14:
building in VS 2015 worked just fine
building on the same machine by MSBuild worked also
building on a server machine with only MSBuild preinstalled failed
Installing the .NET Developer Pack (in my case Developer Pack for 4.5.2) solved the issue, even if the error message was misleading.

Categories

Resources