my application is in C# MVC with framework 4.5.2 and want to run external file(.m) and get output from that and it is written in Octave.
Note: Output result is in a string, so I have to show that output in C# html page.
Algorithm is written in octave and also in algorithm excel file is there to read data and external parameters are also passing through C#.
I tried the things which is already posted, the main concern is that my application is hosted in azure cloud. So, I can not install octave in cloud.
Can you suggest me any other way that directly run external file(.m) with dynamic excel file and parameters.
I can show my code what I have done. Its work in local with all but I can not install Octave in Azure cloud..
I put my installed folder to root path on server but its also not working.
public Octave(string pathToOctaveBinaries, bool createWindow)
{
StartOctave(pathToOctaveBinaries, createWindow);
}
private void StartOctave(string pathToOctaveBinaries, bool createWindow)
{
_ptob = pathToOctaveBinaries;
cw = createWindow;
this.OctaveEchoString = Guid.NewGuid().ToString();
OctaveProcess = new Process();
ProcessStartInfo pi = new ProcessStartInfo();
if (pathToOctaveBinaries[pathToOctaveBinaries.Length - 1] != '\\')
pathToOctaveBinaries = pathToOctaveBinaries + "\\";
pi.FileName = pathToOctaveBinaries + "octave-cli.exe";
pi.RedirectStandardInput = true;
pi.RedirectStandardOutput = true;
pi.RedirectStandardError = true;
pi.UseShellExecute = false;
pi.CreateNoWindow = !createWindow;
pi.Verb = "open";
//
pi.WorkingDirectory = ".";
OctaveProcess.StartInfo = pi;
OctaveProcess.Start();
OctaveProcess.OutputDataReceived += new DataReceivedEventHandler(OctaveProcess_OutputDataReceived);
OctaveProcess.BeginOutputReadLine();
OctaveEntryText = ExecuteCommand(null);
}
public string ExecuteCommand(string command, int timeout)
{
if (OctaveProcess.HasExited)
{
StartOctave(_ptob, cw);
if (OctaveRestarted != null) OctaveRestarted(this, EventArgs.Empty);
}
_exitError = false;
Thread tmp = new Thread(new ParameterizedThreadStart(WorkThread));
tmp.Start(command);
if (!tmp.Join(timeout))
{
tmp.Abort();
throw new Exception("Octave timeout");
}
if (_exitError)
{
throw new Exception(_errorMessage);
}
return SharedBuilder.ToString();
}
This above is Octave class file. Where I dynamically pass the path of .exe to be run as thread.
Controller Code:
Octave octave = new Octave(OctaveFilePath, false);
string fileData = result.Data.ToString();
fileData = fileData.Replace("#ExcelFilePath#", excelFilePath);
fileData = fileData.Replace("#ABCD#", historyData);
string rasp = octave.ExecuteCommand(fileData, 30000);
From here I get string and that I show into html page.
Related
I have been working on converting a GUI script from another language to C# using VS2017. I have the whole thing working for the most part, but have come on a problem. The gui has a listview which I am populating either manually through entering data in various fields or as an import from a CSV. The manual entry works just fine. The CSV import works as well, however it is pulling the header line into the listview. Here is the code I am using for the button to kick off the import:
private void import(object sender, RoutedEventArgs e)
{
OpenFileDialog xls = new OpenFileDialog();
xls.Multiselect = false;
xls.Filter = "CSV files (*.csv)|*.csv";
xls.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
xls.ShowDialog();
string ins;
if (xls.FileName != null)
{
FileStream srcFS;
srcFS = new FileStream(xls.FileName, FileMode.Open);
StreamReader srcSR = new StreamReader(srcFS, System.Text.Encoding.Default);
do
{
ins = srcSR.ReadLine();
if (ins != null)
{
string[] parts = ins.Split(',');
MyItems.Add(new MyItem
{
Name = parts[0],
CPU = parts[1],
RAM = parts[2],
IP = parts[3],
Subnet = parts[4],
PortGroup = parts[5],
Gateway = parts[6],
DNS = parts[7],
Description = parts[8],
Template = parts[9],
Host = parts[10],
Site = parts[11],
Folder = parts[12],
Datastore = parts[13],
Patch = parts[14],
HDD1_Size = parts[15],
HDD2_Size = parts[16],
HDD3_Size = parts[17],
HDD4_Size = parts[18],
HDD5_Size = parts[19],
HDD6_Size = parts[20],
HDD7_Size = parts[21],
HDD8_Size = parts[22],
HDD9_Size = parts[23],
HDD10_Size = parts[24]
});
}
} while (ins != null);
srcSR.Close();
}
}
I have been googling for some ways to skip the first line, but it most of the suggestions have been to iterate through line by line and write the lines one at a time, which slows the import process (there could be hundreds of lines). Just curious if there is a simple way to tell the StreamReader where to begin reading the file.
You want to read a line and throw it away. Just add an ins = srcSR.ReadLine(); right above your do.
I was trying to automate server patch installation for my product and I came to know about Wix Toolset.
I was hoping to get the JBoss Version in my installer. The command to get the same is standalone.bat --version from cmd.
So from my installer I created one CustomAction where I tried to run it and get the output.
public static string runRunnableBatch(string path){
Process exploitVersionService = new Process();
string runnableBinPath = path;
exploitVersionService.StartInfo.WorkingDirectory = path + "bin";
exploitVersionService.StartInfo.FileName = path + "bin\\standalone.bat";
exploitVersionService.StartInfo.CreateNoWindow = false;
exploitVersionService.StartInfo.Arguments = string.Format("--version");
exploitVersionService.StartInfo.UseShellExecute = false;
exploitVersionService.StartInfo.RedirectStandardOutput = true;
exploitVersionService.StartInfo.RedirectStandardInput = false;
exploitVersionService.Start();
exploitVersionService.WaitForExit();
// /*
string opt = "";
while (!exploitVersionService.StandardOutput.EndOfStream){
opt += exploitVersionService.StandardOutput.ReadLine();
}
// */
//using (StreamWriter writer = new StreamWriter("D:\\_log.txt"))
//using (StreamReader reader = exploitVersionService.StandardOutput){
// writer.AutoFlush = true;
// for (; ; ){
// string textLine = reader.ReadLine();
// if (textLine == null)
// break;
// writer.WriteLine(textLine);
// }
//}
//StreamReader exploitVersionFeed = exploitVersionService.StandardOutput;
//string output = exploitVersionFeed.ReadToEnd();
return opt;
}
When I was doing that, all I got as output was the first line of the whole output string.
I needed the whole string in my code so that from regular expression I could extract the version.
Also tried with
public static string runRunnableBatch(string path){
string executableBinPath = path + "bin";
string executableBinPath_BatchCmd = "cd " + "\"" + executableBinPath + "\"";
string outputFileName = "TempVerInfoHolder.txt";
string outputFilePath = executableBinPath+#"\TempVerInfoHolder1.txt";
string versionRetriever_BatchCmd = #"standalone.bat --version > " + "\""+outputFilePath+"\"";
string partitionName_BatchCmd = #Strings.Utils.getPartitionFromPath(path);
// Creating command sequence
SortedList<int, string> commandSequence = new SortedList<int, string>();
// ~ d:
commandSequence.Add(1, partitionName_BatchCmd);
// ~ cd %path%
commandSequence.Add(2, executableBinPath_BatchCmd);
// ~ standalone.bat --version > %filename%
commandSequence.Add(3, versionRetriever_BatchCmd);
runCommandFromSequence(commandSequence);
// Run together
return "";
}
private static void runCommandFromSequence(SortedList<int, string> commandSequence){
Process seqCmdExecHost = new Process();
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = "cmd.exe";
psi.RedirectStandardInput = true;
psi.RedirectStandardOutput = true;
psi.UseShellExecute = false;
psi.CreateNoWindow = false;
seqCmdExecHost.StartInfo = psi;
seqCmdExecHost.Start();
using (StreamWriter writer = seqCmdExecHost.StandardInput) {
if (writer.BaseStream.CanWrite) {
foreach (int item in commandSequence.Keys){
MessageBox.Show(seqCmdExecHost.Id.ToString());
MessageBox.Show(commandSequence[item]);
writer.WriteLine(commandSequence[item]);
}
}
string opt = "";
while (!seqCmdExecHost.StandardOutput.EndOfStream){
opt += seqCmdExecHost.StandardOutput.ReadLine();
}
MessageBox.Show("Exited? " + seqCmdExecHost.HasExited);
MessageBox.Show("O/P? " + opt);
}
}
I have tried some other way as well. Switching the commented code of the above function was one of them.
Output getting while doing it from code level
Calling "D:\Servers\VA\XYZ\JBoss-7.1.1-Final\bin\standalone.conf.bat
Output while running the same command manually from cmd
Calling D:\Servers\VA\XYZ\JBoss-7.1.1-Final\bin\standalone.conf.bat
======================================================================
JBoss Bootstrap Environment
JBOSS_HOME: D:\Servers\VA\XYZ\JBoss-7.1.1-Final
JAVA: C:\Program Files\Java\jdk1.7.0_67\bin\java
JAVA_OPTS
======================================================================
Listening for transport dt_socket at address: 8787
19:08:08,333 INFO [org.jboss.modules] JBoss Modules version 1.1.1.GA
JBoss AS 7.1.1.Final "Brontes"
Press any key to continue . . .
My observation is, the stream is getting closed once the nested standalone.conf.bat is getting called from standalone.bat.
If any workaround available to get the full output in string/buffer/stream, would be appreciated.
Thanks
What you could do is call the Command line Application instead of calling the batch file
exploitVersionService.StartInfo.WorkingDirectory = path + "bin";
exploitVersionService.StartInfo.FileName = "cmd.exe";
exploitVersionService.StartInfo.CreateNoWindow = false;
exploitVersionService.StartInfo.Arguments = string.Format(" /c \"{0}\" --version",path + "bin\\standalone.bat");
I found one work around to do achieve this.
I created the batch file programmatically and ran it with cmd.
public static void createBatchToGetVersion(string path)
{
CustomLogger.getInstance().debug("Started creating batch file");
BatchOps.executableBinPath = path + "bin";
CustomLogger.getInstance().debug("Ëxecutable bin path: " + BatchOps.executableBinPath);
BatchOps.tempBatchFileName = "JBossVerCmd.bat";
BatchOps.holderFileName = #"JBossVerHolder.txt";
BatchOps.absoluteHolderPath = Strings.Utils.normalize(executableBinPath) + holderFileName;
CustomLogger.getInstance().debug("Normalized absoluteHolderPath: " + BatchOps.absoluteHolderPath);
CustomLogger.getInstance().debug("Checking if JBOSS_HOME entered by user actuallty points to JBOSS");
if (!File.Exists(Strings.Utils.normalize(executableBinPath) + "standalone.bat"))
{
CustomLogger.getInstance().error("standalone.bat not found. JBOSS_HOME Dir is not correctly entered");
throw new CustomExceptions.DirectoryNotAcceptableException("Bad directory is assigned to JBOSS_HOME or JBOSS_HOME structure corrupted");
}
/*
* Batch file formation.
* Contains:
* Start file
* D:
* cd D:\Fusion Server\jboss 7.1.1\bin
* #echo | call standalone.bat --version > sample.txt
* #echo Done
* End file
* #echo is required here because it exits the cmd when completed whithout having the user pressing any key
*/
string changePartition_cmd = Strings.Utils.getPartitionFromPath(path);
string changeDirectory_cmd = #"cd " + BatchOps.executableBinPath;
string getVersion_cmd = #"#echo | call standalone.bat --version > " + holderFileName;
string exitCmd = #"#echo Done";
CustomLogger.getInstance().debug("Command to be written on batch file");
CustomLogger.getInstance().debug("\r\n" + changePartition_cmd + "\r\n" + changeDirectory_cmd + "\r\n" + getVersion_cmd + "\r\n" + exitCmd);
SortedList<int, string> commandSequence = new SortedList<int, string>();
CustomLogger.getInstance().debug("Initializing command sequence.");
commandSequence.Add(1, changePartition_cmd);
commandSequence.Add(2, changeDirectory_cmd);
commandSequence.Add(3, getVersion_cmd);
commandSequence.Add(4, exitCmd);
// Will create one if file never existed and open one delete the content and set the pointer to the begnning
// if already existed
StreamWriter batchFileWriter = null;
try
{
CustomLogger.getInstance().debug("Establishing stream to and from temp batch file");
batchFileWriter = new StreamWriter(tempBatchFileName);
CustomLogger.getInstance().debug("Command sequence ready to be written on temp batch file.");
Perform.writeToStreamFromSequence(batchFileWriter, commandSequence);
CustomLogger.getInstance().debug("Command sequence successfully written");
}
catch (IOException ex)
{
CustomLogger.getInstance().error("Error while writing command sequence.\n" + ex.ToString());
// throw exception to CustomAction
throw new IOException("Error while writing commandSequence");
}
finally
{
// Not required. Stream already closed in writeToStreamFromSequence
}
}
public static void runTempBatchFile()
{
Process seqCmdExecHost = new Process();
ProcessStartInfo procStartInfo = new ProcessStartInfo("cmd", #"/c " + BatchOps.tempBatchFileName);
procStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
seqCmdExecHost.StartInfo = procStartInfo;
seqCmdExecHost.Start();
seqCmdExecHost.WaitForExit();
seqCmdExecHost.Close();
}
I found the moment i was doing
procStartInfo.UseShellExecute=true;
procStartInfo.RedirectStandardOutput=true
It was giving the first line of output. Dont know why?. If anyone has any idea about it please explain.
Thanks
I have an application developed in c#. This application send sms to client. This application was doing good till yesterday but suddenly this morning I find that if I start the application it is starting but not showing anywhere in the desktop not even in the task bar. I tried to stop it using the Task manager but I could not find it in the task manager. I have included some function in my code which restricts to run two instances of this application at the same time. So, when I try to run again it shows this Application is already running. I can only close it using TCP Viewer which helps to close background program. But I have not written any line of code to run it on the background.
Even when I am debugging it is going to the debug points correctly but not showing the form. Please help me on this.
Here is my form load code as sample:
private void Form1_Load(object sender, EventArgs e)
{
tcnt = 1;
thistime = DateTime.Now.Date;
techtime = "09:00:01";
techdate = DateTime.Now.Date;
dntime = DateTime.Now.Date;
rebillingdate = DateTime.Now.Date;
checkState[1] = true;
checkState[2] = false;
checkState[3] = false;
this.tmrLog.Enabled = true;
this.stStatus.Text = "Form loading";
string myDate = DateTime.Now.Date.ToString("yyyyMMdd");
string myFile = null;
string myDir = "logs\\schedule\\";
StreamReader sr = default(StreamReader);
string str = null;
DirectoryInfo dir = new DirectoryInfo(myDir);
//DirectoryInfo DirItem = default(DirectoryInfo);
FileInfo[] dirfiles = null;
//FileInfo myf = default(FileInfo);
this.Controls.Add(lsLog);
lsLog.Items.Clear();
if (dir.Exists == true)
{
foreach (var DirItem in dir.GetDirectories())
{
dirfiles = DirItem.GetFiles();
foreach (var myf in dirfiles)
{
if (myf.Name.IndexOf("schedule") > 0 & myf.Name.IndexOf(myDate) > 0)
{
myFile = "logs\\schedule\\" + DirItem.Name + "\\" + myf.Name;
if (DirItem.Name == "48" | DirItem.Name == "IPX")
{
sr = File.OpenText(myFile);
while (sr.Peek() != -1)
{
str = sr.ReadLine();
lsLog.Items.Insert(0, str);
}
sr.Close();
}
}
}
}
}
tmrLog.Enabled = true;
}
I have written a photoshop script to generate product image for a newsletter on runtime and a vbs script to call it which all work fine when I execute the vbs script throught the command line, but if I call it from a asp.net application it doesn't, then a get the error: There is no script engine for file extension ".jsx".
The jsx script, the vbs script and the code I use to execute can be found below. Can anyone help me to make it work through the asp.net application please.
UPDATE
I managed to fix the script engine error, that was just a problem with the c# process argument. I've fixed the code below. It would seem, the problem is the network service user, doesn't have permission to startup photoshop. I have tried all kind of stuff to give it the right permission, but it's still not working.
How do I allow the network service user to access photoshop?
JSX script:
#target photoshop
function getLayer(target, layerName)
{
try
{
var layer = doc.layers.getByName(layerName);
return layer;
}
catch(e)
{
alert("Unable to find layer: " + layerName); // only for debug
}
return false;
}
function changeTextOnTextLayer(target, layerName, textToInsert)
{
var textLayer = getLayer(target, layerName);
if(textLayer && textLayer.kind == LayerKind.TEXT)
{
textLayer.textItem.contents = textToInsert;
}
textLayer = null;
}
function setImageOnLayerFromFile(target, layerName, fullFileName)
{
var imageLayer = getLayer(target, layerName);
if(imageLayer)
{
var x = imageLayer.bounds[0];
var y = imageLayer.bounds[1];
var layerSize = getWidthAndHeight(imageLayer);
var width = layerSize[0];
var height = layerSize[1];
var file = File(fullFileName);
app.load(file);
var imageFile = app.activeDocument;
imageFile.resizeImage( width, height);
imageFile.selection.selectAll();
imageFile.selection.copy();
imageFile.close(SaveOptions.DONOTSAVECHANGES);
file.close();
file = null;
target.paste();
var newImageLayer = target.layers[0];
moveLayerTo(newImageLayer, x, y);
}
textLayer = null;
}
function getWidthAndHeight(layer)
{
var width = layer.bounds[2] - layer.bounds[0];
var height = layer.bounds[3] - layer.bounds[1];
return [width, height];
}
function moveLayerTo(fLayer,fX,fY)
{
var Position = fLayer.bounds;
Position[0] = fX - Position[0];
Position[1] = fY - Position[1];
fLayer.translate(Position[0],Position[1]);
}
function saveToPNG(doc, fileName)
{
var file = new File(fileName);
opts = new ExportOptionsSaveForWeb();
with (opts)
{
format = SaveDocumentType.PNG;
PNG8 = false;
}
doc.exportDocument(file, ExportType.SAVEFORWEB, opts);
// save for web
}
if(!arguments || arguments.length != 5 )
{
alert("Missing arguments!"); // only for debug
}
else
{
var file = File(arguments[0]);
app.load(file);
var doc = app.activeDocument;
setImageOnLayerFromFile(doc, 'Image', arguments[1]);
changeTextOnTextLayer(doc, 'ProductDescription', arguments[3]);
changeTextOnTextLayer(doc, 'Price', arguments[4]);
saveToPNG(doc, arguments[2]);
doc.close(SaveOptions.DONOTSAVECHANGES);
doc = null;
file.close();
file = null;
}
VBS script:
Set vbsArguments = WScript.Arguments
If vbsArguments.Length = 0 Then
WScript.Echo "Argument(0) is `your script to execute"
WScript.Echo "Arguments(0+n) are passed to your script as argument(0) to argument(n-1)"
Else
ReDim jsxArguments(vbsArguments.length-2)
for i = 1 to vbsArguments.length - 1
jsxArguments(i-1) = vbsArguments(i)
Next
Set photoshop = CreateObject( "Photoshop.Application" )
photoshop.BringToFront
Call photoshop.DoJavaScriptFile( vbsArguments(0), jsxArguments, 1)
End IF
C# asp.net
const string vbsScript = "cscript";
string arguments = "\"" + #"D:\script\createproduct.vbs" + "\" " + string.Format(#"D:\script\createproduct.jsx " +
"/d/script/test.psd \"{0}\" \"{1}\" \"{2}\" \"{3}\"",
imagePath,
fullSavePath,
requestSpecificProduct.ShortDescription,
requestSpecificProduct.DisplayPrice);
context.Response.Write(vbsScript + "\n");
context.Response.Write(arguments);
using (var scriptProc = new Process
{
StartInfo =
{
FileName = vbsScript,
Arguments = arguments,
WorkingDirectory = #"D:\",
WindowStyle = ProcessWindowStyle.Hidden,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
}
})
{
scriptProc.Start();
scriptProc.WaitForExit();
Thank you for your help
I'm trying to remove a Silverlight Out Of Browser app programatically passing the arguments to sllauncher in following this post: http://timheuer.com/blog/archive/2010/03/25/using-sllauncher-for-silent-install-silverlight-application.aspx However it won't uninstall the app when given the origin.
It turns out that when you have an automatically updating Out-Of-Browser application, Silverlight stamps each application Uri with a time stamp that can be found in the application's folder in the C:\Users\Trevor\AppData\Local\Microsoft\Silverlight\OutOfBrowser(AppFolderName) metadata file. So to facilitate the removal of our app in preparation for our new one, I implemented the following:
UninstallExisting(GetInstalledAppUri()); // This is how it's called
//This is the two method's implementation
// TODO: Change to your app name.
const string appName = "YourAppNameHere";
static string silverlightOutOfBrowserFolder =
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)
+ #"\Microsoft\Silverlight\OutOfBrowser";
private static string GetInstalledAppUri()
{
string xapFolderPath = Path.Combine(silverlightOutOfBrowserFolder, GetXapFolder());
string[] lines = File.ReadAllLines(Path.Combine(xapFolderPath, "metadata"), Encoding.Unicode);
string finalAppUriLine = lines.First(i => i.Contains("FinalAppUri="));
return "\"" + finalAppUriLine.Replace("FinalAppUri=", "") + "\"";
}
private static string GetXapFolder()
{
string AppXapFolder = "";
foreach (var dir in Directory.GetDirectories(silverlightOutOfBrowserFolder))
{
if (dir.Contains(appName))
{
AppXapFolder = dir;
}
}
return AppXapFolder ;
}
private static string silverlightExe
{
get
{
return Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles),
#"Microsoft Silverlight\sllauncher.exe");
}
}
private static void UninstallExisting(string xapUriToRemove)
{
string installArgs = "/uninstall" + " /origin:" + xapUriToRemove;
ProcessStartInfo pstart = new ProcessStartInfo(silverlightExe, installArgs);
Process p = new Process();
pstart.UseShellExecute = false;
p.StartInfo = pstart;
p.Start();
p.WaitForExit();
}
I hope this serves to save someone else the hours of time it took me to figure out about the metadata file and all the peculiarities of sllauncher.exe