Process killing itself - c#

I'm working on writing a program to batch convert video files using HandbrakeCLI as the converter. I've got most of it set up and am actually working on passing the file to Handbrake now. I create a new process with the location of HandbrakeCLI and pass the arguments. I also make it so it executes in the same shell. It spins up and then starts to go through the converting and gets to three frames or so and kills itself. I'm using Visual Studio 12 on Windows 8 64 bit. Here's my code:
static void EncodeVideos()
{
var continueConverting = true;
while (continueConverting)
{
var converted = 0;
if (settings.Optimize == true)
{
videos = videos.OrderBy(x => x.InputSize).ToList();
}
foreach (var v in videos)
{
if (!v.AlreadyConverted())
{
v.CreateOutputPath();
var input = String.Format("-i \"{0}\" ", v.InputPath);
var output = String.Format("-o \"{0}\" ", v.OutputPath);
var preset = String.Format("-Z {0}", settings.Preset);
var convertString = String.Format(" {0} {1} {2}", input, output, preset);
//Converting is not working correctly yet.
var p = new Process();
p.StartInfo = new ProcessStartInfo(settings.HandBrakeLocation, convertString)
{
UseShellExecute = false,
};
p.Start();
p.WaitForExit();
converted++;
}
}
if (settings.Loop == true)
{
if (converted == 0)
{
continueConverting = false;
}
}
else
{
continueConverting = false;
}
}
}
If you would like more context for the code, I've put it all on github and you can find it on Github.
Edit: Fixed code

if (settings.Loop == true)
{
if (converted == 0)
{
continueConverting = false;
}
continueConverting = false;
}
else
{
continueConverting = false;
}
I guess you REALLY don't want to continue converting!
This looks like it's incorrect for a start.

Related

Running an R-script from C#

I have the following R script and C# program that is used as an example of calling R from C#. If I run the script from within R-GUI, I see the expected output. However, if I run it from within C# as below, I get no output. I tried moving the R script inside the C# executable directory, and this doesn't work either. I tried running Visual Studio as Administrator, again no output.
Not sure what I am doing wrong:
R code:
# Gradient Boosting model with gbm
# Turn off library warning messages
suppressWarnings(library(gbm))
# gbm result for simulated data
get_gbm <- function()
{
set.seed(123)
a <- sample(1:10, 250, replace = T)
b <- sample(10:20, 250, replace = T)
flag <- ifelse(a > 5 & b > 10, "red", ifelse(a < 3, "yellow", "green"))
df <- data.frame(a = a, b = b, flag = as.factor(flag))
train <- df[1:200,]
test <- df[200:250,]
mod_gb <- gbm(flag ~ a + b,
data = train,
distribution = "multinomial",
shrinkage = .01,
n.minobsinnode = 10,
n.trees = 100)
pred <- predict.gbm(object = mod_gb,
newdata = test,
n.trees = 100,
type = "response")
res <- cbind(test, pred)
return(res)
}
# need to call function to get the output
get_gbm()
C# code:
using System;
using System.Diagnostics;
using System.IO;
class Program
{
static void Main(string[] args)
{
var rmainpath = #"C:\Program Files\R\R-4.0.3";
var rpath = rmainpath + #"\bin\Rscript.exe";
var mainGoogleDrivePath = #"C:\Users\Administrator\Google Drive";
//var scriptpath = mainGoogleDrivePath + #"\repos\rsource\Script.R";
var scriptpath = mainGoogleDrivePath + #"\Projects\RFromCSharp\RFromCSharp\bin\Debug\Script.R";
var output = RunRScript(rpath, scriptpath);
Console.WriteLine(output); // output is empty
Console.ReadLine();
}
private static string RunRScript(string rpath, string scriptpath)
{
try
{
var info = new ProcessStartInfo
{
FileName = rpath,
WorkingDirectory = Path.GetDirectoryName(scriptpath),
Arguments = scriptpath,
RedirectStandardOutput = true,
CreateNoWindow = true,
UseShellExecute = false
};
using (var proc = new Process { StartInfo = info })
{
if (false == proc.Start())
throw new Exception("Didn't start R");
return proc.StandardOutput.ReadToEnd();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
return string.Empty;
}
}

C# WUApiLib know if a windows update needs a restart

I use this code to get pending windows updates and also most of the informations of the update:
static List<PendingUpdate> GetPendingUpdates()
{
var updateSession = new UpdateSession();
var updateSearcher = updateSession.CreateUpdateSearcher();
updateSearcher.Online = false; //set to true if you want to search online
List<PendingUpdate> pendingUpdates = new List<PendingUpdate>();
try
{
var searchResult = updateSearcher.Search("IsInstalled=0 And IsHidden=0");
if (searchResult.Updates.Count > 0)
{
Console.WriteLine("There are updates available for installation");
foreach (IUpdate windowsUpdate in searchResult.Updates)
{
PendingUpdate update = new PendingUpdate();
update.Title = windowsUpdate.Title;
update.Description = windowsUpdate.Description;
update.Downloaded = windowsUpdate.IsDownloaded;
update.Urls = new List<string>();
foreach (string url in windowsUpdate.MoreInfoUrls)
{
update.Urls.Add(url);
}
foreach (dynamic category in windowsUpdate.Categories)
{
update.Categories += category.Name + ", ";
}
pendingUpdates.Add(update);
}
}
}
catch (Exception ex)
{
Console.WriteLine("ERROR");
throw ex;
}
return pendingUpdates;
}
I also use this code to get to know if the computer currently needs a restart to finish installed updates:
static bool needsRestart()
{
ISystemInformation systemInfo = new SystemInformation();
return systemInfo.RebootRequired;
}
Now my question is, is it possible to get to know if an pending update needs a computer restart to finish? In the first code I get a IUpdate object but I dont see informations about a needed restart after installing this update. I there a way to get this information?
For the asynchronous installation I use something like this:
rebootRequired = false;
UpdateSession updateSession = new UpdateSession();
updateSession.ClientApplicationID = SusClientID;
IUpdateInstaller updatesInstaller = updateSession.CreateUpdateInstaller();
IInstallationJob job = updatesInstaller.BeginInstall(InstallProgressCallback, installComplete, installState);
// here is your installer code and the checking if the installation is completed
IInstallationProgress jobProgress = job.GetProgress();
for (int updateindex = 0; updateindex < updatesInstaller.Updates.Count; updateindex++)
{
IUpdateInstallationResult updateInstallResult = jobProgress.GetUpdateResult(updateindex);
rebootRequired |= updateInstallResult.RebootRequired;
}
if(rebootRequired)
{
// any of the updates need a reboot
}

How to kill the application that is using a TCP port in C#?

I want to free a TCP port during startup of my application (asking confirmation to user), how to get the PID number and then, if the user confirm, kill it?
I know I can get this information by netstat, but how to do it in a script or better in a C# method.
You can run netstat then redirect the output to a text stream so you can parse and get the info you want.
Here is what i did.
Run netstat -a -n -o as a Process
redirect the standard out put and capture the output text
capture the result, parse and return all the processes in use
check if the port is being used
find the process using linq
Run Process.Kill()
you will have to do the exception handling.
namespace test
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
Console.WriteLine("Port number you want to clear");
var input = Console.ReadLine();
//var port = int.Parse(input);
var prc = new ProcManager();
prc.KillByPort(7972); //prc.KillbyPort(port);
}
}
public class PRC
{
public int PID { get; set; }
public int Port { get; set; }
public string Protocol { get; set; }
}
public class ProcManager
{
public void KillByPort(int port)
{
var processes = GetAllProcesses();
if (processes.Any(p => p.Port == port))
try{
Process.GetProcessById(processes.First(p => p.Port == port).PID).Kill();
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
else
{
Console.WriteLine("No process to kill!");
}
}
public List<PRC> GetAllProcesses()
{
var pStartInfo = new ProcessStartInfo();
pStartInfo.FileName = "netstat.exe";
pStartInfo.Arguments = "-a -n -o";
pStartInfo.WindowStyle = ProcessWindowStyle.Maximized;
pStartInfo.UseShellExecute = false;
pStartInfo.RedirectStandardInput = true;
pStartInfo.RedirectStandardOutput = true;
pStartInfo.RedirectStandardError = true;
var process = new Process()
{
StartInfo = pStartInfo
};
process.Start();
var soStream = process.StandardOutput;
var output = soStream.ReadToEnd();
if(process.ExitCode != 0)
throw new Exception("somethign broke");
var result = new List<PRC>();
var lines = Regex.Split(output, "\r\n");
foreach (var line in lines)
{
if(line.Trim().StartsWith("Proto"))
continue;
var parts = line.Split(new char[]{' '}, StringSplitOptions.RemoveEmptyEntries);
var len = parts.Length;
if(len > 2)
result.Add(new PRC
{
Protocol = parts[0],
Port = int.Parse(parts[1].Split(':').Last()),
PID = int.Parse(parts[len - 1])
});
}
return result;
}
}
}

File upload on Parse.com isn't working

I have been developing a game in Unity3D in C#. So I have set the game to upload the game save file
to Parse every 2 minutes. When I run the code in Unity it works fine, it saves the game save file locally, and every 2 minutes it uploads it to Parse, it also points to the user who's playing the game. Although when I run the game on a mobile device the file does not upload, I have been refreshing my parse data object in the last half an hour and I still haven't got anything.
Here is the code:
void Start ()
{
if (ParseUser.CurrentUser != null)
{
gapTest = true;
}
}
void Update ()
{
if(gapTest)
{
StartCoroutine(UploadFile());
}
if (uploadSaveFile)
{
OnZipComplete();
uploadSaveFile = false;
}
else if (createNewSaveFile)
{
CreateNewSaveFile();
createNewSaveFile = false;
}
}
IEnumerator UploadFile()
{
gapTest = false;
yield return new WaitForSeconds (120.0F);
if(ParseUser.CurrentUser != null)
{
OnZipComplete();
}
gapTest = true;
}
void OnZipComplete()
{
var query = ParseObject.GetQuery("GameSave").WhereEqualTo("UserObjectId", ParseUser.CurrentUser);
if (existingGameSave == null)
{
query.FindAsync().ContinueWith(t =>
{
IEnumerable<ParseObject> results = t.Result;
int resultCount = 0;
foreach (var result in results)
{
if (resultCount > 0)
{
Debug.LogError("Found more than one save file for user!");
}
else
{
resultCount++;
existingGameSave = result;
uploadSaveFile = true;
}
}
if (resultCount == 0)
{
createNewSaveFile = true;
}
});
}
else
{
UpdateExistingSaveFile();
}
}
private void CreateNewSaveFile()
{
//upload the file to parse
zipPath = Application.persistentDataPath + "/SaveGame.zip";
byte[] data = System.Text.Encoding.UTF8.GetBytes(zipPath);
ParseFile GameSave = new ParseFile("GameSave.zip", data);
var gameSave = new ParseObject("GameSave");
gameSave["UserObjectId"] = ParseUser.CurrentUser;
gameSave["GameSaveFile"] = GameSave;
Task saveTask = gameSave.SaveAsync();
Debug.Log("New Game save file has been uploaded");
}
void UpdateExistingSaveFile()
{
//upload the file to parse
UserIdFile = Application.persistentDataPath + "/UserId.txt";
zipPath = Application.persistentDataPath + "/SaveGame.zip";
byte[] data = System.Text.Encoding.UTF8.GetBytes(zipPath);
ParseFile GameSave = new ParseFile("GameSave.zip", data);
existingGameSave["GameSaveFile"] = GameSave;
Task saveTask = existingGameSave.SaveAsync();
Debug.Log("Existing Game save file has been uploaded");
}
This might be a problem related to permission on android device.
Go to Build Setting > Player Setting > Other Settings, and check "Write Access", by default, it is internal Only which means that the path is for development purpose only.
Try Setting the Write Access as External(SD Card) or add WRITE_ EXTERNAL_STORAGE permission into AndroidManifest.xml. And check Android/file/com.your.appid/files of your sd card if your data is actually getting written on device.
If data is getting written, then it will sure get uploaded on parse.com.

How to start Windows Azure Storage Emulator V3.0 from code

Since I installed the new Windows Azure SDK 2.3 I got a warning from csrun:
"DevStore interaction through CSRun has been depricated. Use WAStorageEmulator.exe instead."
So there are two questions:
1) How to start the new storage emulator correctly from code?
2) How to determine from code if the storage emulator is already running?
I found the solution myself. Here is my C# code. The old code used for SDK 2.2 is commented out.
public static void StartStorageEmulator()
{
//var count = Process.GetProcessesByName("DSServiceLDB").Length;
//if (count == 0)
// ExecuteCSRun("/devstore:start");
var count = Process.GetProcessesByName("WAStorageEmulator").Length;
if (count == 0)
ExecuteWAStorageEmulator("start");
}
/*
private static void ExecuteCSRun(string argument)
{
var start = new ProcessStartInfo
{
Arguments = argument,
FileName = #"c:\Program Files\Microsoft SDKs\Windows Azure\Emulator\csrun.exe"
};
var exitCode = ExecuteProcess(start);
Assert.AreEqual(exitCode, 0, "Error {0} executing {1} {2}", exitCode, start.FileName, start.Arguments);
}
*/
private static void ExecuteWAStorageEmulator(string argument)
{
var start = new ProcessStartInfo
{
Arguments = argument,
FileName = #"c:\Program Files (x86)\Microsoft SDKs\Windows Azure\Storage Emulator\WAStorageEmulator.exe"
};
var exitCode = ExecuteProcess(start);
Assert.AreEqual(exitCode, 0, "Error {0} executing {1} {2}", exitCode, start.FileName, start.Arguments);
}
private static int ExecuteProcess(ProcessStartInfo start)
{
int exitCode;
using (var proc = new Process { StartInfo = start })
{
proc.Start();
proc.WaitForExit();
exitCode = proc.ExitCode;
}
return exitCode;
}
using System;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using Xunit;
namespace UnitTests.Persistence
{
public class AzureStorageEmulatorManagerV3
{
private const string ProcessName = "WAStorageEmulator";
public static void StartStorageEmulator()
{
var count = Process.GetProcessesByName(ProcessName).Length;
if (count == 0)
ExecuteWAStorageEmulator("start");
}
public static void StopStorageEmulator()
{
Process process = GetWAstorageEmulatorProcess();
if (process != null)
{
process.Kill();
}
}
private static void ExecuteWAStorageEmulator(string argument)
{
var start = new ProcessStartInfo
{
Arguments = argument,
FileName = #"c:\Program Files (x86)\Microsoft SDKs\Windows Azure\Storage Emulator\WAStorageEmulator.exe"
};
var exitCode = ExecuteProcess(start);
if (exitCode != 0)
{
string message = string.Format(
"Error {0} executing {1} {2}",
exitCode,
start.FileName,
start.Arguments);
throw new InvalidOperationException(message);
}
}
private static int ExecuteProcess(ProcessStartInfo start)
{
int exitCode;
using (var proc = new Process { StartInfo = start })
{
proc.Start();
proc.WaitForExit();
exitCode = proc.ExitCode;
}
return exitCode;
}
public static Process GetWAstorageEmulatorProcess()
{
return Process.GetProcessesByName(ProcessName).FirstOrDefault();
}
[Fact]
public void StartingAndThenStoppingWAStorageEmulatorGoesOk()
{
// Arrange Start
AzureStorageEmulatorManagerV3.StartStorageEmulator();
// Act
Thread.Sleep(2000);
Process WAStorageEmulatorProcess = GetWAstorageEmulatorProcess();
// Assert
Assert.NotNull(WAStorageEmulatorProcess);
Assert.True(WAStorageEmulatorProcess.Responding);
// Arrange Stop
AzureStorageEmulatorManagerV3.StopStorageEmulator();
Thread.Sleep(2000);
// Act
WAStorageEmulatorProcess = GetWAstorageEmulatorProcess();
// Assert
Assert.Null(WAStorageEmulatorProcess);
}
}
}
See my answer here. It actually uses the WAStorageEmulator status API instead of simply relying on testing whether or not the process exists as in #huha's own answer.
See my answer here. It uses a neat little NuGet package to assist with starting/stopping the Azure Storage Emulator programmatically: RimDev.Automation.StorageEmulator.

Categories

Resources