Download page with Knockout bindings via PhantomJs - c#

I want to parse a page on Microsoft Virtual Academy with PhantomJs. For instance this one. I am able to load it (see result) but in the downloaded source code I don't see the description of the course or its duration.
To download a page I've used next approach: https://gist.github.com/DotNetNerd/5635371.
public string Grab(string url)
{
var process = new System.Diagnostics.Process();
var startInfo = new System.Diagnostics.ProcessStartInfo
{
WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden,
UseShellExecute = false,
RedirectStandardOutput = true,
FileName = Config.PhantomJSPath,
Arguments = string.Format("\"{0}\\{1}\" {2}", Directory.GetParent(Directory.GetCurrentDirectory()).Parent.FullName, "index.js", url)
};
process.StartInfo = startInfo;
process.Start();
string output = process.StandardOutput.ReadToEnd();
process.WaitForExit();
return output;
}
and IndexJs
var page = require('webpage').create(),
system = require('system');
page.onLoadFinished = function() {
console.log(page.content);
phantom.exit();
};
page.open(system.args[1]);
Should I configure phantomjs to wait until binding will take effect or PhantomJs simply doesn't support it?

Finally, I decided to wait for 5s after the page was loaded. It doesn't guarantee that everything will load by this time but worked for me.
Index.js was updated to:
var page = require('webpage').create(),
system = require('system');
page.onLoadFinished = function() {
setTimeout(function () {
console.log(page.content);
phantom.exit();
}, 5000);
};
page.open(system.args[1]);

Related

How to execute cmds using HTTP Post method in C#

We have a REST endpoint installed as a windows service on a server. This server will be used for test automation. The idea is make a POST request to the endpoint and that endpoint will kick off cypress tests based off the parameters specified in the POST url.
I have an existing powershell script that will do this. Ideally I'd like to call that script and fill in the needed params.
No matter what I do the request returns OK without actually running any of the commands. Is there a way to use a POST request to execute a cmds or a powershell script?? Code below(Note: I'm trying 2 different methods here neither work):
namespace CNet.TestRunner
{
public class AddTestRun : CNetApiEndpoint
{
[HttpPost("Cypress/{testName}/{serverName}")]
public CineNetResult TestRun(string testName, string serverName)
{
string test = testName + ".js";
string testPath = $#"..\EndToEndSpecs\cypress\integration\{test}";
var path = "%PROGRAMFILES%";
var resolvedPath = Environment.ExpandEnvironmentVariables(path);
string cmd = $#"{resolvedPath}\PowerShell\7\pwsh.exe "" '..\EndToEnd.ps1' '-TestPath {testPath}' '-HostToTest {serverName}' """;
Process P = Process.Start($#"{resolvedPath}\PowerShell\7\pwsh.exe", $#""" '..\EndToEnd.ps1' '-TestPath {testPath}' '-HostToTest {serverName}'""");
P.WaitForExit();
int result = P.ExitCode;
string resStr = result.ToString();
var model = new ResponseModel
{
Message = resStr,
DataPassed = $"{testName}|{serverName}"
};
var proc1 = new ProcessStartInfo();
string anyCommand = "yarn install";
proc1.UseShellExecute = true;
proc1.WorkingDirectory = #"C:\Windows\System32";
proc1.FileName = #"C:\Windows\System32\cmd.exe";
proc1.Verb = "runas";
proc1.Arguments = "/c " + anyCommand;
proc1.WindowStyle = ProcessWindowStyle.Hidden;
Process.Start(proc1);
return Ok(model);
}
}
}

How do I return a Python script result from C# without printing?

This sort of question has been asked before in varying degrees, but I feel it has not been answered in a concise way and so I ask it again.
I want to run a script in Python. Let's say it's this:
def func1():
list = [1,2,3,4,5]
return list
Which gets the empty result.when putting print statement its return value to c#.but I want a result without printing in python. My actual code result is very big.so it takes time.
Okay, so how do I run this in C#?
This is what I have now:
var process = new Process () {
StartInfo = new ProcessStartInfo {
FileName = "python",
Arguments = "-u /home/varun/Desktop/data.py",
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true,
}
};
process.Start ();
string output = process.StandardOutput.ReadToEnd ();
string error = process.StandardError.ReadToEnd ();
process.WaitForExit ();
if (string.IsNullOrEmpty (error)) { return output; } else {
Console.WriteLine (error);
return error;
}

Running a PythonScript as a process and reading Standard Output issue

I am trying to run a python script as a process to which I pass a couple of parameters and then read standard output. I have a little console app and a dummy script that works fine, but when I do the same thing in my WebApi project, Standard Output is always blank, and I cannot figure out why. My code follows:
Console App
class Program
{
private static string Foo(string inputString)
{
string result = String.Empty;
ProcessStartInfo start = new ProcessStartInfo();
start.FileName = "python";
start.Arguments = string.Format(" {0} {1} {2}", #"*path*\runner.py", #"*path*\test2.py", inputString);
start.UseShellExecute = false;
start.RedirectStandardOutput = true;
using (Process process = Process.Start(start))
{
using (StreamReader reader = process.StandardOutput)
{
result = reader.ReadToEnd();
}
}
return result;
}
static void Main(string[] args)
{
var result = Foo("flibble");
Console.Write(result);
Console.ReadKey();
}
}
runner.py (for the console app)
import sys, imp
test = imp.load_source('test',sys.argv[1])
result = test.hello(sys.argv[2])
test2.py (from the console app)
import sys
def hello(inputString):
sys.stdout.write(inputString)
return
That is the end of what I have that works, now onto the code where the issue is:
ApiEndpoint
[HttpPost]
public IHttpActionResult TestEndpoint()
{
string postedJson = ReadRawBuffer().Result;
if (postedJson == null) throw new ArgumentException("Request is null");
var result = _pythonOperations.Foo(postedJson);
// Deal with result
return Ok();
}
_pythonOperations.Foo()
public string Foo(string inputString)
{
string result;
var start = new ProcessStartInfo
{
FileName = _pathToPythonExecutable,
Arguments = string.Format(" {0} {1} {2}", _pathToPythonRunnerScript, _pathToPythonFooScript, inputString),
UseShellExecute = false,
RedirectStandardOutput = true
};
using (Process process = Process.Start(start))
{
using (StreamReader reader = process.StandardOutput)
{
result = reader.ReadToEnd();
}
}
return result;
}
pythonRunnerScript
import sys, imp
module = imp.load_source('foo', sys.argv[1])
module.Foo(sys.argv[2])
Foo script
import sys
def Foo(inputString)
outputString = "output"
sys.stdout.write(outputString)
return
This is quite possibly one of the longest posts I have made, so thanks for taking the time to read it, and hopefully I can get a solution to this.
Cheers
Turns out the format I was passing in was wrong. I was using Postman REST Api client, and pasting the huge amounts of data into their request content window truncated it, leaving me with half a line. Once this was sorted, everything ran through ok.

I am having trouble comparing two lists. The purpose of the program is to perform offline patch installation

The problem comes in the looping. It seems to perform the comparison between the wmi qfe list and the KB list. The issue I run into is taking and searching the contents of the .msu file name list for the KB and then installing it. I have made a similar program in python and was mimicking a similar construct in the C# code. Any guidance on how to make this function properly would be greatly appreciated. The code is as follows:
static void Server08r2Patches()
{
var IE9 = from a in IAVA.Worksheet<IE9>("IE9") select a;
var Server08r2 = from a in IAVA.Worksheet<Server08r2>("Server08r2") select a;
var KBlist = Server08r2.Select(s=>new {KB = s.KB}).ToList();
var ExeList = Server08r2.Select(s=>new {Executable = s.Executable}).ToList();
string path = (Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)+#"\x64\");
foreach (var item in KBlist)
{
if (OsPatches.Contains(item.KB))
{
Console.WriteLine(item.KB+" is already installed.");
}
else
{
Console.WriteLine(item.KB+" will now be installed.");
foreach (var inst in ExeList)
{
do
{
var kb_inst = new ProcessStartInfo()
{
CreateNoWindow = true,
UseShellExecute = true,
FileName =path+inst.Executable,
WindowStyle = ProcessWindowStyle.Hidden,
Arguments = (#" /quiet /norestart"),
};
try
{
Process update = new Process();
update.StartInfo = kb_inst;
update.Start();
update.WaitForExit();
Console.WriteLine(inst.Executable+" was successfully installed");
}
catch (Exception Ex)
{
Console.WriteLine(Ex.Message+" "+inst.Executable);
}
}
while (inst.Executable.Contains(item.KB) == true);
}
}
}
}

mass .net update in iis6

We have about 200 web sites (on 3 separate servers, so 600 total) that we're going to have to update to run on .net 4 framework. They're currently set to run on .net 2. Does anyone know if there's a way to do this with a c# console program? Thanks!
Edit: I found a tool called IIS Metabase Explorer. Using that along with some code I had found a while ago for setting up a site in IIS 6, I came up with the following code. Hopefully it will be of help to others.
I would call it like
UpdateSiteToDotNet4("mytestsite", "mywebserver", #"D:\inetpub\wwwroot\", "DotNet4");
private void UpdateSiteToDotNet4(string siteName, string server, string serverPath, string newAppPoolId)
{
var service = new DirectoryEntry("IIS://" + server + "/W3SVC");
DirectoryEntries sites = service.Children;
bool found = false;
foreach (DirectoryEntry siteEntry in sites)
{
var siteId = siteEntry.Name;
DirectoryEntries siteSettings = siteEntry.Children; //Root
foreach (DirectoryEntry siteSetting in
from DirectoryEntry siteSetting in siteSettings
where siteSetting.SchemaClassName == "IIsWebVirtualDir"
let siteRoot = siteSetting.Properties["Path"][0].ToString()
where siteRoot.ToLower().Trim() == (serverPath + siteName).ToLower().Trim()
select siteSetting)
{
siteSetting.Properties["AppPoolId"].Value = newAppPoolId;
siteSetting.CommitChanges();
//Update to version v4.0.30319
var aspnet = string.Format(#"{0}\Microsoft.NET\Framework\v{1}\aspnet_regiis.exe", Environment.GetEnvironmentVariable("windir"), "4.0.30319");
var startInfo = new ProcessStartInfo(aspnet)
{
Arguments = string.Format("-sn \"{0}\"", "W3SVC/" + siteId + "/Root"),
WindowStyle = ProcessWindowStyle.Hidden,
UseShellExecute = false,
CreateNoWindow = true
};
var process = new Process { StartInfo = startInfo };
process.Start();
process.WaitForExit();
process.Dispose();
found = true;
break;
}
if (found) break;
}
}

Categories