C# Mono/.NET differential CAD software retrievement - c#

OK, I will try to do my best, but I think that my English is still too bad when it comes to complex subjects/phrases.
I have to build a class (as for now it's not static) that retrieves the information about the external application (software available on customers PC).
The Linux class was really easy to code, but now I have to implement it on Windows.
Basically I've encountered some difficulties with x64 registry reading from x86 version of my application: you can do it only by using [DllImport("advapi32.dll")].
From the beginning I knew that software retirement is strongly depending on target OS, so I've created 4 classes:
public abstract ExternalApplications that defines some basic methods and it is derived by ExternalApplicationsWin, ExternalApplicationsMac and ExternalApplicationsUnix.
Inmy application I create an instance of ExternalApplications and assign it by switching the operating system type:
ExternalApplications ex = null;
switch (Environment.OSVersion.Platform)
{
case PlatformID.Win32NT:
goto default;
case PlatformID.MacOSX:
_ex = new ExternalApplicationsMac(); break;
case PlatformID.Unix:
_ex = new ExternalApplicationsUnix(); break;
default:
_ex = new ExternalApplicationsWin(); break;
}
I this way the method call will be dispatched automatically to the right ExternalApplicationsXXX type.
Now by introducing [DllImport("advapi32.dll")] I'm obligated to:
change the class structure (to static extern)
it will probably brake Mono compilation on Unix/Mac OS X compilation (with
DllNotFoundException)
There are several options:
(1) I can create 3 parallel projects (.cproj) with the same target assembly name for Linux, Mac and Windows. The projects will contain the same classes and methods so I can reference it inside my application without any problem.
This option sucks, it lacks of automation: everything is done manually.
(2) I can accomplish a preventive "DllImport" code exclusion by using C# directives like
#if !MONO
...
#endif
I'm sure that there are many other methods like DLLMAP and others.
I think that more experienced programmers will tell me what is the most elegant/reliable solution.
EDIT 1:
I've just discovered that x64 registry hive reading from an x86 application is possible, however only in .NET 4.0 and higher (according to my source, still need to test).
string registryBranchPath = "SOFTWARE\MySoft";
RegistryKey regKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
regKey = regKey.OpenSubKey(registryBranchPath);
This solves only one part of my question, the other part (regarding the possibility to use DllImport in Windows specific non-static classes) is still to be confirmed / tested.

Your class doesn't need to be static, only the imported external method is marked as such. Also, the imported method should be marked private, as nothing except the importing class should call it directly.
You don't need any fancy compilation tricks / code splitting, the DllImport is not checked until it's actually invoked.
An example from MSDN documentation for DllImport:
using System;
using System.Runtime.InteropServices;
class Example
{
// Use DllImport to import the Win32 MessageBox function.
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
private static extern int MessageBox(IntPtr hWnd, String text,
String caption, uint type);
public void MessageBox()
{
// Call the MessageBox function using platform invoke.
MessageBox(new IntPtr(0), "Hello World!", "Hello Dialog", 0);
}
}

So the final solution for me will look like this simplified snippet:
public static class UsageClass
{
private static ExternalApplications _extApps;
public static void Initialize()
{
_extApps = null;
switch (Environment.OSVersion.Platform)
{
case PlatformID.Win32NT:
goto default;
case PlatformID.MacOSX:
_extApps = new ExternalApplicationsMac(); break;
case PlatformID.Unix:
_extApps = new ExternalApplicationsUnix(); break;
default:
_extApps = new ExternalApplicationsWin(); break;
}
}
internal abstract class ExternalApplications
{
public abstract string[] DoSomething();
}
internal class ExternalApplicationsWin : ExternalApplications
{
public abstract void DoSomething()
{
// Windows code
RegistryKey regKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine,
(Environment.Is64BitOperatingSystem) ? RegistryView.Registry64 : RegistryView.Registry32).OpenSubKey("SOFTWARE\MySoft");
...
}
}
internal class ExternalApplicationsUnix : ExternalApplications
{
public abstract void DoSomething()
{
// Unix code
}
}
internal class ExternalApplicationsMac : ExternalApplications
{
public abstract void DoSomething()
{
// Mac code
}
}
}

Related

Selenium - disable test and do not show in test explorer [duplicate]

Is it possible to skip all tests from a specific class like in NUnit
[TestFixture]
[Ignore("Reason")]
public class TestClass {
}
No - there is no such facility at present, and the last time it was requested it was considered too low value to add,
One quick way of achieving the effect in xUnit is to comment out the public - private classes are not reflected over (obviously it won't appear on the skip list that way though).
UPDATE: Another way is to put a TraitAttribute on the class and then (assuming you're using the xunit.console runner) filter it out by running with /-trait traitName. (e.g. you can achieve ExplicitAttribute, some aspects of the BDD frameworky technique of Pending tests and similar semantics that way - of course the big problem is they don't show up in any reports when using any of these filtering techniques)
UPDATE 2: You can do
const string skip = "Class X disabled";
[Fact(Skip=skip)]
void Test() {}
Then you can change to to const string skip = null to undo the skip. The (dis)advantage of this is that the test is still shown as a Skipped test in the test list, generally with a reason included in the test run report (vs making it private which makes it likely to be forgotten)
Here is my hack to avoid error xUnit1000: Test classes must be public (checked on single Fact, I think Theories can be hacked this way, too).
// Uncomment to enable tests
//public class FactSwitch : FactAttribute { } // public! ahh, a bug!
// Uncomment to disable tests
internal class FactSwitch : Attribute { }
public class MyTests
{
[FactSwitch]
public void MyTest1()
{
"it".ShouldBe("it");
}
}
(3 years later)
While searching for the same solution I found there are better ways to do the same.
Let's rewrite the example above in a way Ruben Bartelink suggested (continuation of his idea).
public class MyTests
{
//const string SkipOrNot = null; // Run all tests
const string SkipOrNot = "reason"; // Skip all tests
[Fact(Skip = SkipOrNot)]
public void MyTest1()
{
"it".ShouldBe("it");
}
}
Nathan Cooper suggested a good improvement for my idea:
public class MyTests
{
// Uncomment to disable tests
//private class FactAttribute : Attribute { }
[Fact]
public void MyTest1()
{
"it".ShouldBe("it");
}
}
So I like both ideas from Ruben and Nathan. There is a subtle difference between using Skip="something" (Ruben) and not using Skip at all. Using "Skip" will put all your tests in a "Skipped tests" warning zone, while "FactAttribute : Attribute" will hide them.
I've found yet another way of temporary disabling entire class without compiler warning.
Disabled:
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "xUnit1000:Test classes must be public", Justification = "Disabled")]//*/
/*
public /**/class DatabaseTests
{
}
to enable move the /* one line up (i.e. using alt+up):
/*
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "xUnit1000:Test classes must be public", Justification = "Disabled")]//*/
public /**/class DatabaseTests
{
}
Note that using full namespace path for SupressMessage does not mess up with your usings.
You need to set the your class access level as as internal and surpress message as #Miq did:
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "xUnit1000:Test classes must be public", Justification = "Disabled")]
internal class MyClassThatIsNotATestClass
{ ... }
You can create LocalOnlyFactAttribute
public class LocalOnlyFactAttribute : FactAttribute
{
//uncomment to run on local
//const string skip = null;
//keep this to avoid slow running tests on other env
const string skip = "Disabled slow running tests.";
public override string Skip { get => skip; set => base.Skip = value; }
}
As far as I know, the simplest way to dynamically skip a whole xUnit test class at runtime is to use the TestFrameworkAttribute at the assembly level, to point to a class that implements the ITestFramework interface (or inherits from XunitTestFramework, which is simpler) and which overrides the CreateDiscoverer() method to return another class, that implements the ITestFrameworkDiscoverer interface (or inherits from XunitTestFrameworkDiscoverer, which is simpler), where you can finally override the IsValidTestClass() method, to decide whether a class should be skipped or not.
Here is some sample code:
[assembly: TestFramework("MyNamespace.Xunit.MyTestFramework", "MyAssembly")]
namespace MyNamespace.Xunit
{
public class MyTestFramework : XunitTestFramework
{
public MyTestFramework(IMessageSink messageSink)
: base(messageSink)
{
}
protected override ITestFrameworkDiscoverer CreateDiscoverer(
IAssemblyInfo assemblyInfo)
=> new MyTestFrameworkDiscoverer(
assemblyInfo,
SourceInformationProvider,
DiagnosticMessageSink);
}
public class MyTestFrameworkDiscoverer : XunitTestFrameworkDiscoverer
{
public MyTestFrameworkDiscoverer(
IAssemblyInfo assemblyInfo,
ISourceInformationProvider sourceProvider,
IMessageSink diagnosticMessageSink,
IXunitTestCollectionFactory collectionFactory = null)
: base(
assemblyInfo,
sourceProvider,
diagnosticMessageSink,
collectionFactory)
{
}
protected override bool IsValidTestClass(ITypeInfo type)
=> base.IsValidTestClass(type) &&
FilterType(type);
protected virtual bool FilterType(ITypeInfo type)
{
// Insert your custom filter conditions here.
return true;
}
}
}
Tested with xUnit 2.4.1.
We are using it in Pomelo.EntityFrameworkCore.MySql (see AssemblyInfo.cs and MySqlXunitTestFrameworkDiscoverer.cs) (a bit more complex than the sample code here).
You could achieve this through a custom ITestClassCommand.
See http://mariangemarcano.blogspot.be/2010/12/xunitnet-running-tests-testcategory.html
Here's another hack that requires minimal changes to code
using FactAttribute = System.Runtime.CompilerServices.CompilerGeneratedAttribute;
using TheoryAttribute = System.Runtime.CompilerServices.CompilerGeneratedAttribute;
Any compatible attribute can be used for the replacement.
If you also use the InlineDataAttribute then you'll need to define a replacement as I don't think there's an existing compatible attribute.
using InlineDataAttribute = DummyDataAttribute;
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
internal class DummyDataAttribute : Attribute
{
public DummyDataAttribute(params object[] data)
{
}
}
Adding a reason almost after one year after the initial question. I have a set of tests which are calling real server apis, and I would like to run then on demand. With nUnit, it has Ignore attribute : with that set, test runner will skip those tests, but I can still manually run it.
xUnit has no such feature. The nearest one is setting such a class level attribute, and comment it out when I want to run it.
Consider creating LocalOnlyFactAttribute, which can be reused across multiple test files.
public class LocalOnlyFactAttribute : FactAttribute
{
//uncomment to run on local
//const string skip = null;
//keep this to avoid slow running tests on other env
const string skip = "Disabled slow running tests.";
public override string Skip { get => skip; set => this.Skip = value; }
}

C# Constructors Ambiguity with explicit call - Error CS0012

There is an unexplained ambiguity in C#, where I explicitly try to call a constructor but the compiler thinks it is a different constructor. I will start with showing a short C# architecture we use. Then show a small "working" example I created, and the possible solution to this, but still I like to understand why this happens.
The Architecture:
CLR DLL which bridges the C++ API.
C# API which uses the bridge level.
C# Client applications that use the C# API.
Note that the C# Clients are not allowed to use the CLR level.
Example I created
A class in the CLR DLL:
#pragma once
#include <string>
using namespace System;
namespace Inner {
public ref class AInner
{
public:
AInner() : _data(new std::wstring(L"")) {}
~AInner() {
delete _data;
}
property String^ Val
{
String^ get()
{
return gcnew String((*_data).data());
}
void set(String^ value) {
System::IntPtr pVal = System::Runtime::InteropServices::Marshal::StringToHGlobalUni(value);
*_data = (const wchar_t*)pVal.ToPointer();
System::Runtime::InteropServices::Marshal::FreeHGlobal(pVal);
}
}
private:
std::wstring* _data;
};
}
Class wrapping the CLR level, in a DLL:
using System;
using Inner;
namespace Outer
{
public class A
{
public A()
{
_inner.Val = String.Empty;
}
public A(string val)
{
init(val);
}
public string Val
{
get
{
return _inner.Val;
}
set
{
_inner.Val = value;
}
}
internal A(AInner inner)
{
_inner = inner;
}
private void init(string Val)
{
_inner = new AInner();
_inner.Val = String.Empty;
}
private AInner _inner;
}
}
Note that there is an internal constructor and a public constructor.
Executable Client using the C# API DLL:
using Outer;
namespace OneClient
{
class Program
{
static void Main(string[] args)
{
string myString = "Some String";
A testA = new A(myString);
}
}
}
Twist in the story:
In the DLL wrapping the CLR level, not ALL API should be used by external clients, but can be used by internal clients, thus the internals are exposed to the internal clients by adding [assembly: InternalsVisibleTo("OneClient")] to the 'AssemblyInfo.cs' of the DLL wrapping the CLR level.
The issue
When compiling the Client code I get the following error:
error CS0012: The type 'AInner' is defined in an assembly that is not referenced. You must add a reference to assembly 'InnerOne, Version=1.0.7600.28169, Culture=neutral, PublicKeyToken=null'.
I cannot use InnerOne because clients are not allowed to use this level.
The client is exposed to both A(string val) and A(AInner inner) constructors.
Possible Workarounds:
Remove the [assembly: InternalsVisibleTo("OneClient")] - This is unacceptable due to other classes internals that the specific client needs to use.
Change the A(string val) constructor to A(string val, bool unique=true) and use it A testA = new A(myString, true) - Not a nice solution.
Use default constructor A() and call testA.Val = myString; - This is actually OK but to much code.
Change the client code from A testA = new A(myString) to A testA = new A(val:myString); - This is actually the chosen solution.
Question
Why does this ambiguity happen?
I call the A(string val) with the myString which is actually a string value
This is very strange.
Is this a bug in Microsoft compiler?
Example Sources:
Source Code One.zip
Why does this ambiguity happen?
Because to satisfy the constructor overload resolution, the compiler needs to know what all the argument types are, and it doesn't know what an AInner is.
Why not expose the AInner version as a factory method:
static internal A Create(AInner inner)
{
return new A { _inner = inner };
}
I don't see any issue in this, the problem is we are used to do the things in a wrong/briefly way.
The correct answer fot this is:
A testA = new A(val:myString);
Furthermore, all your calls (in this way is a call to a constructor/initializer but it's a call anyway) should be with the parameter name. No one (even me) writes them, but...

.NET object design: hardware handles & garbage collection

I'm developing a .NET library for easy use of LibTiePie by .NET code.
Relevant library code (C#):
using Handle = UInt32;
public static class API
{
[DllImport(#"libtiepie.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void DevClose(Handle device);
};
public class Device
{
protected Handle _handle;
public Device(Handle handle)
{
_handle = handle;
}
~Device()
{
API.DevClose(_handle);
}
}
Program code (C#):
Device dev = new Device( some_valid_open_handle );
// Do something useful with dev
dev = null; // How can I make sure that the handle is closed now, as the GC may not cleanup it directly?
I can add Close method the Device class which can be called before releasing the reference. But wonder is there is a better .NET way of implementing this?
Implement the IDisposable interface.
Consumers can then do:
using (Device d = new Device(handle))
{
...
}
This will give deterministic closing of the underlying handle. Also see documentation on the using keyword.
Instead of calling API.DevClose(_handle) in the finalizer, you'd then do it in Dispose(). The MSDN link has a nice example of how this pattern can be used to close native handles.

Getting C# ActiveX/COM Library to Work through JScript

I have checked on stackoverflow (and what seems like everywhere else). I would like to get a COM solution working so that a jscript file can be written as
var T = new ActiveXObject("MySimulator.World");
T.MyMethod();
It would be executed at the command prompt by
cscript mytest.js
In this case, I get the error "Automation server can't create object".
In C#, I have followed various suggestions, with the latest interface being:
[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsDual), Guid("EAA4976A-45C3-4BC5-BC0B-E474F4C3C83B")]
public interface IComMyReaderInterface
{
void MyFunction();
}
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None), Guid("0D53A3E8-E51A-49C7-944E-E72A2064F9DD"), ProgId("MySimulator.World")]
[ComDefaultInterface(typeof(IComMyReaderInterface))]
public class MyReader : IComMyReaderInterface
{
public MyReader()
{
...
}
public void MyFunction()
{
...
}
...
}
Thanks and just let me know if more information is needed.
I'd assume the following. Your development environment is probably a 64-bit OS and your C# DLL project is probably configured to compile with Any CPU as Platform Target. Read on if that's the case.
Choose either x86 or x64 and compile the project. If you go with x86, then register your assembly with the 32-bit version of RegAsm.exe:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe /codebase assembly.dll
Then run your JavaScript test with the 32-bit version of cscript.exe:
C:\Windows\SysWOW64\cscript.exe mytest.js
If you go with x64, that would be:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe /codebase assembly.dll
C:\Windows\System32\cscript.exe mytest.js
[EDITED] The following code has been verified to work using the above instructions.
C#:
using System;
using System.Runtime.InteropServices;
namespace ComLibrary
{
[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsDual),
Guid("EAA4976A-45C3-4BC5-BC0B-E474F4C3C83B")]
public interface IComMyReaderInterface
{
void MyFunction();
}
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None),
Guid("0D53A3E8-E51A-49C7-944E-E72A2064F9DD"),
ProgId("MySimulator.World")]
[ComDefaultInterface(typeof(IComMyReaderInterface))]
public class MyReader : IComMyReaderInterface
{
public MyReader()
{
}
public void MyFunction()
{
Console.WriteLine("MyFunction called");
}
}
}
JavaScript (mytest.js):
var T = new ActiveXObject("MySimulator.World");
T.MyFunction();
Output:
MyFunction called

WinForms/Console application on Mono, how to know it runs as root

As we can execute such executables in two ways, such as "sudo mono test.exe", and "mono test.exe".
Now I want to know how to detect whether this application is running as root inside the application itself.
I tried to check user name like below and see whether they equal to "root",
Thread.CurrentPrincipal.Identity.Name
Process.GetCurrentProcess().StartInfo.UserName
AppDomain.CurrentDomain.ApplicationIdentity.FullName
The first two are empty strings always, while the third throws NullReferenceException.
Please advise if this is doable on Mono 2.6.
One solution is to DllImport libc and use the getuid() function. If you're running as root, getuid() returns 0; if not, it returns some other UID:
using System.Runtime.InteropServices;
public class Program
{
[DllImport ("libc")]
public static extern uint getuid ();
public static void Main()
{
if (getuid() == 0) {
System.Console.WriteLine("I'm running as root!");
} else {
System.Console.WriteLine("Not root...");
}
}
}
This works fine in Mono 2.6.
EDIT: It might be better to access getuid() through the Mono.Unix.Native.Syscall wrapper class in the Mono.Posix assembly:
using Mono.Unix.Native;
public class Program
{
public static void Main()
{
if (Syscall.getuid() == 0) {
System.Console.WriteLine("I'm running as root!");
} else {
System.Console.WriteLine("Not root...");
}
}
}
Sorry, I'm not much of a Mono expert. But however you get to it, the process's UID is what you want to know; if it's equal to zero then you're root, otherwise you're not root.

Categories

Resources