I setting my WorkerService appsettings.json like below
"AppRun": {
"App1": {
"AppName": "CheckDataForm",
"AppPath": "D:\\2021-Project\\Project\\CheckDataForm-MSSQL\\CheckDataForm\\bin\\Debug\\net5.0-windows\\CheckDataForm.exe"
},
"App2": {
"AppName": "notepad++",
"AppPath": "C:\\Program Files\\Notepad++\\notepad++.exe"
},
and
call the app like this:
//i is foreach count
var AppName = _config["AppRun:App"+i+":AppName"];
var AppPath = _config["AppRun:App" + i + ":AppPath"];
//check file exist
var fileExist = System.IO.File.Exists(AppPath);
if ( !String.IsNullOrEmpty (AppName) && !String.IsNullOrEmpty(AppPath) &&
fileExist )
{
//find APP
var processApp = Process.GetProcessesByName(AppName);
//can't find app
if (processApp.Length <=0 )
{
try
{
Process proc = new Process();
proc.StartInfo.FileName = AppPath;
proc.StartInfo.UseShellExecute = true;
proc.StartInfo.Verb = "runas";
proc.Start();
}
catch (Exception ex)
{
var error = ex;
}
}
}
the Process can Start notepad++ , but can't start CheckDataForm .net core windowsForm app, and no exception ,
(I have added to RegistryKey , .netframework 4.8 Ver work well , but .net core 5 Ver have no any Responds and no error)
but I can Manual to run CheckDataForm , and work well,
have any idea to fix it, thank you
If I make assumption that you are not able to load reference when running .net core application then you have to add following line overthere.
Process proc = new Process();
proc.StartInfo.FileName = AppPath;
proc.StartInfo.WorkingDirectory = System.IO.Path.GetDirectoryName(AppPath);
proc.StartInfo.UseShellExecute = true;
proc.StartInfo.Verb = "runas";
proc.Start();
You have to set WorkingDirectory.
Related
I have a requirement where application (app1) needs to install / run another application (app2) on user system in non production hours without UAC prompt. I think I can do it with windows service which will elevate my application 1 (app1) which will install my app 2. I worte below code in my console app which will called by windows service :
SecureString ss = ConvertStr.ConvertToSecureString("****");
DirectoryInfo d = new DirectoryInfo(userDownloadFolder);
string[] extensions = new[] { ".bat", ".exe" };
FileInfo[] Files =
d.GetFiles()
.Where(f => extensions.Contains(f.Extension.ToLower()))
.ToArray();
foreach (FileInfo file in Files)
{
if (File.Exists(d.FullName + file.Name))
{
try
{
var proc = new Process();
proc.StartInfo.FileName = d.FullName + file.Name;
proc.StartInfo.Domain = "****";
proc.StartInfo.UserName = "**********";
proc.StartInfo.Password = ss;
proc.StartInfo.Verb = "runas";
proc.StartInfo.UseShellExecute = false;
proc.Start();
proc.WaitForExit();
var exitCode = proc.ExitCode;
proc.Close();
}
catch (Exception ex)
{
Logger.WriteToFile(ex.Message);
}
}
else
{
Logger.WriteToFile("File does not exists");
}
Console application runs but it gives Access is denied. But when I tried to install /run by manually right clicking app with user Id & password in UAC prompt it works. Any idea any other way to implement this.
I have a WPF application that executes a Powershell script and then displays a message in a textbox in the application. The Powershell script is executed like this:
string scriptPath = folderPath + "/EXECUTE.ps1";
string powershellPath = #"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe";
string outputLog = folderPath + "output.log";
bool is64 = IntPtr.Size == 8;
var ENV = "Get-ItemProperty HKLM:\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\* "
+ (is64 ? ",HKLM:\\Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\*" : "")
+ " | Select-Object DisplayName";
ProcessStartInfo startInstall = new ProcessStartInfo(powershellPath, ENV);
startInstall.UseShellExecute = false;
startInstall.Arguments = scriptPath;
startInstall.EnvironmentVariables.Add("RedirectStandardOutput", "true");
startInstall.EnvironmentVariables.Add("RedirectStandardError", "true");
startInstall.EnvironmentVariables.Add("UseShellExecute", "false");
startInstall.EnvironmentVariables.Add("CreateNoWindow", "true");
Process Install = Process.Start(startInstall);
Install.Close();
Console.WriteLine("Script executed successfully");
Console.WriteLine("Output available at: " + outputLog);
The last two lines in Console.WriteLine are printed out in a textbox. I was wondering, is there a way that I can show the output of the Powershell terminal window inside of this textbox named txtboxExecutionResult? I am not executing any Powershell command from my application, just starting and executing the EXECUTE.ps1 file from the application. I'd really appreciate any help to point me in some direction.
I had a similar issue once with reading output from another application and I solved it by reading the standard output of the process.
Process process = new Process();
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = false;
process.StartInfo.CreateNoWindow = false;
process.StartInfo.FileName = "example.exe";
process.StartInfo.Arguments = args;
process.Start();
output = await process.StandardOutput.ReadToEndAsync();
I am getting the error:
Cannot access the file because it is being used by another process
I have a C# desktop app.
I am using the Process class to convert images to a video file by using FFMPEG.
This is my code:
using (Process serverBuild = new Process())
{
serverBuild.StartInfo.WorkingDirectory = Environment.CurrentDirectory;
string args = " -f image2 -i " + {path} + "\\img%05d.jpg -s 352x288 -filter:v \"setpts=5.0*PTS\" -y " + {path}\\File.mp4;
serverBuild.StartInfo.Arguments = args;
serverBuild.StartInfo.FileName = "ffmpeg.exe";
serverBuild.StartInfo.UseShellExecute = false;
serverBuild.StartInfo.RedirectStandardOutput = true;
serverBuild.StartInfo.RedirectStandardError = true;
serverBuild.StartInfo.CreateNoWindow = true;
serverBuild.Start();
// string output = serverBuild.StandardOutput.ReadToEnd();
//Log.Instance.Debug(serverBuild.StandardError.ReadToEnd());
serverBuild.WaitForExit();
serverBuild.Close();
}
Directory.Delete(ExportRoute + FFMPEGPacket.LicenseKey + "\\" + FFMPEGPacket.Guid, true);
//which raise the error..
The images are all deleted but the File.Mp4 is not and that is the error. The error says that the newly created MP4 file cannot be deleted.
NB
This is partial code to illustrate the error
You may try the following code to create the file (it worked for me):
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = exe_path;
// replace your arguments here
psi.Arguments = string.Format(#" arguments ")
psi.CreateNoWindow = true;
psi.ErrorDialog = true;
psi.UseShellExecute = false;
psi.WindowStyle = ProcessWindowStyle.Hidden;
psi.RedirectStandardOutput = true;
psi.RedirectStandardInput = false;
psi.RedirectStandardError = true;
Process exeProcess = Process.Start(psi);
exeProcess.PriorityClass = ProcessPriorityClass.High;
string outString = string.Empty;
exeProcess.OutputDataReceived += (s, e) =>
{
outString += e.Data;
};
exeProcess.BeginOutputReadLine();
string errString = exeProcess.StandardError.ReadToEnd();
Trace.WriteLine(outString);
Trace.TraceError(errString);
exeProcess.WaitForExit();
exeProcess.Close();
exeProcess.Dispose();
FFMPEG might still be rendering the creation of video from images after it closes, so it might be worth if you place a Threading.Thead.Sleep(5000) 5 secs; before delete.
Try that:
File.WriteAllBytes(path, new byte[0]);
File.Delete(path);
http://www.lansweeper.com/ has features that let user do some actions such as Remote Computer management and etc from web application. I need to deploy it in my Asp.Net c# web application. I do it by the code blow when I build my project it works but when I trying to run it from IIS it doesn't works, just nothing happens.
Any help and idea please. No error encountered
protected void lnkComputermanagement_Click(object sender, EventArgs e)
{
try
{
long InfoID = Convert.ToInt64(txtInfoID.Text);
IBAPanel.NetworkSupport.WMIInfo WMIInfo = new IBAPanel.NetworkSupport.WMIInfo();
WMIInfo = WMIInfo.Get(Convert.ToInt32(InfoID));
string ComName = WMIInfo.ComputerName1;
string Pass = WMIInfo.Password;
if (WMIInfo.UserName != "" && WMIInfo.ComputerName1 != "" && WMIInfo.Password != "")
{
string Usname = WMIInfo.UserName.Substring(2);
ProcessStartInfo startInfo = new ProcessStartInfo();
Process myprocess = new Process();
myprocess.StartInfo.CreateNoWindow = true;
myprocess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
myprocess.StartInfo.UseShellExecute = false;
myprocess.StartInfo.Verb = "runas";
myprocess.StartInfo.FileName = "cmd.exe";
myprocess.StartInfo.UserName = Usname;
myprocess.StartInfo.Password = MakeSecureString(Pass);
myprocess.StartInfo.Arguments = "/C mmc.exe compmgmt.msc /computer:" + ComName;
myprocess.Start();
myprocess.Close();
}
Response.Redirect("content.aspx?lan=fa&gid=524&InfoID=" + InfoID);
ActionJquery();
}
catch (Exception ex)
{
System.Text.StringBuilder cstext1 = new System.Text.StringBuilder();
cstext1.Append(" $(document).ready(function () {");
cstext1.Append("alert(" + ex.Message + ") ");
cstext1.Append(" }); ");
Page.ClientScript.RegisterStartupScript(typeof(Page), "", cstext1.ToString(), true);
}
}
You are starting the command "mmc.exe" on the webserver and not on the client browsing the website. If you look at the taskmanager on the webserver you will see multiple mmc.exe processes that are running.
To manage Windows Services from Web you need special permission and you can't go through Services.msc, you need to use WMI (Windows management instruments) and you need to give the application pool higher permission but the best way is to impersionate your piece of code where you fetch for sevices information.
A good open source project with full WMI usage is Services+ on codeplex:
Services+ On CodePlex
Thanks
I tried using the Process class as always but that didn't work. All I am doing is trying to run a Python file like someone double clicked it.
Is it possible?
EDIT:
Sample code:
string pythonScript = #"C:\callme.py";
string workDir = System.IO.Path.GetDirectoryName ( pythonScript );
Process proc = new Process ( );
proc.StartInfo.WorkingDirectory = workDir;
proc.StartInfo.UseShellExecute = true;
proc.StartInfo.FileName = pythonScript;
proc.StartInfo.Arguments = "1, 2, 3";
I don't get any error, but the script isn't run. When I run the script manually, I see the result.
Here's my code for executing a python script from C#, with a redirected standard input and output ( I pass info in via the standard input), copied from an example on the web somewhere. Python location is hard coded as you can see, can refactor.
private static string CallPython(string script, string pyArgs, string workingDirectory, string[] standardInput)
{
ProcessStartInfo startInfo;
Process process;
string ret = "";
try
{
startInfo = new ProcessStartInfo(#"c:\python25\python.exe");
startInfo.WorkingDirectory = workingDirectory;
if (pyArgs.Length != 0)
startInfo.Arguments = script + " " + pyArgs;
else
startInfo.Arguments = script;
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
startInfo.RedirectStandardInput = true;
process = new Process();
process.StartInfo = startInfo;
process.Start();
// write to standard input
foreach (string si in standardInput)
{
process.StandardInput.WriteLine(si);
}
string s;
while ((s = process.StandardError.ReadLine()) != null)
{
ret += s;
throw new System.Exception(ret);
}
while ((s = process.StandardOutput.ReadLine()) != null)
{
ret += s;
}
return ret;
}
catch (System.Exception ex)
{
string problem = ex.Message;
return problem;
}
}
Process.Start should work. if it doesn't, would you post your code and the error you are getting?
You forgot proc.Start() at the end. The code you have should work if you call Start().