I’m at the moment automating the test for a legacy application developed in vb6, which uses a GridEx2000b Control from Janus Systems.
For doing this I’m using Ranorex as my favorite tool for developing the test automation, so that I can develop the test code using c#.
My problem now is to automate the GridEx 2000b control, which Ranorex out of-the-box don’t have any support for. Therefore I’m trying to figure out a solution where I can reference the GrixEx control using the Win32 handle I can find for the control, so I can use the ComInterface from the component to navigate the automate the control.
I have an idea of a solution but I cannot figure out how to do it, where I hope that you guys would be able help me.
The pseudo code for the problem:
using GridEX20;
class GridExWrapper
{
public GridEX20.GridEXClass Instance;
public GridExWrapper(IntPtr win32handle)
{
Instance = (GridEX20.GridEXClass)Win32ControlUtilities.GetControlReference(win32Handle);
}
}
class Win32ControlUtilities
{
public static SomeKindOfHandle GetControlReference(IntPtr win32Handle)
{
...
...
...
}
}
I’ll get the win32handle from Ranorex or some other spy tool.
Then I can use the GridExWrapper like this.
using NUnit.Framework;
class Program
{
[Test]
public void control_should_have_9_items()
{
/// Get win32 handle from Ranorex
IntPtr win32handle = XXXXXX;
int expectedItemCount = 9;
GridEXClass control = new GridExWrapper(win32handle);
Assert.AreEqual(expectedItemCount, control.ItemCount);
}
}
You could try the Microsoft UI Automation library (System.Windows.Automation) for identifying the properties of the control. Sometimes even if Ranorex fails, MSUIA manages to recognize the control as it looks into native properties of a control for identification. Not guaranteed but worth a try.Here is a link to a tutorial on using MSUIA.
Related
I want to be able to add hyperlinks to relevant data in the output for a unit test.
I have the following test:
using NUnit.Framework;
namespace BioFire.PanelSoftware.Service.Tests
{
[TestFixture]
public class SimpleTest
{
[Test]
public void Test1()
{
Console.WriteLine("www.google.com"); //not hyperlink
Console.WriteLine(#"C:\Program Files"); //not hyperlink
throw new Exception("My output window will somehow give me a hyperlink to here.");
}
}
}
According to this question, it isn't possible in C#. But it is clearly working for nUnit somehow:
This is very specific to the terminal you are using and I don't believe anything in C# can achieve clickable text. You can technically use Process.Start() from the System.Diagnostics namespace to trigger the default browser to open the webpage you want, but this isn't a hyperlink and would rather be triggered by your specifications
If you are running from within an IDE, you would have to look into the underlying shell and try to swap it out for a different profile (ex. this should be easy on VS Code but I'm unsure if Visual Studio can support it). If you are running from cmd line, then try using the new Windows Terminal App as it supports this functionality
I'm making an app and need to be able to check if settings like : Bluetooth/Phone Rotation/Flashlight/Plane Mode/GPS/Phone Brightness/Silent Mode, are activated on an android phone.
I haven't found any way to do it within Unity, using C#. I found ways to do it using Xamarin but none of them work with Unity (or maybe I haven't done it right), the only way I found is using Java and making it into a plugin and call it in a C# script. But I can't find a clear way to make this work. If this is the only solution could you please explain how to do it, all the documentation I find is from old versions from 2014.
I think there is a simple solution for this but I simply can't find it. And the manifest part is not a problem, I'll add the permissions needed.
In Java the methods you want to call should be public or static, you must build your java source as a library (in build.gradle: apply plugin: 'com.android.library'), and add the .aar to Unity's Assets/Plugins/Android/ folder.
Then you can instantiate your plugin in Unity like so:
// this class string is the package at the top of your Java class extended with the class name, e.g.:
// package com.yourcompany.you.package;
string classString = "com.yourcompany.you.package.className";
// Get the class
var tempAjc = new AndroidJavaClass(classString);
// Here you can call a static method on the class that returns an instance of the class if you want to pass some parameters upon creation
_androidObject = tempAjc.CallStatic<AndroidJavaObject>("CreateInstance",
new object[] {arg1, arg2});
// non static call on your new instance
_androidObject.Call("PassingMoreStuff", initParam);
// if you want to return something from Java to Unity:
int javaVal = _androidObject.Call<int>(methodName, parameters);
I've struggle several hours on that and I can't find what I'm doing wrong.
I created a new C# dll project, here is the content of the only class it contain:
using System;
using System.Runtime.InteropServices;
namespace PolygonSl {
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.AutoDual)]
public class Config {
[ComVisible(true)]
public string GetCompany() {
return "POL";
}
}
}
I basically remove everything from it trying to make it work, the only reference is System.
I checked the Make assembly COM-Visible flag on the Assembly Information and my project is signed (seams required for codebase).
It compiling fine, after that, I called RegAsm.exe, giving it my dll, I added /codebase and /tlb, the command is successful.
When I go to my VBA project, I can add my new tlb file to the references, working fine. After, I can use it in my code, the autocomplete is working and I can compile with no errors.
Then, when I execute, I got this:
Run-time error '430':
Class does not support Automation or does not support expected interface
Here is my code sample in the VBA:
Private Sub Button1_Click()
'With CreateObject("PolygonSl.Config")
With New PolygonSl.Config
MessBox .GetCompany, MB_OK, "Test"
End With
End Sub
I tried late binding and my code is running fine with it but I'd like to be able to use the autocomplete.
Anyone have a suggestion on what I could try to make it work?
Edit (Adding some details on my environment)
I work on VS2008 for projects related to Dynamics SL (one of the Microsoft ERPs)
I'm on Windows Server 2008 R8 Standard, running from VMWare
Compiling on Framework 3.5, Release, x86, Dynamics SL client is 32 bits
I tried my dll on Dynamics but also on Excel to be sure that the problem was not Dynamics ;)
I think you need to define an interface to be able to see getcompany.
using System;
using System.Runtime.InteropServices;
namespace PolygonSl
{
[Guid("6DC1808F-81BA-4DE0-9F7C-42EA11621B7E")]
[System.Runtime.InteropServices.ComVisible(true)]
[System.Runtime.InteropServices.InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IConfig
{
string GetCompany();
}
[Guid("434C844C-9FA2-4EC6-AB75-45D3013D75BE")]
[System.Runtime.InteropServices.ComVisible(true)]
[System.Runtime.InteropServices.ClassInterface(ClassInterfaceType.None)]
public class Config : IConfig
{
public string GetCompany()
{
return "POL";
}
}
}
You can generate the interface automatically by placing the cursor in the class definition and using Edit.Refactor.ExtractInterface.
I'd have to admit that I'm at the absolute edge of my abilities here and the above is put together based on examples I've seen elsewhere.
Edit
The following test code works fine on my PC
Option Explicit
Sub polygontest()
Dim my_polygon As SOPolygon.Config
Set my_polygon = New SOPolygon.Config
Debug.Print my_polygon.GetCompany
End Sub
Where SOPolygon is the project name.
I have the purpose to create a com-visible class with UI elements which I can execute/access via Lotus Notes. This is no problem using Visual Studio 2017. My com-visible class is correctly registered in Windows GAC and I'm able to call the available/visible functions supplied by a com-visible class:
[Guid("AD2C59FF-7B27-458E-9745-CB27092BAC9E")]
[ClassInterface(ClassInterfaceType.None)]
public class LotusNotesIntegrator
{
public void OpenDocumentUI(string filePath, string label, string password)
{
try
{
SingeltonUtils.Instance.MainForm.Show();
}
catch (Exception exception)
{
throw;
}
}
public void SetFocus()
{
}
}
I get in trouble when it comes down to usability for the user. Lotus Notes always 'steals' the shortcuts when I'm inside of the UI of my C# com-visible dll which displays a form with a simple text box. As soon as I try to copy the input text of the text box using 'Crtl + C' the shortcut is executed in the underlaying Lotus Notes client. This is a strange behavior as the UI of the com-visible dll is currently with focus and I'm able to type into the textbox field right after the form.Show() method was executed. But the shortcuts are still referenced to the Lotus Notes client which is the host/origin of the com-visible dll.
Has anyone of you experience a similar or the same issue? I hope you guys have an idea or solution for this problem.
Thanks in advance for your effort!
// Martin
What are the best practices to create a site, with ability to develop plugins for it?
Like you want to create a blog module, and you want users or co-developers to add plugins to extend this module functionality.
Update:
Thanks for the ultra speed answers, but I think this is over kill for me. Isn't there a simpler solution, like I have seen blogengine plugin creation system is you just have to decorate the class plugin with [Extension].
I am kind of mid core developer, so I was thinking of base class, inheritance, interfaces, what do you think ?
Edit
I completely rewrote my answer based on your question edit.
Let me show you just how easy it is to implement a plugin architecture with just the minimal steps.
Step 1: Define an interface that your plugins will implement.
namespace PluginInterface
{
public interface IPlugin
{
string Name { get; }
string Run(string input);
}
}
Step 2: Create a plugin that implements IPlugin.
namespace PluginX
{
using PluginInterface;
public class Plugin : IPlugin
{
public string Name
{
get { return "Plugin X"; }
}
public string Run(string input)
{
return input;
}
}
}
Step 3: Run the plugin.
namespace PluginTest
{
using System;
using System.IO;
using System.Runtime.Remoting;
using PluginInterface;
class Program
{
static void Main( string[] args )
{
string pluginFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "PluginX.dll");
ObjectHandle handle = Activator.CreateInstanceFrom(pluginFile, "PluginX.Plugin");
IPlugin plugin = handle.Unwrap() as IPlugin;
string pluginName = plugin.Name;
string pluginResult = plugin.Run("test string");
}
}
}
Keep in mind, this is just the basic, most straightforward example of a plugin architechure. You can also do things such as
create a plugin host to run your plugin inside of it's own AppDomain
choose either interfaces, abstract classes, or attributes to decorate your plugins with
use reflection, interfaces, IL-emitted thunks or delegates to get the late binding job done
if your design so dictates.
It's valuable to separate technical and architecturas perspectives:
In code level MEF (Managed Extensibility Framework) is a good start. Here is a simple example.
Any other DI (Dependency Injection framework) can work well to (ie. Unity)
And it's good to see this problem in architectural level:
Web Client Software Factory from p&p. Here are not only technical but arcihtectural informations about "How to create composite web applications?". See examples.. There is Modularity Boundle package.
Spring Framework.
I think it's a fast and efficient if you read&try some of those frameworks. And ofcoz read the source if you find something interessing.
Edit
if you are searching for an extensible blog engine then try Blog Engine first. It's from ASP.NET community.
This sounds like a job for the Managed Extensibility Framework from Microsoft. It's in a preview release at the moment but it would seem to be a better bet than rolling your own framework for this. There are links to guides about how to use this on the site there.
If you would like to see a real, open source application that impliments this archecture take a look at DotNetNuke.