Usefull information about PSExec.exe
Class I used to execute a program (FME + extra parameters) on a remote server.
public class TrackValidator
{
public string DestinationDirectoryPathFromClient { get; private set; }
public string DestinationDirectoryPathFromServer { get; private set; }
public string TrackUploadBatchName { get; private set; }
public FileInfo SourceFile { get; set; }
public string CopiedSourceFileName { get; private set; }
public string OutputSourceFileName { get; private set; }
public string FmeExePath { get; private set; }
public string WorkbenchPath { get; private set; }
public string WorkbenchName { get; private set; }
public FileInfo PsExec { get; private set; }
public string ServerName { get; private set; }
public string UserName { get; private set; }
public string Password { get; private set; }
public TrackValidator()
{
DestinationDirectoryPathFromClient = @"\\hictblockap022\FME\TrackUpload\";
DestinationDirectoryPathFromServer = @"E:\FME\TrackUpload\";
TrackUploadBatchName = "trackupload.bat";
CopiedSourceFileName = "source.sdf";
OutputSourceFileName = "output.sdf";
PsExec = new FileInfo(@"c:\data\fme\PsTools\PsExec.exe");
ServerName = @"\\hictblockap022";
UserName = "CXP8200";
Password = "password";
FmeExePath = @"C:\Program
Files\FME\fme.exe";
WorkbenchPath = @"E:\FME\Workbenches\TrackUpload\";
WorkbenchName = "trackupload.fmw";
}
private void CreateBatch()
{
if(SourceFile == null)
throw new Exception("Undefined Sourcefile.");
if(!SourceFile.Exists)
throw new Exception("Sourcefile doesn't exist.");
const char c = '"';
using (var sw = new StreamWriter(DestinationDirectoryPathFromClient +
TrackUploadBatchName))
{
sw.WriteLine(c + FmeExePath + c + " " + WorkbenchPath + WorkbenchName);
sw.WriteLine(@"--SourceDataset_SDF3
" +
DestinationDirectoryPathFromServer + CopiedSourceFileName);
sw.WriteLine(@"--TOLERANCE_VAL
0.01");
sw.WriteLine(@"--DestDataset_SDF3
" +
DestinationDirectoryPathFromServer + OutputSourceFileName);
}
}
private void CreateSource()
{
File.Copy(SourceFile.FullName,
DestinationDirectoryPathFromClient + CopiedSourceFileName);
}
private void RemoveBatch()
{
if(File.Exists(DestinationDirectoryPathFromClient + TrackUploadBatchName))
File.Delete(DestinationDirectoryPathFromClient
+ TrackUploadBatchName);
}
private void RemoveOutput()
{
if(File.Exists(DestinationDirectoryPathFromClient + OutputSourceFileName))
File.Delete(DestinationDirectoryPathFromClient
+ OutputSourceFileName);
}
private void RemoveSource()
{
if (File.Exists(DestinationDirectoryPathFromClient
+ CopiedSourceFileName))
File.Delete(DestinationDirectoryPathFromClient
+ CopiedSourceFileName);
}
public void Upload()
{
RemoveBatch();
RemoveSource();
RemoveOutput();
CreateSource();
CreateBatch();
string arg = ServerName + @" cmd.exe -u " + UserName + @" -p " + Password + @" /c " +
DestinationDirectoryPathFromServer + TrackUploadBatchName;
var p = new Process
{
StartInfo =
{
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
RedirectStandardInput = true,
FileName = PsExec.FullName,
Arguments = arg,
CreateNoWindow = true
}
};
p.Start();
string output =
p.StandardOutput.ReadToEnd();
string errormessage =
p.StandardError.ReadToEnd();
p.WaitForExit();
RemoveSource();
RemoveBatch();
}
}
As a rule of thumb: if something implements IDisposable, You really should call Dispose/Close or use using(...) on it. Note that calling Close on a process does not cause the process to exit.
ReplyDeleteAlso when waiting for a process to exit, u should really check it with a valid timeout, if it gets blocked by anything, then you can decide what to do with it:
ReplyDeleteIt could look something like this... (btw, have no idea how to format code here so ill show it here: http://nopaste.info/5587abfded.html )
I'll look into it. Thanks for the head up.
ReplyDelete