I'm develop a simple Console Application c# (GT-AutoPatcher.exe) with MSVSC2022 .NET5 capable of update some files in windows systems, include itselfs. The problem is, when i try to update the "updater" (the created app called GT-AutoPatcher.exe) i get stucked because i dont know the correct way to update a running program...
I'm trying this
using (WebClient web1 = new WebClient()) {
web1.Headers.Add("user-agent", "Other");
web1.DownloadFile("http://*/","GT-AutoPatcher.exe");
}
But result is:
Unhandled exception. System.Net.WebException: An exception occurred during a WebClient request.
---> System.IO.IOException: The process cannot access the file 'C:\*\bin\Debug\net5.0\GT-AutoPatcher.exe' because it is being used by another process.
Reasons:
The console application is running. How can i close it to donwload a new version?
If you want to close the program, you can refer to this code:
public static class Program1
{
static void Main(string[] args)
{
CloseApp("your file type");//Change this to what you want to turn off
}
private static void CloseApp(string ArrayProcessName)
{
string[] processName = ArrayProcessName.Split(',');
foreach (string appName in processName)
{
Process[] localByNameApp = Process.GetProcessesByName(appName);//Get all processes with program name
if (localByNameApp.Length > 0)
{
foreach (var app in localByNameApp)
{
if (!app.HasExited && app.MainWindowTitle == "your file name")
{
app.Kill();//close the process
}
}
}
}
}
}
I am creating an ASP.Net MVC application and I have created a new console application just so that I can pass it a few parameters and use the DataContext in the MVC application so that I dont have to continually repeat myself.
This is the code that I am using
using mySite.WebSite.DataModel;
namespace mySite.AvailabilityManager
{
class Program
{
public static List<DateTime>Availability = new List<DateTime>();
static void Main(string[] args)
{
var startingDt = Convert.ToDateTime("04-09-2015 08:00:00");
var endingDt = Convert.ToDateTime("04-09-2015 17:00:00");
CreateAvailabilty(startingDt, endingDt);
AddAvailabilityToDatabase();
}
public static void CreateAvailabilty(DateTime startingDt, DateTime endingDt)
{
var hoursDiff = endingDt.Subtract(startingDt);
for (int i = 0; i < hoursDiff.Hours; i++)
{
Availability.Add(startingDt);
startingDt = startingDt.AddHours(1);
}
}
public static void AddAvailabilityToDatabase()
{
using (var db = new FitnessForAllContext())
{
foreach (var availableDate in Availability.Select(date => new AvailableDate {DateAvailable = date}))
{
db.AvailableDates.Add(availableDate);
db.SaveChanges();
}
}
}
}
When I get to db.AvailableDates.Add(..) I get this error
No connection string named 'MyDBContext' could be found in the application config file.
I was under the impression that because I am using the reference from my MVC application and the connection string is in the ASP.Net MVC config file that I would not have to repeat the connection string in my app.config file for the console application.
So, to summaries,
I have the MVC Project refernece in my console application
This fails because of the lack of a connection string at db.AvailableDates.Add(availableDate);
The mySite.Website assembly is being pulled through into my bin debug folder
If you could offer some insight as to what I need to do without having to continually repeat myself by adding the connection string everywhere I intend on using this, unless I REALLY have to repeat myself
Standard, the connection string needs to be in de config file of the startup project. In this case of the console application. The config of the referenced project is ignored.
You can have a constant or an embedded resource or anything IN your EntityFramework project that contains connection string. But I think, it's not a good practice, every executing project should have it's own configuration.
I am unable to find a single post where i can automate mobile testing with appium in C#.
I have written my Website automation code in the specflow. Can I also Reuse it ?
Appium provides the dotnet-appium-driver which is your API to interface with Appium. You can use that to write your app automation.
You did not provide any example here nor code, so I cannot really act on something to show you. I will just write down some C# code to let you understand how a simple test in C# can be written:
namespace AppiumTests
{
using System;
// .NET unit test namespaces needed here as well, just not mentioning them
using OpenQA.Selenium; /* Appium is based on Selenium, we need to include it */
using OpenQA.Selenium.Appium; /* This is Appium */
[TestClass]
public class TestSuite
{
private AppiumDriver driver;
private static Uri testServerAddress = new Uri("http:127.0.01:4723/wd/hub"); // If Appium is running locally
private static TimeSpan INIT_TIMEOUT_SEC = TimeSpan.FromSeconds(180); /* Change this to a more reasonable value */
private static TimeSpan IMPLICIT_TIMEOUT_SEC = TimeSpan.FromSeconds(10); /* Change this to a more reasonable value */
[TestInitialize]
public void BeforeAll()
{
DesiredCapabilities testCapabilities = new DesiredCapabilities();
testCapabilities.App = "<your-app-file>";
testCapabilities.AutoWebView = true;
testCapabilities.AutomationName = "";
testCapabilities.BrowserName = String.Empty; // Leave empty otherwise you test on browsers
testCapabilities.DeviceName = "Needed if testing on IOS on a specific device. This will be the UDID";
testCapabilities.FwkVersion = "1.0"; // Not really needed
testCapabilities.Platform = TestCapabilities.DevicePlatform.Android; // Or IOS
testCapabilities.PlatformVersion = String.Empty; // Not really needed
driver = new AppiumDriver(testServerAddress, capabilities, INIT_TIMEOUT_SEC);
driver.Manage().Timeouts().ImplicitlyWait(IMPLICIT_TIMEOUT_SEC);
}
[TestCleanup]
public void AfterAll()
{
driver.Quit(); // Always quit, if you don't, next test session will fail
}
///
/// Just a simple test to heck out Appium environment.
///
[TestMethod]
public void CheckTestEnvironment()
{
var context = driver.GetContext();
Assert.IsNotNull(context);
}
}
}
You can find more in this article I wrote.
Finally reached to the solution run a test in C#. Many Thanks to Andry.
This solution runs the website in the chrome browser of your phone connected to the computer :
Steps and short program to setup and run a C# program on an android device using Appium:
namespace poc
{
using NUnit.Framework;
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Appium;
using OpenQA.Selenium.Appium.Interfaces;
using OpenQA.Selenium.Appium.MultiTouch;
using OpenQA.Selenium.Interactions;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Appium.Android;
[TestFixture()]
public class TestAppium
{
public IWebDriver driver;
[TestFixtureSetUp]
public void SetUp()
{
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.SetCapability("device", "Android");
capabilities.SetCapability("browserName", "chrome");
capabilities.SetCapability("deviceName", "Motorola Moto g");
capabilities.SetCapability("platformName", "Android");
capabilities.SetCapability("platformVersion", "5.0.2");
driver = new RemoteWebDriver(new Uri("http://127.0.0.1:4723/wd/hub"), capabilities, TimeSpan.FromSeconds(180));
}
[Test()]
public void OpenHofHomePage()
{
driver.Navigate().GoToUrl("http://YourWebsiteToTest.com");
Assert.IsTrue(driver.Title.Equals("Your Website")," Sorry , the website didnt open!!");
}
[TestFixtureTearDown]
public void End()
{
driver.Dispose();
}
}
}
1) Set up usual project in C# , install Appium , Selenium using NuGet package manager , Also install Nunit with the same process.
2) Download Android SDK
3) Envrionment variables : Add variable name "ANDROID_HOME" and in variable give path to sdk folder , In PATH (found in System variable) , append path to tools in sdk folder and append path to platform tools.
4) Connect your device (a.mobile device's drivers should be installed in the computer (my case moto g adb drivers installed) b. device should have developer mode option ON and debugger option checked and always awake option checked)
5) Now download Appium and open the Appium.exe.
6) Appium window -> In Android setting (first button) , check on "Use Browser" option and select "Browser" as an option.
7) Start the appium node server (play button at the top).
8) now run the test from the visual studio and you will see website opening in the browser of phone.
To make this more comprehensive, I have written a blog post which explains all the steps clearly with images. Its a step by step tutorial to use appium with c# and MSTest
You can read it here.
http://www.binaryclips.com/2016/03/test-automation-on-android-using-appium.html
This is how I have implemented Appium. I think it adds some depth to the discussion.
Appium is both a WebDriver that can interact with a device in your project as well as a Server that bridges your project to your physical device or emulator.
You have to run the Appium server as a listener and set up your Capabilities to connect to it. That will start the app and execute your test.
There is a lot more to it than this but here is a setup that you can try to get you on your way:
In a WebDriver Support Class use the [BeforeScenario] tag to execute this code before your test. This has a Sauce Labs implementation.
[BeforeScenario]
public void BeforeScenario()
{
var name = Locale == "sauce" ? "AppiumSauceDriver" : "AppiumDriver";
InitializeServiceLocator();
if (WebDriver == null)
{
InitializeWebDriver(name);
}
ObjectContainer.RegisterInstanceAs(WebDriver);
if (WebDriver != null)
{
Console.WriteLine("Driver Already Exists");
}
}
Then you need to populate the InitializeServiceLocator() method. There is a Device Selector Method here that doesn't do anything other than set the name. You can just hard code it to your capabilities instead.
private static void InitializeServiceLocator()
{
if (ServiceLocator == null)
{
var ip = "";
var deviceType = TestSetupHelper.DeviceSelector["iphone7"];
var capabilities = TestSetupHelper.SetAppiumCababilities(deviceType, Locale);
string server = MSTestContextSupport.GetRunParameter("appiumServer");
var port = Convert.ToInt32(MSTestContextSupport.GetRunParameter("appiumPort"));
if (Locale != "sauce")
{
ip = TestSetupHelper.GetComputerIpAddress(server, port, true);
}
var kernel = new StandardKernel();
kernel.Bind<IOSDriver<AppiumWebElement>>().ToConstructor(x => new IOSDriver<AppiumWebElement>(new Uri("http://" + ip + ":" + port + "/wd/hub"), capabilities, TimeSpan.FromMinutes(10))).Named("AppiumDriver");
kernel.Bind<IOSDriver<AppiumWebElement>>().ToConstructor(x => new IOSDriver<AppiumWebElement>(new Uri("http://ondemand.saucelabs.com:80/wd/hub"), capabilities, TimeSpan.FromMinutes(10))).Named("AppiumSauceDriver");
ServiceLocator = new NinjectServiceLocator(kernel);
Microsoft.Practices.ServiceLocation.ServiceLocator.SetLocatorProvider(() => ServiceLocator);
}
}
From here you need to set up your capabilities. The below method is how I have done it.
public static DesiredCapabilities SetAppiumCababilities(string deviceType, string locale, bool realDevice = false, string udid = "FAKEUDIDFOREXAMPLE")
{
string appiumAppFilePath = MSTestContextSupport.GetRunParameter("appiumAppFilePath");
//Universal Capabilities
capabilities.SetCapability("platformName", "iOS");
capabilities.SetCapability("deviceName", deviceType);
capabilities.SetCapability("automationName", "XCUITest");
capabilities.SetCapability("app", appiumAppFilePath);
capabilities.SetCapability("xcodeOrgId", "GET_THIS_FROM_APP_DEV");
capabilities.SetCapability("xcodeSigningId", "iPhone Developer");
capabilities.SetCapability("noReset", true);
capabilities.SetCapability("newCommandTimeout", 80);
if (locale == "sauce")//Sauce specific capabilities
{
capabilities.SetCapability("appiumVersion", "1.7.2");
capabilities.SetCapability("name", MSTestContextSupport.GetRunParameter("appiumJobName"));
capabilities.SetCapability("username", MSTestContextSupport.GetRunParameter("sauceId"));
capabilities.SetCapability("accessKey", MSTestContextSupport.GetRunParameter("sauceKey"));
capabilities.SetCapability("tunnel-identifier", MSTestContextSupport.GetRunParameter("sauceTunnel"));
capabilities.SetCapability("browserName", "");
capabilities.SetCapability("platformVersion", "11.2");
}
else//Local specific capabilities
{
capabilities.SetCapability("platformVersion", "11.3");
}
if (realDevice)//Sauce real device testing will not need this. This is for Local Real Device testing only
{
capabilities.SetCapability("udid", udid);
}
return capabilities;
}
Anything referencing GetRunParameter is getting a value from a .runsettings file.
Example:
<TestRunParameters>
<Parameter name="appiumJobName" value="OBI App Automated Test"/>
</TestRunParameters>
You have to add all of the stuff to the .runsettings file you are using to run the project that you want to source from there. You can hardcode it if you don't want to go through the runsettings file but I prefer to do it that way. You can make things variable that way based on the runsettings file you have selected.
Then you have to define TestSetupHelper.GetComputerIpAddress(server, port, true); If you have a hard coded IP Address to the computer that is running your Appium server you can just hard code that. Otherwise you need a Helper class somewhere (In this example it is TestSetupHelper). This example initiates a Socket Connection to the server and returns all of the details. That way you don't have to worry about IP addresses changing. You just pass the host name and the port you have Appium configured to run on and you can get the connection information from that connection and make your actual connection to the Appium Server instance.
public static string GetComputerIpAddress(string computerName, int port, bool remote)
{
var ip = "";
using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, 0))
{
socket.Connect(computerName, port);
//If remote it gets the connection destination IP, else it gets the connection initiator IP
IPEndPoint endPoint = remote ? socket.RemoteEndPoint as IPEndPoint : socket.LocalEndPoint as IPEndPoint;
ip = endPoint.Address.ToString();
}
return ip;
}
This isn't going to get you completely there but it will get you close to a working environment. Then you can start working on getting a test to actually run.
I hope this helps.
My app uses Nancy Selfhosting. When I launch it without admin rights I get a System.Net.HttpListenerException "Access Denied".
Here is the code:
static void Main(string[] args)
{
var nancyHost = new Nancy.Hosting.Self.NancyHost(new Uri("http://localhost:80/"));
nancyHost.Start();
Application.Run();
}
I have also tried different ports without success. Strangely, I dont get any Exceptions when launching a HttpListener that listens to the same Url. What could be causing this exception?
You need to set the self-host configuration to not rewrite the localhost route via the RewriteLocalhost property.
namespace NancyApplication1
{
using System;
using Nancy.Hosting.Self;
class Program
{
static void Main(string[] args)
{
var uri = new Uri("http://localhost:3579");
var config = new HostConfiguration();
// (Change the default RewriteLocalhost value)
config.RewriteLocalhost = false;
using (var host = new NancyHost(config, uri))
{
host.Start();
Console.WriteLine("Your application is running on " + uri);
Console.WriteLine("Press any [Enter] to close the host.");
Console.ReadLine();
}
}
}
}
I found this out by trying and failing a bit, but this page explains the reason behind.
Alternatively - From the documentation:
Note that on Windows hosts a HttpListenerException may be thrown with an Access Denied message. To resolve this the URL has to be added to the ACL.
Also but the port may need to be opened on the machine or corporate firewall to allow access to the service.
Add to ACL by running the following command:
netsh http add urlacl url=http://+:8080/ user=DOMAIN\username
if you need to remove from ACL:
netsh http delete urlacl url=http://+:8080/
You can hosting Nancy with Kestrel. It's really simple:
public void Main(string[] args)
{
var owinHost = new WebHostBuilder()
.UseStartup<Startup>()
.UseUrls("http://+:12345/")
.Build();
owinHost.Run();
}
public class Startup
{
public void Configure(IApplicationBuilder app)
{
app.UseOwin(x => x.UseNancy());
}
}
The only difficulty is to prepare all the dlls (30+) required. We should definitely use NuGet to resolve all the dependencies.
I want to mount vhd from my private container. After google I get that it is only possible through .net. I am more of a JAVA person. I need a batch script or code in c# (So that I can get an exe file) which can automatically run at startup and mount vhd. So I decided to create a console app in order to get exe file.(I have very less knowledge c#/Visual studio) I am using following C# console application to do this.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Threading;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.Diagnostics;
using Microsoft.WindowsAzure.ServiceRuntime;
using Microsoft.WindowsAzure.StorageClient;
using Microsoft.WindowsAzure.Internal;
namespace WorkerRole1
{
public class WorkerRole : RoleEntryPoint
{
public override void Run()
{
// This is a sample worker implementation. Replace with your logic.
Trace.WriteLine("WorkerRole1 entry point called", "Starting");
MountDrive();
//while (true)
//{
// Thread.Sleep(10000);
// Trace.WriteLine("Working", "Information");
//}
}
public override bool OnStart()
{
// Set the maximum number of concurrent connections
ServicePointManager.DefaultConnectionLimit = 12;
// For information on handling configuration changes
// see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.
return base.OnStart();
}
public void MountDrive()
{
string connectionStringSettingName = "DefaultEndpointsProtocol=http;AccountName=abc;AccountKey=xyz";
string azureContainerName = "vhds";
string vhdName = "myvhd.vhd";
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionStringSettingName);
//CloudStorageAccount storageAccount = CloudStorageAccount.DevelopmentStorageAccount;
LocalResource localCache = RoleEnvironment.GetLocalResource("MyAzureDriveCache");
CloudDrive.InitializeCache(localCache.RootPath, localCache.MaximumSizeInMegabytes);
Trace.WriteLine("RootPath =====" + localCache.RootPath);
Trace.WriteLine("MaximumSizeInMegabytes =====" + localCache.MaximumSizeInMegabytes);
// Just checking: make sure the container exists
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
blobClient.GetContainerReference(azureContainerName).CreateIfNotExist();
// Create cloud drive
CloudDrive myCloudDrive = storageAccount.CreateCloudDrive(
blobClient
.GetContainerReference(azureContainerName)
.GetPageBlobReference(vhdName)
.Uri.ToString()
);
Trace.WriteLine("Uri =====" + blobClient
.GetContainerReference(azureContainerName)
.GetPageBlobReference(vhdName)
.Uri.ToString());
try
{
myCloudDrive.Create(1024);
}
catch (CloudDriveException ex)
{
// handle exception here
// exception is also thrown if all is well but the drive already exists
}
string driveLetter = myCloudDrive.Mount(50, DriveMountOptions.Force);//Here It throws a Exception
Trace.WriteLine("Drive =====" + driveLetter);
for (int i = 0; i < 10; i++)
{
System.IO.File.WriteAllText(driveLetter + "\\" + i.ToString() + ".txt", "Test");
}
}
}
}
But I keep getting exception ERROR_DEVFABRIC_LOCAL_MOUNT_ONLY at
string driveLetter = myCloudDrive.Mount(50, DriveMountOptions.Force);
Please tell me where am I going wrong?
When RoleEnvironment.IsAvailable is set to false, this means you are not running in a Windows Azure Web/Worker/VM Role. The Windows Azure Drive only works when mounted in these roles (since it depends on RoleEnvironment).
More information can be found in the whitepaper.
ERROR_DEVFABRIC_LOCAL_MOUNT_ONLY means that when you are running locally you must mount the drive form development storage.
change the following line:
string connectionStringSettingName = "UseDevelopmentStorage=true";
or even better use RoleEnvironment.GetConfigurationSettingValue, like:
string connectionStringSettingName = RoleEnvironment.GetConfigurationSettingValue("DriveConnectionString");
and set the Setting in the service configuration (files)