PHP class to C# class? - c#

I work for a company that makes application's in C#.
recently we got a customer asking us to look in to rebuilding an application written in PHP.
This application receives GPS data from car mounted boxes and processes that into workable information.
The manufacturer for the GPS device has a PHP class that parses the received information and extracts coordinates. We were looking in to rewriting the PHP class to a C# class so we can use it and adapt it. And here it comes, on the manufacturers website there is a singel line of text that got my skin krawling:
"The encoding format and contents of the transmitted data are subject to constant changes.
This is caused by implementations of additional features by new module firmware versions which makes it virtually impossible to document it and for you to properly decode it yourself."
So i am now looking for a option to use the "constantly changing" PHP class and access it in C#. Some thing link a shell only exposing some function's i need. Except i have no idea how i can do this. Can any one help me find a solution for this.

I know it's a really hacky solution, but if you need a bit of PHP code that you don't want to have to repeatedly port to C# each time, you could try the following approach, although it means that you would need the php command line tool on the target machine.
First step is to have a php script that continously reads data off stdin, decodes it using this special class from the vendor, and writes the result out to stdout. Really simple example:
<?php
include("VendorDecodingClass.php");
while(true)
{
$input = fgets(STDIN); //read off of the stdin stream
//can't remember if this is valid, but somehow check that there is some data
if($input)
{
//pass it off to the vendor decoding class
$output = VendorDecoding::decode($input);
fwrite(STDOUT, $output); //write the results back out
}
//sleep here so you don't suck up CPU like crazy
//(1 second may be a bit long tho, may want usleep)
//Edit: From Tom Haigh, fgets will block, so the sleep isn't necessary
//sleep(1);
}
?>
Anyway, once you have that in place, in your C# application, right at the start, create a new Process to run that script and then save the Process instance somewhere, so you can reference the STDIN and STDOUT at a later point. Example:
ProcessStartInfo procStartInfo = new ProcessStartInfo("php", "yourscript.php");
procStartInfo.RedirectStandardOutput = true;
procStartInfo.UseShellExecute = false;
procStartInfo.CreateNoWindow = true;
Process proc = new Process(); //store this variable somewhere
proc.StartInfo = procStartInfo;
proc.Start();
Then, when you want to decode your data, you just write to the stdin of the php process you created, and wait for a response on the stdout. Using the stdin/stdout approach is a lot more efficient than creating a new process each time you want to decode some data, because the overhead of creating that process can be noticeable.
proc.StandardInput.WriteLine(somedata); //somedata is whatever you want to decode
//may need to wait here, or perhaps catch an exception on the next line?
String result = proc.StandardOutput.ReadLine();
//now result should contain the result of the decoding process
Disclaimer here, I haven't tested any of this code, but that is the general gist of how I might do it.
Something else I just thought of, you will want some mechanism for terminating that PHP process. It may be OK to use Process.Kill, but if the decoding does any file IO, or anything critical you may want to send an interrupt signal to the php script somehow.

I assume the php script is on your machine and returns usefull data. The first -not very elegant solution- that pops into my mind is the following:
Make sure your machine has the php commandline installed, so that you are able to run the php script from commandline. To execute a commandlinetool from C# see code for that here. The returned data now probably needs to get processed my your C# program.

I have never tried this and do not know anyone that has, but I remember comming across this sometime ago and thought I would throw it out there as a possible option for you.
Phalanger is a compiler project that compiles PHP code to IL, so you can use that then have a managed assembly that you reference from your code directly.

If the format is a regex you can try to put it in an application setting file (not resources, these are compiled WITH the application, you can't change them without recompiling the app).
Application settings are not changeable by the user but you can do that by editing the XML.
Or you can set the settings to user mode and then you can change the format from inside your application code.

Why don't you just launch the PHP script from C#, have it output its results to a file and then use that file as input for your C# program?

Personally, I would setup a PHP web service with a proper and stable API that the C# project can access, implement the manufacturers supplied PHP class in the web service and let it be.

Related

Executing Python Script in C# or Unity

I used Keras in Python to design a neural network calculating something like a noise-reducing-function. It works pretty good so far, and now I want to use this network to clean the data inside a Unity-Project of mine.
I would not have thought that this could be so difficult. I could only find one python interpreter in the asset store, which does not support external python librarys. IronPython is not an option either, because I need to include the Keras Packages.
I found a KerasSharp Project on GitHub, but there is no documentation on how to load an already trained network, and training it at the beginning is not an option. Furthermore it seems like there is no one working on the project anymore, due to the commit history and unanswered questions. Accessing the script via network APIs is probably not an good option either, due to the latency. I need the calculation for every frame.
So my question is: Is there any way I can load a Keras/Tensorflow model in C# or Unity
OR
Can I somehow access the python script which is calculating the noise-reducing-function using the Keras model?
If your situation allows for you to start the python script after Unity, you can try starting the python script as a subprocess as described here:
http://answers.unity.com/answers/14156/view.html
If you do not require the other process to be running before the Unity
one, you could have your Unity project launch that via Process and
then redirect stdin/out to streams and communicate through these.
Example:
Process otherProcess = new Process ();
otherProcess.StartInfo.FileName = path;
otherProcess.StartInfo.CreateNoWindow = true;
otherProcess.StartInfo.UseShellExecute = false;
otherProcess.StartInfo.RedirectStandardInput = true;
otherProcess.StartInfo.RedirectStandardOutput = true;
// Now communicate via streams
// otherProcess.StandardOutput
// and
// otherProcess.StandardInput
It is also possible that grabbing a running process by name or pid and
then setting the forwarding would work, but I've not tested this and
it does seem rather doubtful.
This setup would require that your python script be able to take in data from standard in, and output its results over standard out.

Can a text file be updated by two programs simultaneously (live communication)?

I have a program that has c/c# abilities, and I have python. I want that program to update a text file, almost in milliseconds, and have the python to read that text file in milliseconds as well. How can I go achieve this?
Is it possible for a text file to be updated live by another program and be read live by python? Is there any alternative way to do this instead of relying on text file.
Basically what I want to do is a bunch of computations on live data from that program using python and send back those computations to the program in form of commands.Can a file not be closed and reopened and yet updated in the memory?
If you start the C/C# process from python with subprocess.Popen then your two programs can communicate via the stdin and stdout pipes:
c_program = subprocess.Popen(["ARGS","HERE"],
stdin = subprocess.PIPE, # PIPE is actually just -1
stdout= subprocess.PIPE, # it indicates to create a new pipe
stderr= subprocess.PIPE #not necessary but useful
)
Then you can read the output of the process with:
data = c_program.stdout.read(n) #read n bytes
#or read until newine
line = c_program.stdout.readline()
Note that both of these are blocking methods, although non blocking alternatives exist.
Also note that in python 3 these will return bytes objects, you can convert into a str with the .decode() method.
Then to send input to the process you can simply write to the stdin:
c_program.stdin.write(DATA)
Like the read above, in python 3 this method expects a bytes object. You can use the str.encode method to encode it before writing it to the pipe.
I have extremely limited knowledge of C# but from limited research it seems that you can read data from System.Console.In and write data to System.Console.Out, although if you have written programs in C# that run in a terminal, the same methods used to write data to the screen and read input from the user will work here too. (you can imagine the .stdout as the terminal screen and data python writes to .stdin the user input)

iOS app that can retrieve database query output from web service?

I am not a developer, so explain it like I am five. Does not have to go into detail, just point me in a direction I will spend the next 2-4 weeks of free time (hopefully) trying to work through it.
Our retail system runs on a UniData database, commands include "listuser" "kill __" etc.
We have a web service that can be seen externally.
I want to make a rudimentary iOS app that can "listuser" and see output of connected users, read through the list, and type in a user name then send the "kill ___" command back through the web service to our server.
I created a batch file with the listuser command, then wrote some C# code that will pass output into XML document, I just want to be able to trigger this & load the XML from my iOS app.
public XmlDocument ListUnidataUser(string VisibleStores)
{
Process p = new Process();
// Redirect the output stream of the child process.
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = #"\\server\c$\ud\listuser.bat";
p.Start();
// Do not wait for the child process to exit before
// reading to the end of its redirected stream.
// p.WaitForExit();
// Read the output stream first and then wait.
string output = p.StandardOutput.ReadToEnd();
XmlDocument xml = new XmlDocument();
xml.LoadXml(output);
p.WaitForExit();
return xml;
}
After this, I have no idea what I am doing. This goes in our web service, which can see these local servers, then the web service holds that XML. How do I make a connection from an external app?
If it is easier to learn, I wouldn't mind trying first to make C# code that can be run externally to grab this, and using a service like Xamarin to compile it for iOS, but I am curious to feel my way around Xcode as well.
Please don't flame me, I can hear the jimmies rustling by my approach to coding this.
It's always good to learn something new, and I for one think that the iOS framework really has a good structure - so good luck.
As for your problem:
If possible for you, don't use XML as data protocol - mobile frameworks are much better at interpreting JSON, it's even integrated in the language itself (NSJSONSerializer for example) or you get good libraries for it.
For contacting your Webservice, have a look at NSURLSession or, if you prefer a library with some more functionality, AFNetworking (or AlamoFire if you're using Swift.
In general, look at some tutorials on the Ray Wenderlich website - they are great for learning about developing for iOS, eg the one on AlamoFire.

How to open / use a file descriptor

I have a particular problem, I have some program that I cannot modify but that provides some functionality I'd like to use inside office. So I am writing a plugin for Office that takes my document, executes the program on the background, puts the document on the stdin. The program writes to the stdout, and I take that back to my program to post process that.
This all works fine except that the program asks for a password which I don't want to put on stdin. The tool has a way to read the password from any other input stream but it needs the number of the file-descriptor it should read from.
So here is my question: how do I (within the .net environment) open a stream on a file descriptor with a number that I can give as parameter to this program? Ideally I want to write something like:
process.start("start-program --password-fd " + x);
stream = new StreamWriter(x);
stream.write("secritpwd");
ect.. (but then magically corrected so it will work ;) )
I hope someone can help me.
Thanks
I'm not sure exactly what this app means by "file descriptor", but you may be able to pass the handle of an inheritable anonymous pipe. See AnonymousPipeServerStream. (This assumes you're on at least .NET 3.5.)
The basic outline would be something like this:
Instantiate an AnonymousPipeServerStream.
Pass the pipe handle (pipeServer.GetClientHandleAsString()) as a command-line parameter to your C executable.
Write to the AnonymousPipeServerStream.
File descriptors aren't part of Windows - they're part of the C runtime library. You would have to write a DLL in C or C++ to do your file I/O, then call it from your C# program. Get the file descriptor number from the C DLL to pass to your other code.
Maby this links will help you to start and to get the logic from:
How to use OpenFileById to open a file
Opening pipe connection to a file descriptor in C#
OpenFileById Function

From C#, open an arbitrary application

Related question [stackoverflow] here.
I'm trying to do the above, but I want to take the process one step further. I want to open an arbitrary file using the default editor for the file type. From that point, I want to allow my user to interact with the file as they would normally, or continue to work in my application. The extension is what happens after the user finishes editing. Is there a way I can capture a close (and ideally save) event from the external application and use that as a trigger to do something else? For my purposes, tracking the closing of the external application would do.
I can do this in the specific case. For example, I can open a Word instance from my application and track the events that interest my application. However, I want to de-couple my application from Word.I want to allow my users to use any document editor of their choice, then manage the storage of the file being edited discretely behind the scenes.
You can do this in a manner similar to the referenced question, but the syntax is slightly different:
System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo =
new System.Diagnostics.ProcessStartInfo("C:\...\...\myfile.html");
process.Start();
process.WaitForExit(); // this line is the key difference
The WaitForExit() call will block until the other application is closed. You would use this code in a separate thread so that the user can keep using your application in the meantime.
Use the FileSystemWatcher class to watch for changes to the file.
EDIT: You can also handle the Exited event of the Process object to find out when the program is exited. However, note that that won't tell you of the user closes your file but doesn't exit the process. (Which is especially likely in Word).
To listen for file change, you can use the FileSystemWatcher and listen for a change in the last modified date.
You can also monitor the process and check then file when the process close.
I found this useful tip online just now. It seems to be what you are looking for. This article (link broken) has some more detail and useful, to-the-point tips on C# programming.
string filename = "instruction.txt";
System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo(#filename);
System.Diagnostics.Process rfp = new System.Diagnostics.Process();
rfp = System.Diagnostics.Process.Start(psi);
rfp.WaitForExit(2000);
if (rfp.HasExited)
{
System.IO.File.Delete(filename);
}
//execute other code after the program has closed
MessageBox.ShowDialog("The program is done.");

Categories