Coded UI Application Under Test - c#

Just started implementing a coded ui test automation solution but keep running into an issue when starting the application.
The application seems to start just fine but no matter what I always get an exception stating:
Microsoft.VisualStudio.TestTools.UITest.Extension.FailedToLaunchApplicationException: "The application cannot be started. This could be due to one of the following reasons:
1) Another instance of the application is already running and only one instance can be running at a time.
2) The application started another process and has now stopped. You may need to launch the process directly.
3) You do not have sufficient privileges for this application."
The application is a little strange as it currently is setup to run off of a setup.exe so the user always has the latest version.
Am I missing something in my code (sample below)? Or does the application need to be better set up before I start writing the automation tests. EXE is located in a network location.
ApplicationUnderTest aut = ApplicationUnderTest.Launch(#"\\test.com\\applicationdir\\testenv\\application\\setup.exe");
WpfEdit userName = new WpfEdit(aut);
userName.SearchProperties.Add(WpfEdit.PropertyNames.AutomationId, "PART_UserName");
userName.Text = "TEST";

Currently using a workaround where I start the app via Process and then pass it to the application under test FromProcess(). Seemed to fix the issue.
Probably not the best solution and have to use a Thread.Sleep() but it works for now.
Example:
var process = Process.Start(#"pathToApplication");
Thread.Sleep(2000);
process = Process.GetProcessesByName("process.Name")[0];
ApplicationUnderTest aut = ApplicationUnderTest.FromProcess(process);

Related

c# : Create windows scheduled task as a different user

I'm creating Windows Scheduled Tasks dynamically from c# using the build-in TaskService and TaskDefinition libraries.
But for some of them, we need to create then to run as a different user (Local Service or Network Service). As the tasks are created and removed dynamically we cannot edit all of them manually to change the user. We need to do it via code.
Is is possible?
I've tried the following settings:
TaskDefinition.Principal.Id = "NETWORK SERVICE";
TaskDefinition.Principal.LogonType = TaskLogonType.ServiceAccount;
but this gives me the very descript error when creating the task:
System.Runtime.InteropServices.COMException: '(52,4):Task:'
Without those 2 lines, it works but creates them as the logged in user.
I've played around with the Task Scheduler stuff a bit and have replicated your problem. I believe I’ve found some things out, maybe they can help.
1. Firstly if your making Tasks in the debugger using Services Accounts, you'll want to ensure your Visual Studio or other IDE is launched as administrator to ensure you have the correct privileges to do this task.
2. I'm not sure if you do this later in your code but to make the task save and run as NETWORK SERVICE, I had to Identify Network Service as NT AUTHORITY\\NETWORKSERVICE in both the principle and on the RegisterTaskDefinition method:
TaskService tService = new TaskService();
TaskDefinition tDefinition = tService.NewTask();
tDefinition.Principal.Id = "NT AUTHORITY\\NETWORKSERVICE";
tDefinition.Principal.LogonType = TaskLogonType.ServiceAccount;
tDefinition.RegistrationInfo.Description = "Testing";
tDefinition.Triggers.Add(new DailyTrigger {DaysInterval = 2});
tDefinition.Actions.Add(new ExecAction("notepad.exe"));
tService.RootFolder.RegisterTaskDefinition(#"Test", tDefinition, TaskCreation.CreateOrUpdate,
"NT AUTHORITY\\NETWORKSERVICE", null,
TaskLogonType.ServiceAccount);
I used the above code to make a test Task that got successfully added to my scheduler as Network Service as shown below:
I'm guessing that one or both of the above points may have stopped the task from being added, hope that helps

c# run application as another user fails with System.ComponentModel.Win32Exception

I work with emergency services and they have an application that uses map files to let them know where they need to go and it uses GPS to let them know where they are. We have to update the map files as things change and before I started here they were being done through VB scripts which started to fail. I decided to code my own app in C# to do this which works fine.
I created a package in SCCM 2012 that caches all of the files locally and then it compares the files in the cache to what is on the machine and then replaces any older files. This all works fine but the application they use called MobileCAD locks the files so I have to kill this process and then do the file copy and start the application again. We never know when an emergency happens so this update may start when they are on the road so it is important that it starts the application again as soon as possible. If it does not start the application then the emergency services people may try to do so manually but if core files are being updated then it may not start or cause issues.
I coded my application which uses an app manifest to force it to run as an administrator for the file copy. This application is run through SCCM which uses the local 'System' account to do all of the work and killing MobileCAD and copying files which works great. What I originally found was that it does start MobileCAD but it does so under the System account and the process would be there but it was not visible. I think this is the same problem they were originally having so the emergency services people would need to reboot the computer and wait for it to log back in and then start the wireless service so they could get back into MobileCAD.
To address this issue I did research and found that I could use the ProcessStartInfo in .NET and force it to use another account. As we use an automatic logon for these machines the users name, password, and domain are all in the registry so it was easy to pull it out and inject it into the code. Awesome, looks like it is easy enough so I code it up and sure enough it works perfectly when run under my admin account. In my basic testing everything worked perfectly until I try the same in SCCM, now it fails with the following error message.
System.ComponentModel.Win32Exception (0x80004005): Access is denied
at System.Diagnostics.Process.StartWithCreateProcess(ProcessStartInfo startInfo)
at System.Diagnostics.Process.Start()
at System.Diagnostics.Process.Start(ProcessStartInfo startInfo)
at UpdateFDM.Program.StartProcess(String processName)
I am sorry for all of the words but I believe it helps if you have a good understanding of the issue and what I am trying to do. I have also hard coded the user information into the code instead of pulling it from the registry but I get the same error. Again, this works fine under my admin account but fails when it is pushed through SCCM and it is only launching MobileCAD that fails.
This is the code I am using for launching MobleCAD, do you see where my issue may lie? I know SCCM confuses it but SCCM basically runs things just as you would from the command line but it uses the local System account.
Thanks for any help.
// Declares the new start instance
ProcessStartInfo process = new ProcessStartInfo();
// Gets the process to start
process.FileName = processName;
// Maximizes the process windows at start-up
process.WindowStyle = ProcessWindowStyle.Maximized;
// Gets the user name from the autologon information
process.UserName = GetDefaultUserInfo("DefaultUserName");
// Gets the domain for the user
process.Domain = GetDefaultUserInfo("DefaultDomainName");
// Holds the password for the default user
SecureString password = new SecureString();
// Gets the raw password from the registry
string rawPassword = GetDefaultUserInfo("DefaultPassword");
// Copies the password in a secure string
foreach (char ch in rawPassword)
{
password.AppendChar(ch);
}
// Sets the password
process.Password = password;
// Needed to launch the app as the logged on user
process.LoadUserProfile = true;
process.UseShellExecute = false;
// Starts the process
Process.Start(process);
// Process started, return true
return true;

Can I run another Command Prompt/GUI process in a Windows Service?

I am writing a windows service that occasionaly has to renew IP address of the system and It would call ipconfig /renew to do it.
The code is going to look like this
Process ipconfigProcess = new Process();
ipconfigProcess.StartInfo.FileName = "ipconfig";
ipconfigProcess.StartInfo.Arguments = " /renew";
ipconfigProcess.StartInfo.UseShellExecute = false;
ipconfigProcess.StartInfo.RedirectStandardOutput = true;
ipconfigProcess.Start();
strOutput = compiler.StandardOutput.ReadToEnd();
ipconfigProcess.WaitForExit();
I suppose a windows service is not allowed to show windows/dialogs. So my question is whether renewing ip as above would be a problem in windows service because it may or may not show a console to run ipconfig ?
I think the only issue you're going to face is that of permissions - you should have no problem running a process like this (as long as you don't want to interact with any kind of UI), but your windows service needs to run as an account that will be able to spawn a process and execute ipconfig.
This does not require an instance of cmd.exe. Many command line applications are used in this manner.
A service can use GUI functions and/or create a console. Windows creates a dummy display surface to draw on as necessary. (Obviously, this dummy surface can't interact with the user.)

Finding which service has run an executable in C#

I was wondering if it were possible to find out which windows service has run an executable?
I've got two different services running from the same exe, doing different things. The main method of the program detects a command line parameter and will either start the console app (if running in Environment.UserInteractive), or start one of the two possible services. I can't find a good way to discern which service is running so I can choose the correct service to start in the code. Passing in .exe parameters in the image path of the windows service doesn't seem to work. The services are running on a server and starting automatically, so doing it manually isn't really an option.
I'd really like to avoid having to have two different projects with different executables, so any way I can notify the program of which service to run would be great.
You can pass arguments in the ImagePath. I know I have done it at some point using a .net windows service, but as I recall, I had to install the service using something other than the standard .Net installer.
The .Net installer adds quotes around whatever you pass, which makes ImagePath go from C:\test\test.exe -arguments to "C:\test\test.exe -arguments" when it should be "C:\test\test.exe" -arguments.
Check out WiX, sc.exe or CreateService to get the correct registry value.
To test, install your service as usual and browse in regedit to HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\yourServiceName and edit ImagePath. For an example of how it should look, check out HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\seclogon.
You could create a Mutex in your service at the point it starts, using a name unique to the version it is running. If the mutex is obtained then you know it isn't running. If it can't be obtained then the service is already running.
You could then start your services through a new process that first tries to obtain the mutex for the first service and if it can't obtain it it starts the second.
So, you start ServiceRunner.exe -foo. A mutex called "foo" is obtained, so you release the Mutex and ServiceRunner.exe starts Service.exe -foo.
If the mutex is not obtained you then try to obtain a mutex called "bar" and follow the same process.
This is a nasty solution, and would require your to create a new exe that simply tries to start the services.
Have your service share its start state( temp file, registry key or other method, it could even write this as html to a web server... )
ServiceController yourService = new ServiceController( "YourServiceName" , "YourMachine" );
if( yourService.Status == ServiceControllerStatus.Stopped )
{
yourService.Start();
}

The applications started by console application fail to display on desktop

I have a windows service called MainService, which is used to monitor SubServices. The SubServices are actually some console applications and started by the MainService via Process.Start() method. Example code:
var subServiceProcess = Process.Start(subService.ServicePath);
The SubServices work perfectly until one of them needs to start another desktop application like the MainService does. Example code:
var desktopApplicationProcess = Process.Start(desktopApplicationPath);
The desktopApplicationProcess is created and we can see it in the taskmanager. However, its GUI doesn't show.
I've tried to run the sub service manually, and then the desktop runs correctly. So, I guess this is caused by that the sub service is started by the MainService.
Can anybody give me some sugguestion?
Thanks a lot~
Have you allowed the Service to interact with the desktop?

Categories

Resources