VMWare vix api - not logging in into Vitual machine - c#

While powering up the virtual machine:
var virtualMachine = host.Open("myVM.vmx");
virtualMachine.PowerOn();
virtualMachine.LoginInGuest("Administrator", "myPass");
everything gets stuck in the log in screen of the VM. Is it possible somehow to start up the VM, and have the GUI loaded and ready, because automated tests require the GUI of the application to be present so the tests can fire off.

pass VIX_LOGIN_IN_GUEST_REQUIRE_INTERACTIVE_ENVIRONMENT to LoginInGuest.
See the remarks: https://www.vmware.com/support/developer/vix-api/vix17_reference/lang/com/functions/RunProgramInGuest.html

Related

Unable to Pass Selenium tests within Azure Pipeline

I am trying to build out UI test cases in our CI/CD build pipeline within Azure Devops and I can't seem to workaround a basic use case where we route to one of our internal web pages landing screen, and verify a Div with a Selector exists.
[Theory]
[InlineData("Chrome")]
public void TestFindElementByID(string browser)
{
var driver = SetupDriver(browser);
try
{
driver.Navigate().GoToUrl(TestConfig.WebURL);
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
IWebElement element = wait.Until(ExpectedConditions.ElementIsVisible(By.Id("mainRepDiv")));
//Thread.Sleep(2500);
//IWebElement element = driver.FindElement(By.Id("mainRepDiv"));
Assert.True(element != null);
}
catch (Exception ex)
{
}
finally
{
driver.Quit();
}
}
In my web page, I have a basic div that I just want to see that it exists once the chromedriver navigates to the URL.
Element To Check
And here is a log of the Azure Pipeline failing on this test.
Pipeline Log
I do have an additional test that just asserts that the Browser is able to go to the URL, and the URL is in fact what I routed to, and that test passes.
driver.Navigate().GoToUrl(TestConfig.URL);
Assert.True(driver != null);
Assert.True(driver.Url.ToLower() == TestConfig.URL.ToLower());
There also some layers that likely are making this more difficult such as
The Azure Pipeline is running off a Self-hosted agent.
This self hosted agent is also the same server that is running the application were trying to test against.
There is OS level Security that shows up if you route to it normally, however as the Windows Server that is running the application would have a valid credential to the browser, it should bypass this dialog.
So things I have tried so far:
Various ways of actually selecting the Element incase that was off, such as By ID that is shown, or by XPath as well.
Using the Thread.Sleep() or the WebDriver Wait commands to determine if it was a page load.
Implementing AutoIT Process that will run in the event there is in fact an OS popup that displays, so I can prefill the Admin Username/Password credentials incase it actually is not getting there.
Running the unit test locally on my client PC, publishing the code to the Server, running the code from the application server directly and verifying it works there as well.
So I'm a bit at a loss what to check on regarding the Azure Pipeline build itself and why the ChromeDriver is unable to pass this test.
Finally - if this is also helpful, here is a screenshot of the YML file pertaining to the Tasks.
- task: VSTest#2
displayName: "Run UI Tests"
inputs:
testSelector: 'testAssemblies'
testAssemblyVer2: |
**\Project.Test.UI.dll
!**\*TestAdapter.dll
!**\obj\**
searchFolder: '$(System.DefaultWorkingDirectory)'
uiTests: true
Unable to Pass Selenium tests within Azure Pipeline
Please make sure your private agent run as an interactive process.
According to the document Interactive vs. service:
You can run your self-hosted agent as either a service or an
interactive process. After you've configured the agent, we recommend
you first try it in interactive mode to make sure it works. Then, for
production use, we recommend you run the agent in one of the following
modes so that it reliably remains in a running state.
As an interactive process with auto-logon enabled. In some cases, you might need to run the agent interactively for production use -
such as to run UI tests. When the agent is configured to run in this
mode, the screen saver is also disabled. Some domain policies may
prevent you from enabling auto-logon or disabling the screen saver. In
such cases, you may need to seek an exemption from the domain policy,
or run the agent on a workgroup computer where the domain policies do
not apply.
So, if your agent not run as interactive mode, please configure a another agent in interactive mode to test this issue.

C#: Programmatically Detect Windows Server Has Booted

I'm working on an automation process in C# that is going to remotely reboot a Windows (2008/2012/2016) server and I need to wait until that server is back online before proceeding.
I know 'back online' can be ambiguous, so for my requirements, I need the server to be back at the Ctrl-Alt-Del screen.
The reason for this is to have the server in a consistent state before proceeding. In my experience, there are several factors that could prevent the server from reaching this screen, such as installing windows updates that gets stuck in a reboot cycle or getting stuck at 'Waiting for Local Session Manager' etc.
I've spent a few days looking in to this to no avail:
The server obviously starts responding to ping requests before it is available
System Boot Time occurs before the Server reaches the desired state
Any events indicating the system has booted are logged before the desired state
I can't simply poll for an essential service - when Windows is applying computer updates prior to logon these services can be already started. Additionally, sometimes a server will reboot itself whilst installing updates at this stage which could result in false positives.
Polling CPU activity could also produce false positives or introduce delays
Is there anyway to detect a Windows server has finished booting and is available for an interactive logon?
It sounds like you've covered most of the possible ways I know of. Which makes me revert to brute force ideas. I am curious what you're doing where you can't install a windows service on the box (or is that just not very viable because of the number)
First would just be trying to remote login or whatever, and having some way to test if it fails or not, wait 1 minute, try again. But seems like that might cause side-issues for you somehow?
My idea of a brute force method that wouldn't affect state:
Ping every 1-5seconds
Once it starts responding
wait 5 or 10 or even 15 minutes, whilst still pinging it
If pings fail reset that timer (windows updates restart case)
Then be pretty confident you're at the right state.
With potentially thousands of servers, I can't imagine 15 minutes each would be a big deal, especially if it is consistent enough to be able to run in larger batches
So I've been able to accomplish this by using a hacky method put seems to work in my test environment.
Note that the el.Current.Name property will equate to the Ctrl-Alt-Del text, so on 2008R2 this is 'Press CTRL-ALT-DEL to log on' and 'Press CTRL-ALT-DEL to sign in.' on 2012R2
I've built a C# console application that uses UI Automation:
using System;
using System.Windows.Automation;
namespace WorkstationLocked
{
class Program
{
static void Main()
{
AutomationElement el = AutomationUI.FindElementFromAutomationID("LockedMessage");
if (el !=null)
{
Console.WriteLine(el.Current.Name);
}
}
}
class AutomationUI
{
public static AutomationElement FindElementFromAutomationID(string automationID)
{
string className = "AUTHUI.DLL: LogonUI Logon Window";
PropertyCondition condition = new PropertyCondition(AutomationElement.ClassNameProperty, className);
AutomationElement logonui = AutomationElement.RootElement.FindFirst(TreeScope.Children, condition);
if (logonui != null)
{
condition = new PropertyCondition(AutomationElement.AutomationIdProperty, automationID);
return logonui.FindFirst(TreeScope.Descendants, condition);
}
else
{
return null;
}
}
}
}
I can then execute this console application via PsExec, however, because this needs to be launched in the winlogon desktop, which can only be done by running under the local system, PsExec is invoked twice. For example:
psexec.exe \\ServerA -s -d C:\PsTools\PsExec.exe -accepteula -d -x C:\Utils\WorkstationLocked.exe
This is very much a work in progress right now as I can't get the output of the command to pass through to the calling process so I may just look to populate a registry value or write to a file that can be subsequently interrogated.

Process.Start won't work

I am trying to launch a process from a web page's back-end code/app pool. This process will launch an App that i built myself.
For some reason, the process only works / runs when i start it from VS2013... it never works when i launch it from IIS(7.5) itself.
I am on a Windows 7 machine (both IIS host, and App location), and I've setup my web site to only be accessible via internal network.
Here's the code, followed by the config / attempts to fix the issue:
protected void btn_DoIt_Click(object sender, EventArgs e)
{
string file_text = this.txt_Urls.Text;
if (!String.IsNullOrWhiteSpace(file_text))
File.WriteAllText(ConfigurationManager.AppSettings["filePath"], file_text);
ProcessStartInfo inf = new ProcessStartInfo();
SecureString ss = GetSecureString("SomePassword");
inf.FileName = #"........\bin\Release\SomeExecutable.exe";
inf.Arguments = ConfigurationManager.AppSettings["filePath"];
inf.UserName = "SomeUserName";
inf.Password = ss;
inf.UseShellExecute = false;
//launch desktop app, but don't close it in case we want to see the results!
try
{
Process.Start(inf);
}
catch(Exception ex)
{
this.txt_Urls.Text = ex.Message;
}
this.txt_Urls.Enabled = false;
this.btn_DoIt.Enabled = false;
this.txt_Urls.Text = "Entries received and process started. Check local machine for status update, or use refresh below.";
}
Here are the things I've tried to resolve the issue:
Made sure the executing assembly was built with AnyCPU instead of
x86
Ensured that the AppPool that runs the app, also runs under the same account (SomeUsername) as the ProcessStartInfo specified.
Ensured that the specific user account has full access to the executable's folder.
Ensured that IIS_USR has full access to the executable's folder.
Restarted both the app pool and IIS itself many times over implementing these fixes
I am now at a loss as to why this simply will not launch the app... when i first looked into the event log, i saw that the app would die immediately with code 1000:KERNELBASE.dll, which got me on the AnyCPU config instead of X86 fix... that fixed the event log entries but the app still doesn't start (nothing comes up in task manager), and i get no errors in the event log...
if someone could help me fix this problem i would really appreciate it. This would allow me to perform specific tasks on my main computer from any device on my network (phone, tablet, laptop, etc etc) without having to be in front of my main PC...
UPDATE
The comment to my OP, and ultimate answer from #Bradley Uffner actually nailed the problem on the head: My "app" is actually a desktop application with a UI, and in order to run that application, IIS would need to be able to get access to the desktop and the UI, just like if it were a person sitting down in front of the PC. This of course is not the case since IIS is running only as a service account and it makes sense that it shouldn't be launching UI programs in the background. Also see his answer for one way of getting around this.
Your best bet might be to try writing this as 2 parts. A web site that posts commands to a text file (or database, or some other persistent storage), and a desktop application that periodically polls that file (database, etc) for changes and executes those commands. You could write out the entire command line, including exe path command arguments, and switches.
This is the only way I can really think of to allow a service application like IIS to execute applications that require a desktop context with a logged in user.
You should assign a technical user with enough high priviliges to the running application pool. By default the application pool is running with ApplicationPoolIdentity identy which has a very low priviliges.

Reliable method for detecting if Webex Client is running

What is the best method for determining if the Cisco Webex client is running on a user's computer? Currently, I'm checking for a running process like this:
public static bool IsWebExClientRunning()
{
// webex process name started from internet browser (could change). Just use Process Explorer to find the sub process name.
// alternate name - CiscoWebexWebService
Process[] pname = Process.GetProcessesByName("atmgr");
return pname.Length > 0;
}
While this method works, there could be an instance where Cisco pushes out updates to their client that changes the process name which would break this code if we're looking for a specific process name.
The Webex client starts as a child process from an Internet browser since it is technically a browser plugin and it doesn't show up on its own in Windows Task Manager. I have seen both atmgr and CiscoWebexWebService using Process Explorer to find the process. Sometimes, depending on the host operating system, Windows XP/Windows 7, it will just display atmgr and not the child process CiscoWebexWebService belonging to atmgr. It also varies slightly based on the browser that is used. It runs as a browser plugin for all supported browsers and for unsupported browsers, it will give the option to run as a standalone application.
The process tree can vary (i.e. other browsers/operating systems), but it looks something like this:
iexplore.exe
-> atmgr.exe
-> CiscoWebexWebService.exe
Obviously, all checks must be done client side and not server side, but is there a better method for approaching this?
I spoke with a Cisco specialist and they said that my current approach should be safe for detecting if the Webex client is running a user's machine. They were able to confirm that the process name is atmgr.exe and should not change in the near future.

Keep C# application running

I'm building a Windows Service that uses FileSystemWatcher, and runs in the background.
I don't want to keep on uninstalling and installing the service every time I want to debug, so would like to do most of my development in a normal program before moving it into a service. But I'm quite new to this, and when I run it, it just runs through the block and exits.
What would be a good way to keep the program running?
http://einaregilsson.com/run-windows-service-as-a-console-program/
I've used this before to debug my service as a Console application based on whether its running in an interactive user environment.
public partial class DemoService : ServiceBase
{
static void Main(string[] args)
{
DemoService service = new DemoService();
if (Environment.UserInteractive)
{
service.OnStart(args);
Console.WriteLine("Press any key to stop program");
Console.Read();
service.OnStop();
}
else
{
ServiceBase.Run(service);
}
}
while (true)
{
// Execute your program's functionality here.
}
I wrote a 7 part series a while ago titled: Building a Windows Service. It covers all the intricacies of building services, making them friendly to debug, and self-installing.
The basic feature set I was looking for was as follows:
Building a service that can also be used from the console
Proper event logging of service startup/shutdown and other activities
Allowing multiple instances by using command-line arguments
Self installation of service and event log
Proper event logging of service exceptions and errors
Controlling of start-up, shutdown and restart options
Handling custom service commands, power, and session events
Customizing service security and access control
The final result was a Visual Studio project template that creates a working service, complete with all of the above, in a single step. It's been a great time saver for me.
see Building a Windows Service – Part 7: Finishing touches for a link to the project template and install instructions.
Here’s documentation from MSDN # http://msdn.microsoft.com/en-us/library/7a50syb3(v=vs.80).aspx?ppud=4 . I have tried it before and it works under .NET Framework 3.x. I could not find my descriptive notes on it, at the moment.
Use the pragma #If DEBUG for debugging purposes like console outputs. Another is using the Debug object.
If you have any trouble with this, say so. I may be able to find my notes or make a Windows Service app myself, just to see if the steps on MSDN still work.

Categories