WMI ManagementOperationObserver doesn't work against remote box - c#

I'm trying to figure out how to do WMI queries against a remote computer asynchronously using C# on .Net 4.5.
I'm using the ManagementObjectSearcher class, and using the Get(ManagementOperationObserver watcher) method; more or less I'm using the example from here https://msdn.microsoft.com/en-US/library/ms257344(v=vs.80).aspx
It doesn't work.
Here's what I know:
When I use wbemtest to connect to the remote computer and execute a query (SELECT * FROM Win32_Service) synchronously it works.
When I set wbemtest to be asynchronous, it also works, so it isn't a configuration issue on my workstation or my target machine, and my credentials work fine.
If I have my C# code connect to my local workstation, performing the same query asynchronously using ManagementOperationObserver also works fine.
When I change my C# code to connect to my remote target machine, it doesn't work. None of the events on the ManagementOperationObserver ever fire, and my application just sits there waiting. I've left it sit there for minutes and nothing happens.
My workstation is part of a domain, and my target remote machine is not, if that matters (since wbemtest works both sync/async I'm not sure it matters).
At this point I don't know what to try next. Does ManagementOperationObserver just not work for remote queries?

Ok, by default, Visual Studio 2013 sets "Prefer 32bit" to true on console applications. My workstation is 64bit; I turned this off, now my remote calls work :/

what's your explanation that in case you are running code as 32b it doesn't work, but under 64b compilation it works fine? For it's quite scary situation.

I am trying myself to get results from async call and still have issue with it: the code get executed, but I don't see the final result.
My code is installing a printer remotely from WMI. In the Win32_Printer, I am using
printer.Put(operationWatcher);
and in the event, setting a bool that I am monitoring.
private void OperationWatcher_ObjectPut(object sender, ObjectPutEventArgs e)
{
if (e.Path.ClassName == "Win32_Printer")
{
printerSuccessfullyPut = true;
Console.WriteLine("should be installed");
}
}
The code got properly executed, but I don't get my printer installed. If I make a sync call
printer.Put();
the printer is installed. Very strange.
Wonder if the issue might have similar background as the one mentioned here (about Start method with ManagementEventWatcher)
http://blogs.microsoft.co.il/sasha/2012/09/20/asynchronous-wmi-queries-stay-away-from-them/

Related

why Control M OS Job that executes an exe gets stuck mid execution?

I have a c# exe that reads some log lines from a remote unix server using sed. when I run this exe several times on my windows server or even my dev pc, it executes fine. However, when I try to run it as a cyclic OS job in Control M eventually (sometimes at the first execution, seems to happen at random) it gets stuck but doesn't throw an exception or anything.
The command of the job runs a .bat file, and the cyclic is configured to 0 minutes with pause time being controlled dynamically by the exe with a thread.sleep.
after searching the web and seeking recommendation from other areas of my workplace that use control M, I have so far tried changing my agent to use local user with ctmwincfg, I also tried with changing the agent service to the same user (had to reverse this one as the agent stopped working properly), I also changed from directly executing my exe on the job to using a .bat file.
one of my hostgroup agents is windows server 2016 and 3 more are windows server 2012
I wasn't able of finding a solution within control M itself, but rather in the code of the .exe. I used a task, it allows the program to terminate the stuck method after a timeout, which in turn allows the control M job to finish normally.
var task = Task.Run(() => MyStuckMethod(arg));
if (task.Wait(TimeSpan.FromSeconds(30)))
return task.Result;
else
throw new Exception("Timed out");
Alternatively, there are a few workarounds within control M which involve sending alerts or creating shouts and then automating the kill of the job, but this is not useful for my case.
Example in BMC communities

UnauthorizedAccessException when trying to open serial port in C#

I'm using .NET 4.5.2. In one of my ViewModels, I need to access serial port COM8, which is connected to my device, a sensor that provides a continuous stream of data. I can access and send commands to the serial port via Tera Term, Windows Command Prompt, and a LabView application, so the port is not occupied by another process - I know that is usually the case with these posts, but I'm very sure that is not the case here. I've tried sending a command to the port via C# using the Process() class, but that does not work, so it seems to be something with C#.
I saw this post: Force a COM port to close, but that does not seem to be the issue either.
Other things I've tried:
Uninstalling the COM8 device via Device Manager.
Running the application in "Release" mode via Visual Studio.
Running Visual Studio in Administrator mode.
Switching to .NET 4.5.2.
And a few other things that I'm not recalling right now. Any advice about this situation would be appreciated! I'm happy to provide any more information you may need.
Code to open the port:
if (port == null)
{
port = new SerialPort(location, baudRate);
port.ReadBufferSize = 16384;
}
if (!port.IsOpen)
{
port.Open();
}
Update:
If I copy the above code into the startup method, it works fine. It just doesn't seem to work where it is in my ViewModel. I thought it was a threading issue, but I was able to call the code in the main thread and it did not work. Hopefully this will get me closer to a solution!
Update 2:
The code above also works fine in the codebehind of my login method, but in no other codebehind. Super confused right now.

Graphics.CopyFromScreen() and GetDC(0) fail with "The handle is invalid"

I have an application that takes screenshots from the local computer.
This works since many years correctly until suddenly a colleague reported me that he got an "The handle is invalid" error from my application.
This error came from inside the .NET framework from Graphics.CopyFromScreen().
To work around this I replaced this function with C++ code using GetDC(GetDesktopWindow()) / GetDC(NULL) and BitBlt() to copy the screen into a bitmap. Now I got ERROR_INVALID_HANDLE.
This happens on Windows 7.
What is going on there ?
I can not investigate this problem on my own because I cannot reproduce it and my colleague is in another country.
I searched in Google and lots of people report this error.
But all posts that I found were from people who tried to take a screenshot from a client computer through ASP code on a server. I don't understand how people can have the strange desire to capture the client's computer from a website. It is obvious that this will not work.
But I could not find one single case where someone reports this problem from an application that cannot capture the screen of the SAME computer in the SAME session where the application itself is running.
After investigating more with my colleague and giving him ideas what he can try, he told me that he starts my application through a remote desktop session.
The remote desktop session creates a virtual desktop (you see for example that the desktop wallpaper is missing).
I told my colleague to install a VNC client to remote control the computer instead of a remote desktop session and now all works fine. He installed TightVNC which uses the REAL desktop user session instead of creating a virtual session and locking the screen of the machine.
So if anyone gets reports of "The handle is invalid" while taking a screen capture, ask your users if they use a remote desktop session.
To detect a remote desktop session in code you can write:
in C++:
if (GetSystemMetrics(SM_REMOTESESSION) > 0)
{
MessageBox(m_hWnd, L"This application may not work correctly in a remote desktop session", "Error", MB_ICONSTOP);
}
or in C#:
if (System.Windows.Forms.SystemInformation.TerminalServerSession)
{
Messagebox.Show("This application may not work correctly in a remote desktop session");
}
Note that the problem is not reproducible on all computers. When I test on my own Windows 7 it works. So there are probably any additional system settings or other factors that trigger the "The handle is invalid" error (service packs / hotfixes...?).
But my colleague reports that he has never seen the error again after he stopped using the remote desktop connection.
There are a few reasons this can happen but the underlying theme is that the desktop window isn't available when this method is called.
In addition to the reasons mentioned above, another reason this can happen is if this method is being called when the screen is locked.
The code for CopyFromScreen has this section:
int result = SafeNativeMethods.BitBlt(targetDC, destinationX, destinationY, destWidth, destHeight, screenDC, sourceX, sourceY, (int) copyPixelOperation);
//a zero result indicates a win32 exception has been thrown
if (result == 0) {
throw new Win32Exception();
}
It would seem to me that the safest course of action would be that if you make use of this function, make sure that you also write your code assuming that receiving a Win32Exception or an unavailable Desktop Window is a use case which must be handle so the application doesn't crash.

Selenium 2.0 Remote web driver fails to start IEDriver with C#

DesiredCapabilities capabilities = DesiredCapabilities.InternetExplorer();
System.Environment.SetEnvironmentVariable("webdriver.ie.driver", #"C:\\IEDriverServer.exe");
instance = new RemoteWebDriver(new Uri("http://localhost:4444/wd/hub"), capabilities);
I also have the a system variable set, and the IEDriverServer is in the system path. I cannot run the IEDriver from command line (which makes me thinking is there something wrong with path configuration, or some security restriction)
note that the hub and the node are one and the same machine.
when I execute the test I get:
"System.InvalidOperationException:
The path to the driver executable must be set by the webdriver.ie.driver system property; for m....."![enter image description here][1]
I'm running this one one machine both acting as a hub and a node just to make a proof of concept it'll work for me.
There are a number of things I'd question about your approach to what you're trying to accomplish. First, if you're running your C# code on the same machine as the remote Java server (node/hub), why bother? You can easily just use the InternetExplorerDriver class and eliminate the Java server altogether.
Second, setting an environment variable is not the same as setting a Java system property. You can set the system property by using a -D command line flag on the command line with which you launch the Java .jar.
Finally, if you're actually running the Java server on a different machine from the C# code, and are correctly using RemoteWebDriver, bear in mind that you need IEDriverServer.exe on the machine running the Java server, and not the one running your C# code. Furthermore, you need the hub/node to be aware of the path to the executable on that machine, not to the executable where your C# code is running.
I've got it solved, used the appropriate version IEDriver and fixed the PATH and it worked.

ClickOnce fails to initialize with no network

I have an application that I have just added ClickOnce to as an update method. I'm about to pull it and do something else, even after working through all the gotchas of dealing with ClickOnce in a moderately complex application. Well, it's not even a complex application, but it's going onto dedicated hardware, so I have a few odd requirements, like completely transparent and automatic updates, no odd little pup-up windows, etc. The main one is that the application starts and takes over the system at boot.
Where this causes trouble for ClickOnce is that when the system first boots, there is no network - the Wi-Fi is still getting started and connecting. The application handles this, checking for the network to get started and then connecting to our server. ClickOnce is a different matter. If there is no network when the application starts, then all the ApplicationDeployment functions will not work, even after the network is started.
So, for example, I use something like this to get the version:
if (ApplicationDeployment.IsNetworkDeployed)
Version = ApplicationDeployment.CurrentDeployment.CurrentVersion.ToString();
else
Version = "unknown";
If I run the application at boot (that is, before the network is working), this code will return "unknown" for the rest of the application run, even after the network is up. If I shut down the application and restart it, it shows the deployed version. So technically, the IsNetworkDeployed is returning an incorrect value. The application WAS network deployed; it's just not on a network NOW. I'll probably post this as a bug over on MSDN.
BTW, the application does not actually require a network to run, so at startup, I can't take the path of "wait until the network is ready, then restart the application automatically". The hardware can move around, and may be in the middle of nowhere with no available network at all. I still have to deal with that (and I don't actually return "unknown" for that case, I just pull the version from the assembly). And if the problem was just getting a version, I wouldn't care, but this means that there is no way to ever update the application, since it always starts with no network, and it will never get to my code to check for, download, and auto-update the application.
Before I write off all my ClickOnce work, I was wondering if anyone knew of a way to reinitialize ApplicationDeployment, so that it will figure out that there is a network and enable all that ClickOnce goodness.
This is basically what that check is doing:
private static bool _isNetworkDeployed;
private static bool _isNetworkDeployedChecked;
public static bool IsNetworkDeployed
{
get
{
if (!_isNetworkDeployedChecked)
{
_isNetworkDeployed = (
AppDomain.CurrentDomain != null &&
AppDomain.CurrentDomain.ActivationContext != null &&
AppDomain.CurrentDomain.ActivationContext.Identity != null &&
AppDomain.CurrentDomain.ActivationContext.Identity.FullName != null);
//_isNetworkDeployed = ApplicationDeployment.IsNetworkDeployed;
_isNetworkDeployedChecked = true;
}
return _isNetworkDeployed;
}
}
We ran into the same issue with ClickOnce and reverse engineered the check. You could modify this to do your own checking prior to calling the .NET version.

Categories

Resources