Are there any dependencies for UI Automation? - c#

I have a Windows application which captures the details from screen based on the configuration. I am using UI Automation to capture the details from the screen. Everything works fine on the developer's machine where Visual Studio is installed. When I run the same application on another system where we have only .NET Framework 4.5 installed, it started behaving strangely, and it's not able to detect the child element.
My question is why it works fine on the developer's machine where Visual Studio and .NET Framework are installed. What's the difference? Is there anything we are missing as far as prerequisites? Any dependencies of UI Automation or any library we are missing..?
Thanks in advance - please help me out.

It looks like a known bug in .NET wrapper around native UIAutomationCore.dll (yes, its core is not a .NET). And it's included into WinVista+ (.NET Framework also adds it even to WinXP).
Here is a C# example how to use native COM API (UIAutomationCore.dll) from C#. Just copying the code here:
using System;
using interop.UIAutomationCore;
namespace PrintDesktopUiaElementNameViaCom
{
class PrintDesktopUiaElementNameViaComProgram
{
static void Main(string[] args)
{
// Instantiate the UIA object:
IUIAutomation _automation = new CUIAutomation();
// Get the root element
IUIAutomationElement rootElement = _automation.GetRootElement();
// Get its name
string rootName = rootElement.CurrentName;
Console.WriteLine(
"The root automation element's name should be 'Desktop'.");
Console.WriteLine("The actual value is: '{0}'", rootName);
}
}
}

Yeah at last after doing day's reading, i came to know the solution is that der is no dependency on Visual studio.
This behavior is due to lack of privileges to the application. so to overcome this behavior we have to get signed our application and one more thing its very important thing is place your executable file in Program Files
Reference Links : https://msdn.microsoft.com/en-us/library/windows/desktop/ee671610(v=vs.85).aspx

Related

Trying to call x86 .Net 3.5 SDK in more recent .Net versions

This may be a long shot... I need to create a simple-ish web app that needs to call an OEM supplied SDK that is 10-15, or more, years old (no updates are possible). The SDK is 32bit and is pegged to .Net Framework 3.5. There is still an active NDA for using the SDK so there is not much that I can share.
I have access to Visual Studio 2015, 2017 and 2019. In each version I can go through the process of creating a C# web app and I can select .Net 3.5 as the target framework but the only available template is a "Blank" one. Are there MVC based templates for 3.5? I have googled and have not found any.
That is my first problem. I decided to just move on and try newer .Net versions that might have a more complete template set. I have tried 4.8 most recently.
Using .Net 4.8 and specifying an "x86" platform I can create a simple app. I can call the SDK lib and get values from the simple library "get" methods like "getHeight", "getWidth", etc. The SDK is for an old computer controlled device that still works like a charm. It has a camera and one of the available functions is GetCameraImage.
The SDK comes with documentation and some sample C# "SLN"s. One of those has the following sample code:
var idata = new byte[numOfBytes];
unsafe {
fixed (byte* fixedPtr = idata) {
channel.GetCameraImage((int) numOfBytes, out idata[0]);
}
}
In my code the above just crashes with an "Access Violation". No exceptions are thrown in the debugger. It just dies.
The docs that come with the SDK suggest that the following is valid:
var idata = new byte[numOfBytes];
channel.GetCameraImage((int) numOfBytes, out idata[0]);
but I get the same Access Violation.
Any ideas about the Access Violation?
EDIT
#Serg: Addressing a couple of comments: var idata = new byte[numOfBytes*3] did not work but was a great idea.
#DekuDesu: I am not sure how to exactly verify that the memory is allocated so I did the following:
var idata = new byte[numOfBytes];
for (var i=0;i<numOfBytes;i++) {
idata[1] += 0;
}
channel.GetCameraImage((int) numOfBytes, out idata[0]);
I also tried this with #Serg's offset idea and the violation is definately triggered by the GetCameraImage call.

How to retrieve data from Elipse server with .Net Core? Am I restrained to .NET Framework for using a DLL?

I have an Elipse E3 Studio (build 5.0.434) server with a bunch of tags (running on a x64 windows) and I want to read then from a .NetCore (3.0) console application (same machine). The thing is Elipse works with COM (as far as I know) and .NetCore can't natively handle it. Gotta use some Interoperability Library or something. .netCore3.0 Release Notes at Windows Native Interop
To make the Elipse server work I used a hardkey so the server was running locally.
I have named my tag "A1" and set the value inside Elipse.
To make the access I made a C# program using e3DataAccessLib and referenced it on the .csprj.
The Program.cs is as follows :
using System;
using E3DATAACCESSLib;
namespace ElipseNetCore{
class Program{
static void Main(string[] args){
try{
E3DataAccessManager e3DA = new E3DataAccessManager();
e3DA.Server = "localhost"; //kinda pointless but still
object Value = new object();
object Timestamp = new object();
object Quality = new object();
e3DA.ReadValue("A1.Value", ref Timestamp, ref Quality, ref Value); //ReadValue is a Elipse Server method that takes in a "tag" and place the result in the ref's
Console.WriteLine($"Value: {Value}, Timestamp: {Timestamp} and Quality: {Quality}");
}//end try
catch(Exception ex){
Console.WriteLine("the mother funking error now is :" +ex.ToString());
//regsvr32 C:\Users\lucas.battistella\Documents\Desenvolvimento\ElipseNetCore\ElipseNetCore\obj\Release\netcoreapp2.2\win-x64\ElipseNetCore.dll
}//end catch try
}//end Main
}//end Program
}//end namespace
The Error I get is the following:
System.Runtime.InteropServices.COMException (0x80040154): Retrieving the COM class factory for component with CLSID {80327130-FFDB-4506-B160-B9F8DB32DFB2} failed due to the following error: 80040154 Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG)).
Other answers point to a x32 on a x64 or vice-versa issue.
However I've already tried making sure everything is running on x64.
Then I tried everything on x32/x86.
Also tried manually registering the .dll with regsvr32 (as show in the commented out line in the first code block and also the E3DATAACESSLib.dll), got and error popup saying "the said dll was loaded but the entry point DllRegisterServer was not located. Verify if the said dll is a DLL or OCX file"
I've been entangled with this problem for a few days now and since I'm new to all this I don't even know if I'm tumbling in the right direction. I would really appreciate any explanation and please excuse my typos.
How do I retrieve data from an Elipse server? Have I missed something?
UPDATE: I have tried that exact same code on Visual Studio running on .Net Framework 4.7.2 and it worked.
Also tried (still on Visual Studio) on .NetCore and got the aforementioned error.
Work Around:
Forget about NetCore and migrate to NetFramework 4.8. Forget about VSCode and keep rolling with VS.
Every time I look back at this problem it intrigues me. The E3DATAACCESSLib was build against x32 and for NetFramework (which mean Windows necessarily). The weird bit is that it ran on my machine targeting x86 (VS and NetFramework 4.8) but not on VSCode and NetCore. I read conflicting information on libraries built for NetFramework working (or not) on Core.
Today I tried running the built working code on a different machine (virtual and remote) and it showed me the exact same error message. And I fixed it by installing the E3 program and restarting the machine, simple as that.
If that ring any bell to you please share the light.

NLog - System.MethodAccessException only in VMWare Horizon View client

I updated my C# WPF application to use latest versions of NLog and NLog.Extensions.Logging.
It works everywhere except in this VMWare Horizons client where it crashes with this error:
$exception {"Attempt by method 'NLog.Extensions.Logging.NLogLoggerProvider..ctor(NLog.Extensions.Logging.NLogProviderOptions, NLog.LogFactory)' to access method 'NLog.LogManager.get_LogFactory()' failed."} System.MethodAccessException
This project is currently using NLog v4.5.11 and
NLog.Extensions.Logging v1.4
A previous version of my application which uses NLog v.4.4.12 and
NLog.Extensions.Logging v1.0 worked in this VM so i am trying to fall back to that. Then i'll work my way up the versions of these libraries.
More to follow soon... meanwhile, any insight into what might be causing this would be very welcome.
using Microsoft.Extensions.Logging;
using NLog.Extensions.Logging;
using System;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
var loggerFactory = new LoggerFactory();
var Logger = loggerFactory.CreateLogger<Program>();
loggerFactory.AddNLog();
Logger.LogDebug($"============{Environment.NewLine}");
Console.ReadLine();
}
}
}
You have a problem with your deployment. Your application is not using NLog ver. 4.5 (But some older version).
LogFactory-property became public with this: https://github.com/NLog/NLog/pull/2316
Maybe you have old NLog registered in Windows GAC ? (Global Assembly Cache)
Maybe try writing the typeof(NLog.LogFactory).Assembly-location using Console.WriteLine.
I'll add to answer https://stackoverflow.com/a/54557849/8081796
This issue is actual for Windows 8.
Get path to used NLog.dll:
typeof(NLog.LogFactory).Assembly.Location
If the path leads somewhere in C:\Windows\Microsoft.NET\assembly\GAC_MSIL then just delete this file
Thanks Stepan.
As I recall, it is not easy to delete a file from the GAC. And from what I have learned, not a good practice because it could break another application that depended on it.
Windows installer maintains a reference count of items in GAC, increasing the count with each install, reducing with each uninstall. If the count goes to 0, the dll is also removed from the GAC.
I uninstalled the application that put Nlog in the GAC. (It was another application that I had written long ago.) Then i modified the installer for that old app, ensured that it did not put it back in the GAC and re-installed it. And everything was well again.

Instance of AggregateException causes TargetInvocationException

I have a problem that an instance of an AggregateException causes a TargetInvocationException after a couple of accesses to an Icon resource.
I broke down the problem to the following steps to reproduce (.Net 4.0 full or client profile):
Create a new WinForms application (a console application will not work)
Add an arbitrary icon (.ico file) to the resources
Add the following code to the constructor:
new AggregateException();
for (var i = 0; ; ++i)
{
var icon = Resources.Certificate;
}
You have to change the resource name to the name of your resource.
That's all. Yes I know that this sample doesn't make sense. It's just to illustrate the problem. My working code is much more complex and all of this code is needed.
Without creating this excection the application will work forewer. But if this exception is created the access to the resource will fail with a TargetInvocationException. The InnerException told me that the operation has been finished successfully(?!?!) having a two-line stack trace in System.Drawing.Icon (ctor + Initialize).
What can I do to prevent this problem?
EDIT
It seems to be a problem using Windows 7. A binary which fails on Win 7 will run correctly in Win 8.1.
I found the reason for that problem:
The following system configuration is needed to reproduce the issue:
Windows 7 German Edition
Microsoft .Net Framework 4.5.2 installed (yes I know my binary is compiled against .Net 4.0)
KB2901983 installed
Having a machine which only contains the .Net Framework without KB2901983 the program works fine. After installing KB2901983 the program fails for the same binary (no recompilation required).
I tried to uninstall KB2901983 but it doesn't help. If it was once installed the program will fail. I tested it on a clean Windows 7 German Edition.

PerformanceCounters on .NET 4.0 & Windows 7

I have a program that works fine on VS2008 and Vista, but I'm trying it on Windows 7 and VS2010 / .NET Framework 4.0 and it's not working. Ultimately the problem is that System.Diagnostics.PerformanceCounterCategory.GetCategories() (and other PerformanceCounterCategory methods) is not working. I'm getting a System.InvalidOperationException with the message "Cannot load Counter Name data because an invalid index '' was read from the registry."
I can reproduce this with the very simple program shown below:
class Program
{
static void Main(string[] args)
{
foreach (var pc in System.Diagnostics.PerformanceCounterCategory.GetCategories())
{
Console.WriteLine(pc.CategoryName);
}
}
}
I did make sure I'm running the program as an admin. It doesn't matter if I run it with VS/Debugger attached or not. I don't have another machine with Windows 7 or VS2010 to test it on, so I'm not sure which is complicating things here (or both?). It is Windows 7 x64 and I've tried forcing the app to run in both x32 and x64 but get the same results.
It seems performance counters were corrupted on my system. Although I didn't follow this post exactly, it led me to the solution. Here is what I did:
In an command prompt with administrator/elevate privileges typed the following:
lodctr /?
Useful stuff in there...
Then typed:
lodctr /R
According to the docs from the prior step, this gets windows to rebuild the perf registry strings and info from scratch based on the current registry settings and backup INI files. I have a feeling this is what did the magic. However, next I noticed the .NET performance counters were not there anymore so based on this I typed the following to reload them:
lodctr "C:\Windows\Microsoft.NET\Framework64\v4.0.20506\corperfmonsymbols.ini"
Note that this path is for .NET Framework 4.0 on x64. You can imagine the path for other variations of the framework/platform. I'm guessing you should always load the counters from the highest version of the .NET framework that you have installed, but that is just a guess.
I hope this helps someone else someday!

Categories