I'm converting an .NET Windows application for Mono to run on Linux (Ubuntu). One of the features depends on a native library (user32.dll). The Mono guide that talks about conversion of applications (Linux Platform Differences) suggests that one approach would be to modify this code.
I'm trying to use GDK to access the Title of a Gdk.Window that I had access through the property Gdk.Global.ActiveWindow. But I found this error at compile time:
Error CS0154: The property or indexer `Gdk.Window.Title` cannot be used in this context because it lacks the `get` accessor (CS0154) (GetActiveWindow)
If i remove the code that reads de Title property of activeW, everything works fine. There is another way to read this property?
Here my unit of work:
using System;
using Gtk;
using Gdk;
using System.Threading;
namespace GetActiveWindow
{
class GdkApp : Gtk.Window
{
public static void Main ()
{
Application.Init ();
new GdkApp ();
Application.Run ();
}
public GdkApp () : base("Simple App")
{
SetDefaultSize (150, 150);
ShowAll();
while (true) {
var activeW = Gdk.Global.ActiveWindow;
Console.WriteLine("Active Window: {0}",activeW.Title); // Where my compile error happens.
Console.WriteLine("Simple App Window: {0}",this.Title); // This code works perfectily.
Thread.Sleep(1000);
}
}
}
}
I think that with Gdk is imposible. Try it with Wnck library giving to a C compiler this '-DWNCK_I_KNOW_THIS_IS_UNSTABLE' and works but with a warning: Unhandled action type _OB_WM_ACTION_UNDECORATE
Sorry I have used genie instead vala.
//valac *.gs --pkg gtk+-3.0 --pkg libwnck-3.0 -X '-DWNCK_I_KNOW_THIS_IS_UNSTABLE'
init
Gtk.init(ref args)
var ventana= new win()
ventana.inicio()
ventana.printinfo()
Gtk.main()
class win:Gtk.Window
won:weak GLib.List of Wnck.Window
def inicio()
var button= new Gtk.Button()
button.clicked.connect(printinfo)
this.add(button)
this.show_all()
def printinfo()
won= Wnck.Screen.get_default().get_windows()
won.foreach(allwin)
def allwin(w:Wnck.Window)
if w.is_skip_tasklist() or w.is_skip_pager()
pass
else
print w.get_name()
Related
I have created a console application .NET 6.0 for learning of Singleton Pattern.
But I have observed a significant change in Program.cs file.
namespace, class and Main method have been removed from program.cs in .NET 6.0.
I believe the code that will be written in program.cs will be considered as within Main method.
But I want to create two static methods which are using globally intialized instances but I am not able to do that.
By declaring the instances like below:
It gives Compile Error:
CS0106 The modifier 'static' is not valid for this item
While using the instances in static methods like below:
It gives Compile Error:
CS8421: A static local function cannot contain a reference to
'tableservers1'.
Here is all the code of program.cs :
using SingletonApp;
static TableServers tableservers1 = TableServers.GetInstance();
static TableServers tableservers2 = TableServers.GetInstance();
Console.WriteLine("Hello, World!");
for (int i = 0; i < 5; i++)
{
Host1();
Host2();
}
Console.WriteLine();
static void Host1()
{
Console.WriteLine("Host1 Next server is: " + tableservers1.GetNextServer());
}
static void Host2()
{
Console.WriteLine("Host2 Next server is: " + tableservers2.GetNextServer());
}
Please someone can explain how can we use this new minified program.cs, specially to use global instance and variables and creating methods.
As in this answer since C# 10 you can achieve this by introducing public partial class Program (at the bottom of you top level statement file or in separate file):
// rest of your top-level statement code
// ...
public partial class Program
{
static TableServers tableservers1 = TableServers.GetInstance();
static TableServers tableservers2 = TableServers.GetInstance();
}
But I would argue that switching to "old style" Program class or moving static fields to another class would be a better option.
I'm writing a Console App (.NET Framework) in C#. I want to use arguments from the command line, and I'm trying to use the Command Line Parser library to help me do this.
This is the package on Nuget - https://www.nuget.org/packages/CommandLineParser/
I found out about it from this StackOverflow question - Best way to parse command line arguments in C#?
MWE
using System;
using CommandLine;
namespace CLPtest
{
class Program
{
class SomeOptions
{
[Option('n', "name")]
public string Name { get; set; }
}
static void Main(string[] args)
{
var options = new SomeOptions();
CommandLine.Parser.Default.ParseArguments(args, options);
}
}
}
When I try create a minimal working example, I get an error for options on this line:
CommandLine.Parser.Default.ParseArguments(args, options);
The error is Argument 2: cannot convert from 'CLPtest.Program.SomeOptions' to 'System.Type'
I'm really confused as I have seen this same example code on at least 3 tutorials for how to use this library. (see for example - Parsing Command Line Arguments with Command Line Parser Library)
(This answer is being written at the time of v2.7 of this library)
From looking at their repository's README, it appears as if this is part of the API change that is mentioned earlier in the README. It looks as though the arguments are now handled differently since the example code you reference. So, now you should do something like this inside of Main:
...
static void Main(string[] args)
{
CommandLine.Parser.Default.ParseArguments<SomeOptions>(args);
}
...
To actually do something with those options you can use WithParsed which takes in the options that are defined in your SomeOptions class.
...
static void Main(string[] args)
{
CommandLine.Parser.Default.ParseArguments<SomeOptions>(args).WithParsed(option =>
{
// Do something with your parsed arguments in here...
Console.WriteLine(option.Name); // This is the property from your SomeOptions class.
});
}
...
The C# Example further down the README shows that you can pass in a method into WithParsed to handle your options instead of doing everything within Main.
I want to load a class form a .cs file and use it in another code.
Assume I have a .cs file which contains code like that:
//some imports
public class Commands
{
//a lot of commands
}
What I am trying is to load this class from a file using CSharpCodeProvider or whatever and create a list of Commands.
A piece of code from a console app.
list<Commands> lst;
The question is how can I load Commands class dynamically (at runtime) (without restarting the console app or starting VS) and create the list of Commands?
Try this example, which I have put together and tested:
Build program.cs as a .Net Framework Console App in e.g. Visual Studio.
// program.cs
using System;
using System.IO;
using System.CodeDom.Compiler;
using System.Reflection;
namespace RuntimeCompile
{
class Program
{
static void Main(string[] args)
{
// Get a path to the file(s) to compile.
FileInfo sourceFile = new FileInfo("mySource.cs");
Console.WriteLine("Loading file: " + sourceFile.Exists);
// Prepary a file path for the compiled library.
string outputName = string.Format(#"{0}\{1}.dll",
Environment.CurrentDirectory,
Path.GetFileNameWithoutExtension(sourceFile.Name));
// Compile the code as a dynamic-link library.
bool success = Compile(sourceFile, new CompilerParameters()
{
GenerateExecutable = false, // compile as library (dll)
OutputAssembly = outputName,
GenerateInMemory = false, // as a physical file
});
if (success)
{
// Load the compiled library.
Assembly assembly = Assembly.LoadFrom(outputName);
// Now, since we didn't have reference to the library when building
// the RuntimeCompile program, we can use reflection to create
// and use the dynamically created objects.
Type commandType = assembly.GetType("Command");
// Create an instance of the loaded class from its type information.
object commandInstance = Activator.CreateInstance(commandType);
// Invoke the method by name.
MethodInfo sayHelloMethod = commandType.GetMethod("SayHello", BindingFlags.Public | BindingFlags.Instance);
sayHelloMethod.Invoke(commandInstance, null); // no arguments, no return type
}
Console.WriteLine("Press any key to exit...");
Console.Read();
}
private static bool Compile(FileInfo sourceFile, CompilerParameters options)
{
CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");
CompilerResults results = provider.CompileAssemblyFromFile(options, sourceFile.FullName);
if (results.Errors.Count > 0)
{
Console.WriteLine("Errors building {0} into {1}", sourceFile.Name, results.PathToAssembly);
foreach (CompilerError error in results.Errors)
{
Console.WriteLine(" {0}", error.ToString());
Console.WriteLine();
}
return false;
}
else
{
Console.WriteLine("Source {0} built into {1} successfully.", sourceFile.Name, results.PathToAssembly);
return true;
}
}
}
}
In the output directory (bin), next to the console app executable place a text file named mySource.cs with this content:
// mySource.cs
using System;
internal class Program
{
static void Main()
{
Console.WriteLine("Hello from mySource!");
Console.ReadLine();
}
}
public class Command
{
public void SayHello()
{
Console.WriteLine("Hello (Command)");
}
}
Then run the first console app and observe it's output. It should log "Hello (Command)", showing that the code was correctly compiled, loaded and executed.
The example shows how to use the CodeDom.Compiler to compile a cs-file at runtime and then load it as dll to run code within it. Be aware, that almost no error handling was implemented.
This should answer the question, but there may still be better approaches to handling your use-case. In case of plugin loading it makes sense to use interfaces which are added as a reference to both assemblies to avoid the use of reflection, etc.
There is probably a better way to achieve your overall goal, like dependency injection.
However, you can do it with the ICodeCompiler.
See this article https://support.microsoft.com/en-ca/help/304655/how-to-programmatically-compile-code-using-c-compiler
To load the c# class from another c# class you need to use "using"
using Commands;
public class class1
{
private list<Commands>lst;
//...
}
I'm trying to write some tests for testing GUI interface. I decided to choose NUnit.Forms. But the tests fall with the following error:
TearDown : System.ComponentModel.Win32Exception : The requested resource is in use
I have two versions of the source code tests.
First:
using System.Windows.Forms;
using NUnit.Extensions.Forms;
using NUnit.Framework;
using YAMP;
namespace Tests.GUITests
{
[TestFixture]
public class GuiTest : NUnitFormTest
{
private FrmMain _frm;
//[SetUp] // or it is still needed
public override void Setup()
{
base.Setup();
_frm = new FrmMain();
_frm.Show();
}
[Test]
public void TestData()
{
var txtInput = new TextBoxTester("txtInput") {["Text"] = "2+2"};
var txtOutput = new TextBoxTester("txtOutput");
Assert.AreEqual("2+2", txtInput.Text);
var btnRes = new ButtonTester("btnRes");
btnRes.Click();
Assert.AreEqual("4", txtOutput.Text);
}
}
}
Second:
using System.Windows.Forms;
using NUnit.Extensions.Forms;
using NUnit.Framework;
using YAMP;
namespace Tests.GUITests
{
[TestFixture]
public class GuiTest : NUnitFormTest
{
private FrmMain _frm;
//[SetUp] // or it is still needed
public override void Setup()
{
base.Setup();
_frm = new FrmMain();
_frm.Show();
}
[TearDown]
public override void TearDown()
{
_frm.Close();
_frm.Dispose();
}
[Test]
public void TestData()
{
var txtInput = new TextBoxTester("txtInput") {["Text"] = "2+2"};
var txtOutput = new TextBoxTester("txtOutput");
Assert.AreEqual("2+2", txtInput.Text);
var btnRes = new ButtonTester("btnRes");
btnRes.Click();
Assert.AreEqual("4", txtOutput.Text);
}
}
}
And there are two different versions of the method TestNoData:
public void TestFormNoDataHandler()
{
var messageBoxTester = new MessageBoxTester("Message");
messageBoxTester.ClickOk();
}
[Test]
public void TestNoData()
{
ExpectModal("Message", TestFormNoDataHandler);
var txtInput = new TextBoxTester("txtInput") {["Text"] = string.Empty};
Assert.AreEqual(string.Empty, txtInput.Text);
var btnRes = new ButtonTester("btnRes");
btnRes.Click();
Assert.IsFalse(_frm.DialogResult == DialogResult.OK);
}
[Test]
public void TestNoData()
{
var txtInput = new TextBoxTester("txtInput") {["Text"] = string.Empty };
Assert.AreEqual(string.Empty, txtInput.Text);
var btnRes = new ButtonTester("btnRes");
btnRes.Click();
Assert.IsFalse(_frm.Enable);
}
Testable form is very simple. There are two TextBox - "txtInput", "txtOutput" and button - "btnRes". In "txtInput" introduced a mathematical expression, and "txtOutput" output response. The decision of expression occurs when you press "btnRes". If the field "txtInput" empty, the button is disabled and you can not click on it.
When searching for solutions to this problem came on the following links:
AutomaticChainsaw: WinForms testing using NUnitForms
c# - I need to create a windows form from within a NUnit test - Stack Overflow
Unfortunately I can attach only 2 links. But the information I learned is very different. Especially the part of writing methods Setup and TearDown.
In any case, I specify the version I use:
Visual Studio 2015 Community
NUnit - 2.6.4.14350
NUnitForms - 1.3.1771.29165
Because it seems to me that the problem might be too recent versions of frameworks, as article I learned quite old.
Thank you for any suggestion.
UseHidden Property: Tests are run on a separate hidden desktop. This makes them much faster and it works for any tests that are not using the keyboard or mouse controllers. They are less disruptive and input tests cannot interfere with other applications.
UseHidden property controls whether a separate desktop is used at all.
Though tests on the separate desktop are faster and safer (There is no danger of keyboard or mouse input going to separate running applications.), however for some operating systems or environments the separate desktop does not work. And the tests throw up errors like:
System.ComponentModel.Win32Exception : The requested resource is in use
--TearDown
at NUnit.Extensions.Forms.Desktop.Destroy()
at NUnit.Extensions.Forms.Desktop.Dispose()
at NUnit.Extensions.Forms.NUnitFormTest.Verify()
In that case you can override UseHidden property from test class and set it to return false. This will cause the tests to run on original, standard desktop.
I've just installed Cosmos and tried to run the test program given by default. That's the code:
using System;
using System.Collections.Generic;
using System.Text;
using Sys = Cosmos.System;
namespace CosmosKernel2
{
public class Kernel : Sys.Kernel
{
protected override void BeforeRun()
{
Console.WriteLine("Cosmos booted successfully. Type a line of text to get it echoed back.");
}
protected override void Run()
{
Console.Write("Input: ");
var input = Console.ReadLine();
Console.Write("Text typed: ");
Console.WriteLine(input);
}
}
}
When I try to compile it, it says:
Error 8 Plug needed. System.Void System.Threading.Monitor.Exit(System.Object)
at Cosmos.IL2CPU.ILScanner.ScanMethod(MethodBase aMethod, Boolean aIsPlug) in c:\Data\Sources\Cosmos\source2\IL2CPU\Cosmos.IL2CPU\ILScanner.cs:line 663
at Cosmos.IL2CPU.ILScanner.ScanQueue() in c:\Data\Sources\Cosmos\source2\IL2CPU\Cosmos.IL2CPU\ILScanner.cs:line 779
at Cosmos.IL2CPU.ILScanner.Execute(MethodBase aStartMethod) in c:\Data\Sources\Cosmos\source2\IL2CPU\Cosmos.IL2CPU\ILScanner.cs:line 284
at Cosmos.Build.MSBuild.IL2CPUTask.Execute() in c:\Data\Sources\Cosmos\source2\Build\Cosmos.Build.MSBuild\IL2CPUTask.cs:line 239 C:\Program Files (x86)\MSBuild\Cosmos\Cosmos.targets 32 10 CosmosKernel2Boot
I'm using Visual Studio 2010, I have installed all requirements listed here: http://cosmos.codeplex.com/releases/view/123476
Thank you in advance!
"plug needed" error means that you have used some method which relies on an internal call or PInvoke, and thus Cosmos cannot compile it.
You probably use a method that has not been plugged yet or maybe missing a reference to that implementation (which makes Cosmos think it is not implemented)
Use the below guides to help you getting started:
http://www.codeproject.com/Articles/220076/Csharp-Open-Source-Managed-Operating-System-Intro
http://www.codeproject.com/Articles/29523/Cosmos-C-Open-Source-Managed-Operating-System
Update: Try using something similar to this code:
using System;
using Cosmos.Compiler.Builder;
namespace CosmosBoot1
{
class Program
{
#region Cosmos Builder logic
// Most users wont touch this. This will call the Cosmos Build tool
[STAThread]
static void Main(string[] args)
{
BuildUI.Run();
}
#endregion
// Main entry point of the kernel
public static void Init()
{
var xBoot = new Cosmos.Sys.Boot();
xBoot.Execute();
//There's supposed to be a bit of text here. Change it to Console.WriteLine("Hello world!");
}
}
}
It seems that Cosmos isn't working well with windows 8/8.1. So the only solution is to either install Windows 7 or run a virtual machine with installed Windows 7 (the latter worked for me)