Start.Process not run scipt in separate process - c#

I want to run my long runing python script from my console app.
I use
("my_script.py"), when I shut down console also python script is terminate.
In task manager all(console app and script) is runing under .Net Core Host.
How to run python as completly separated process?

Normally, this would start your python script completely outside of your console application:
System.Diagnostics.Process.Start(#"C:\path\to\my_script.py");
In classic .NET it will invoke the process via a new shell, but in .NET Core, the process is created directly inside the existing executable. There is an option to change this, called UseShellExecute. This is directly from the Microsoft documentation:
true if the shell should be used when starting the process; false if the process should be created directly from the executable file. The default is true on .NET Framework apps and false on .NET Core apps.
This is how you can use it:
var myPythonScript = new Process();
myPythonScript.StartInfo.FileName = #"C:\path\to\my_script.py";
myPythonScript.StartInfo.UseShellExecute = true;
myPythonScript.Start();
When your C# console app terminates, your python script should still be running.
EDIT
Thanks to Panagiotis Kanavos, he made me realize the UseShellExecute has nothing to do with the parent/child relationship between the processes. So I setup a sandbox locally with .NET Core and played around with it a bit and this is working for me:
var myPythonScript = new Process();
myPythonScript.StartInfo.FileName = #"C:\path\to\python.exe"; // the actual python installation executable on the server
myPythonScript.StartInfo.Arguments = #"""C:\path\to\my_script.py""";
myPythonScript.StartInfo.CreateNoWindow = true;
myPythonScript.Start();
When the parent app terminates, my python script is still running in the background.

Related

Running a process from jenkins

My console application is responsible for starting a WCF service in interactive mode (ie. the service does not get installed as a Windows service in that case).
In order for my application to start the latter, the application invokes the compiled executable using the following method:
static bool AutoStartService()
{
var MyProcessFile = System.IO.Path.GetFullPath($"pathToExecutable/MyServiceExe.exe");
Process myProcess = new Process();
myProcess.StartInfo.FileName = MyProcessFile;
myProcess.StartInfo.Arguments = "";
myProcess.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
myProcess.Start();
Thread.Sleep(WaitForTheServiceToStart);
}
return true;
}
Note that this approach works just fine when debugging from Visual Studio.
However, when the console application is invoked from Jenkins (note that I gave Jenkins admin access and it logs in as a normal user), then the service process does not seem to stick or be visible from the Console application. I can tell it at least starts and stops as I can see the logs being written to file.
The Console application is started using a batch command from Jenkins (I also tried using Powershell, but without luck).
Any suggestion on how to do that?
I have tried with both debug and release builds of my Console app C# project, but it makes no difference.
EDIT
I have edited the following properties, but without success:
myProcess.StartInfo.UseShellExecute = false;
myProcess.StartInfo.Environment.Add("BUILD_ID", "dontKillMe");
I am now seeing the following warning, but I don't believe installing the service is the only way to go as this is what I am doing when running this code without Jenkins and it works. Maybe Jenkins does not allow it though?:
Cannot start service from the command line or a debugger. A Windows Service must first be installed (using installutil.exe) and then started with the ServerExplorer, Windows Services Administrative tool or the NET START command.
EDIT2
I went a step further. The reason why I was getting the former message is that the service checks "Environment.UserInteractive" to either run as interactive or to start/run the installed service. For some reasons this flag is always set to false, while it should be true in my case.
Is there a way to fool the service to think that flag is true?

Passing in Command Line Arguments to C# .NET app Without Using Manifest File Inside a UWP App

I have a UWP app that I am developing that launches another application, which in turn launches a bat file, which does certain tasks, in order to not block the UI thread, while having enough permissions to do the tasks. The EXE I'm trying to launch is a separate .NET framework app that is in the same SLN, but a different project, in an app package project. However, the second C# app that the UWP app is launching requires command line arguments that may as often as the user of the app decides, so they can't be hard-coded into the manifest file, and using the following command:
await FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync("ArgumentGroupName");
Is there an alternative to the above command that allows for parameters to be passed in, while changing the parameter value is available at every launch? I've googled for days without finding any topic on this apart from one comment on an SO post that I can't find that says that it can be done without using the app's manifest file. I am using the latest version of Visual Studio 2019 with the latest .NET Framework (4.8) and Windows SDK (Windows 2004-compatible). The second C# app runs using the .NET Framework and the main UWP app uses the Windows SDK.
Passing in Command Line Arguments to C# .NET app Without Using Manifest File Inside a UWP App
For your requirement, you could pass the launcher parameter with LocalSettings. Store the parameter in the UWP client and retrieve value from launcher, then call process start with retrieved paramete.
For example
UWP Client
private async void btnClick_Parameters(object sender, RoutedEventArgs e)
{
if (ApiInformation.IsApiContractPresent("Windows.ApplicationModel.FullTrustAppContract", 1, 0))
{
// store command line parameters in local settings
// so the Lancher can retrieve them and pass them on
ApplicationData.Current.LocalSettings.Values["parameters"] = "command parameter";
await FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync("Parameters");
}
}
Launcher
string parameters = ApplicationData.Current.LocalSettings.Values["parameters"] as string;
Process newProcess = Process.Start(rootPath + #"WPF\WPF.exe", parameters);
For more detail please refer stanfen's blog UWP with Desktop Extension – Part 2

"Access denied" error when running a process from a UWP app

Question: In my following case, how can I use allowElevation capability from a UWP app to execute code with elevated privileges on my Windows 10 desktop with the 1809 update. This good article from Stefan Wick explains a similar use of such a capability from UWP app to a WPF app but in my case I'm using a Class Library instead of an exe.
Details: In my UWP project in VS2019, I've added .NET Standard Class Library project. My one UWP method is calling following method of my class library project. But due to Sandbox nature of UWP - as expected - the app is throwing Access denied error at line Process.Start() of the code.
public void Process_Start_Test()
{
using (Process myProcess = new Process())
{
myProcess.StartInfo.UseShellExecute = false;
myProcess.StartInfo.FileName = #"C:\DotNET2019\UWP\TestFolder\MyExeApp.exe";
myProcess.StartInfo.CreateNoWindow = true;
myProcess.Start(); //Access denied error here
}
}
You can't call Process.Start from a .NET Standard library that is referenced by your sandboxed UWP app.
You need to create an actual elevated process (.exe) that calls Process.Start as Stefan's blog post explains.
The full-trust .exe may of course reference your class library where the Process_Start_Test() is defined, but the method has to be called from the full-trust process regardless of whether it's defined in a library.

Process.Start() fails to execute when run as Scheduled Task

I have a .NET console application written in C# (myApp.exe), that runs an external application ('bob.exe'). The console application works great when I run myApp.exe manually. The C# code that calls the application is:
System.Diagnostics.ProcessStartInfo procStartInfo =
new System.Diagnostics.ProcessStartInfo("C:\\bob.exe");
procStartInfo.RedirectStandardOutput = true;
procStartInfo.UseShellExecute = false;
// Do not create the black window.
procStartInfo.CreateNoWindow = true;
// Create the process and assign its ProcessStartInfo and start it
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo = procStartInfo;
proc.Start();
In Windows Server 2003, I created a Scheduled Task that executed 'myApp.exe' on a regular basis. It was set to execute even if the user was not logged in. The Scheduled Task worked and called 'bob.exe' (I was able to verify this by viewing the output files from 'bob.exe')
We then upgraded to Windows Server 2012. I created a Scheduled Task in Windows Server 2012, setting it to execute even if the user was not logged in and configuring it for Windows Server 2003.
I set the Action to call 'C:\myApp.exe', similar to how I had it set up in Windows Server 2003
When the scheduled tasks executes and I am logged in, the 'bob.exe' application is executed from 'myApp.exe'. However, when I am not logged in and the scheduled task executes, 'myApp.exe' is executed but 'bob.exe' is never executed (I can verify this by seeing there are no output files from 'bob.exe'). There are no errors reported by the Scheduled Task and the Last Run Result says "The operation completed successfully. (0x0)".
I found a similar post here but I was unable to resolve my situation. What am I missing?
I had a similar issue with my app calling out 7za.exe to archive db backups. When I ran my app manually it worked fine, but when I scheduled my app via Task Scheduler, the 7z routine would not fire off and didn't give my app a verbose error. I found that adding the directory I ran my app from to the task scheduler's Start in (optional): box corrected my issue.
Program/script: "C:\Program Files (x86)\CustApp\CustApp.exe"
Start in (optional) C:\Program Files (x86)\CustApp\
Note not to use double-quotes on the "Start in (optional)" setting for the directory, it errors when I did.
I had a similar problem with running a Batch file (on WS2008) and the problem was due to the permissions given to the user executing the scheduled task on the folders where the Batch file and the Executable files were set.
I'm not sure if the security of WS 2012 is different, but if I were You I'll try to debug the application (if you have the code) checking for permissions.
HTH

Windbg and viewing AppDomain content

I know we can use !dumpdomain command in winbbg to view the various app domains present in a given managed process(e.g. w3wp).
I wrote a small program(Recipe 3-1 from Visual C# 2010 Recipes A problem solution approach) in LinqPad, to create a custom AppDomain. This is where I am facing issues. I am not able to view this appdomain using windbg. In other words, where is this app domain created ? Is it hosted inside LinqPad process ? If not, then which process is hosting this custom appdomain ?
I tried attaching LinqPad.exe to windbg and issues !dumpdomain command but I got the following error :
Failed to find runtime DLL (clr.dll), 0x80004005 Extension commands
need clr.dll in order to have something to do.
Code :
void Main()
{
AppDomainSetup setUpInfo = new AppDomainSetup();
setUpInfo.ApplicationBase = #"C:\MyRootDirectory";
setUpInfo.ConfigurationFile = "MyApp.config";
setUpInfo.PrivateBinPath = "bin;plugins;external";
AppDomain newDomain = AppDomain.CreateDomain("My New Domain",null,setUpInfo);
Console.WriteLine("Main method complete.Press Enter");
Console.ReadLine();
}
Steps Followed :
Run the program. It waits for the user to press Enter.
Start windbg. Attach LinqPad.exe.
issue commands : .load sos.dll and .load sosex.dll
Issue command .reload
Finally call !dumpdomain. At this point the LinqPad freezes. If I close the windbg, then LinqPad is also closed.
It's created inside the LINQPad process. Your query itself runs in separate AppDomain created by LINQPad. Could the error message be related to a CLR version mismatch? Are you running LINQPad 2.x or 4.x?

Categories

Resources