How to load an extension in Edge using Selenium? - c#

I want to load an extension in Edge while using Selenium in C#.
I have figured I have to use EdgeOptions.AddExtensionPath() but when passing the path no extensions are loaded.
The extension was extracted from %localappdata%\Microsoft\Edge\User Data\Default\Extensions
Here is the part of the code used to initialize the EdgeDriver:
using OpenQA.Selenium.Edge;
public void InitializeNewDriver() {
string microsoftWebDriverPath = #"some\path";
EdgeDriverService service = EdgeDriverService.CreateDefaultService(microsoftWebDriverPath);
EdgeOptions options = new EdgeOptions();
options.AddExtensionPath(#"path\to\extension\folder");
Driver = new EdgeDriver(service, options);
}
Edit: I'm using Selenium.Webdriver v4.0.0

I try to test the issue and found that if you pass the location of the extension to the options.AddExtensionPath() then the extension is not getting a load.
I suggest trying to use the options.AddExtensions() method and pass the .CRX file of the extension as a parameter.
It can help you to load the extension successfully.
C# code example:
var options = new EdgeOptions();
options.UseChromium = true;
options.BinaryLocation = #"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe";
options.AddExtensions(#"Path_of_the_extension_here\extension.crx");
var driver = new Microsoft.Edge.SeleniumTools.EdgeDriver(#"Web_driver_path_here......", options);
driver.Navigate().GoToUrl("https://Your_URL_will_be_here...");
Output:
Further, you can modify the code sample as per your own requirements.

Related

C# and IronPython integration

I want simply use io.py from C# to write a file and I use the following code:
using Microsoft.Scripting.Hosting;
using IronPython.Hosting;
...
System.IO.Directory.SetCurrentDirectory(
Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) +
"\IronPython\Lib");
ScriptRuntime py = Python.CreateRuntime();
dynamic io = py.UseFile("io.py");
dynamic f = io.open("tmp.txt", "w");
f.writelines("some text...");
f.close();
but when I run the program the runtime give me a:
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException telling that no overload of writelines accept argument '1'
it seems like that method doesn't exists... but into io.py documentation it exists.
P.S. The same is for close method!!!
Any idea?
I can only tell you how to make your code working, however I don't have much experience with IronPython and have no idea why it is done this way (though I try to learn that). First, it seems io module is treated in a special way and there is special (non-dynamic) class for that. When you do io.open what is returned is instance of PythonIOModule._IOBase class. You can do
var f = (PythonIOModule._IOBase) io.open("tmp.txt", "w");
And see for yourself that "writeline" method (which is regular method, not a dynamic one) accepts CodeContext instance as first argument, and second argument is lines. Interesting that this class itself already contains field with that CodeContext, but it is made internal for some reason, and what is even worse - writelines (and other methods) could have been using that CodeContext and not require us to provide external one. Why is it done like this - I have no idea.
So to make your code working, we have to get CodeContext somewhere. One way is do that via reflection:
var context = (CodeContext) f.GetType().GetField("context", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(f);
Another way is to craft it yourself:
var languageContext = HostingHelpers.GetLanguageContext(engine);
var context = new ModuleContext(io._io, new PythonContext(languageContext.DomainManager, new Dictionary<string, object>())).GlobalContext;
Both methods will work and program will successfully write to a file. Full working sample:
static void Main(string[] args) {
System.IO.Directory.SetCurrentDirectory(#"G:\Python27\Lib");
var engine = Python.CreateEngine();
dynamic io = engine.ImportModule("io");
var f = (PythonIOModule._IOBase) io.open("tmp.txt", "w");
var languageContext = HostingHelpers.GetLanguageContext(engine);
var context = new ModuleContext(io._io, new PythonContext(languageContext.DomainManager, new Dictionary<string, object>())).GlobalContext;
f.writelines(context, "some text....");
f.close(context);
}

FindAndModify missing in mongodb C# driver

I am using Mongodb shell 3.2.4 and C# driver 2.2.3. I have even installed legacy driver 2.2.3 but still facing following problem.
I want to use AutoIncremented value for one of my field i.e eventID so I am trying to use FindAndModify but I cannot seem to find it.
_client = new MongoClient();
_database = _client.GetDatabase("users");
var counters = _database.GetCollection<BsonDocument>("counters");
var counterQuery = Query.EQ("_id", "eventId");
var findAndModifyResult = counters.FindAndModify(
new FindAndModifyArgs()
{
Query = counterQuery,
Update = Update.Set("web", "testweb")
});
But I get following error:
Error 2 'MongoDB.Driver.IMongoCollection<MongoDB.Bson.BsonDocument>' does not contain a definition for 'FindAndModify' and no extension method 'FindAndModify' accepting a first argument of type 'MongoDB.Driver.IMongoCollection<MongoDB.Bson.BsonDocument>' could be found (are you missing a using directive or an assembly reference?)
Attaching screenshot
In the new 2.0 driver, this is now called FindOneAndUpdate.
You have a mix of the old legacy, and new format in your question - Query.EQ is also from the legacy driver - so I suggest removing that legacy driver as the first step.
Then you should be able to get what you need by using the Builders, for example:
var _client = new MongoClient();
var _database = _client.GetDatabase("users");
var counters = _database.GetCollection<BsonDocument>("counters");
var counterQuery = Builders<BsonDocument>.Filter.Eq("_id", "eventId");
var findAndModifyResult = counters.FindOneAndUpdate(counterQuery,
Builders<BsonDocument>.Update.Set("web", "testweb"));

Convert to PDF method only works once

I'm using pechkin.synchronized to convert from HTML to PDF. On the first http request it works fine, but after that it gets stuck on the convert method and doesn't doesn't do anything after that.
Here's my controller action method:
public ActionResult ToPdf(int id)
{
var order = _orderBll.GetById(id);
var viewHtml = order.Body;
byte[] pdfBuf = new SimplePechkin(new GlobalConfig()).Convert(viewHtml);
return File(pdfBuf, "application/pdf");
}
Try using SynchronizedPechkin.
See:
Why my Web App hangs on the "easy to use" code example below?
Why my Web App hangs/crashes even after I've started using SynchronizedPechkin
Unfortunately, Pechkin is a dead project and has many unresolved issues. You can avoid these by using Tuespechkin's ThreadSafeConverter, Pechkin's development is continuing there.
Example:
IConverter converter =
new ThreadSafeConverter(
new PdfToolset(
new Win32EmbeddedDeployment(
new TempFolderDeployment())));
// Keep the converter somewhere static, or as a singleton instance!
// Do NOT run the above code more than once in the application lifecycle!
byte[] result = converter.convert(document);
I had the same problem with my application too. So i download Synchronized Pechkin from Nuget manager. Your code will look like:
using Pechkin;
using Pechkin.Synchronized;
public ActionResult ToPdf(int id)
{
var order = _orderBll.GetById(id);
var viewHtml = order.Body;
byte[] pdfBuf = new SynchronizedPechkin(new GlobalConfig()).Convert(viewHtml);
return File(pdfBuf, "application/pdf");
}

How to invoke a function written in a javascript file from C# using IronJS

I just download the Iron JS and after doing some 2/3 simple programs using the Execute method, I am looking into the ExecuteFile method.
I have a Test.js file whose content is as under
function Add(a,b)
{
var result = a+b;
return result;
}
I want to invoke the same from C# using Iron JS. How can I do so? My code so far
var o = new IronJS.Hosting.CSharp.Context();
dynamic loadFile = o.ExecuteFile(#"d:\test.js");
var result = loadFile.Add(10, 20);
But loadfile variable is null (path is correct)..
How to invoke JS function ,please help... Also searching in google yielded no help.
Thanks
The result of the execution is going to be null, because your script does not return anything.
However, you can access the "globals" object after the script has run to grab the function.
var o = new IronJS.Hosting.CSharp.Context();
o.ExecuteFile(#"d:\test.js");
dynamic globals = o.Globals;
var result = globals.Add(10, 20);
EDIT: That particular version will work with the current master branch, and in an up-coming release, but is not quite what we have working with the NuGet package. The slightly more verbose version that works with IronJS version 0.2.0.1 is:
var o = new IronJS.Hosting.CSharp.Context();
o.ExecuteFile(#"d:\test.js");
var add = o.Globals.GetT<FunctionObject>("Add");
var result = add.Call(o.Globals, 10D, 20D).Unbox<double>();

How to access WinRM in C#

I'd like to create a small application that can collect system information (Win32_blablabla) using WinRM as opposed to WMI. How can i do that from C#?
The main goal is to use WS-Man (WinRm) as opposed to DCOM (WMI).
I guess the easiest way would be to use WSMAN automation. Reference wsmauto.dll from windwos\system32 in your project:
then, code below should work for you. API description is here: msdn: WinRM C++ API
IWSMan wsman = new WSManClass();
IWSManConnectionOptions options = (IWSManConnectionOptions)wsman.CreateConnectionOptions();
if (options != null)
{
try
{
// options.UserName = ???;
// options.Password = ???;
IWSManSession session = (IWSManSession)wsman.CreateSession("http://<your_server_name>/wsman", 0, options);
if (session != null)
{
try
{
// retrieve the Win32_Service xml representation
var reply = session.Get("http://schemas.microsoft.com/wbem/wsman/1/wmi/root/cimv2/Win32_Service?Name=winmgmt", 0);
// parse xml and dump service name and description
var doc = new XmlDocument();
doc.LoadXml(reply);
foreach (var elementName in new string[] { "p:Caption", "p:Description" })
{
var node = doc.GetElementsByTagName(elementName)[0];
if (node != null) Console.WriteLine(node.InnerText);
}
}
finally
{
Marshal.ReleaseComObject(session);
}
}
}
finally
{
Marshal.ReleaseComObject(options);
}
}
hope this helps, regards
I've got an article that describes an easy way to run Powershell through WinRM from .NET at http://getthinktank.com/2015/06/22/naos-winrm-windows-remote-management-through-net/.
The code is in a single file if you want to just copy it and it's also a NuGet package that includes the reference to System.Management.Automation.
It auto manages trusted hosts, can run script blocks, and also send files (which isn't really supported but I created a work around). The returns are always the raw objects from Powershell.
// this is the entrypoint to interact with the system (interfaced for testing).
var machineManager = new MachineManager(
"10.0.0.1",
"Administrator",
MachineManager.ConvertStringToSecureString("xxx"),
true);
// will perform a user initiated reboot.
machineManager.Reboot();
// can run random script blocks WITH parameters.
var fileObjects = machineManager.RunScript(
"{ param($path) ls $path }",
new[] { #"C:\PathToList" });
// can transfer files to the remote server (over WinRM's protocol!).
var localFilePath = #"D:\Temp\BigFileLocal.nupkg";
var fileBytes = File.ReadAllBytes(localFilePath);
var remoteFilePath = #"D:\Temp\BigFileRemote.nupkg";
machineManager.SendFile(remoteFilePath, fileBytes);
Hope this helps, I've been using this for a while with my automated deployments. Please leave comments if you find issues.
I would like to note that this shows an interop error by default in Visual Studio 2010.
c.f. http://blogs.msdn.com/b/mshneer/archive/2009/12/07/interop-type-xxx-cannot-be-embedded-use-the-applicable-interface-instead.aspx
There appear to be two ways to solve this. This first is documented in the article listed above and appears to be the correct way to handle the problem. The pertinent changes for this example is:
WSMan wsManObject = new WSMan();
This is in lieu of IWSMan wsman = new WSManClass(); which will throw the error.
The second resolution is to go to the VS2010—>Solution Explorer—>Solution—>Project—>References and select WSManAutomation. Right click or hit Alt-Enter to access the properties. Change the value of the "Embed Interop Types" property of the wsmauto reference.

Categories