"Access denied" error when running a process from a UWP app - c#

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.

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

UWP App proc.Start() Unable to Find the File Specified C#

I have been trying to make a UWP app using the latest Windows 10 SDK and the latest version of Visual Studio 2019 that can launch bat files, but whenever I try to launch the bat file using a Process, and error occurs when doing proc.Start(). The error is the following:
System.ComponentModel.Win32Exception: 'The system cannot find the file specified'
Currently, the code is using the ms-appx protocol, but I have tried granting the app filesystem access by editing the app manifest and granting permissions through settings and giving it the full path to no avail. Sometimes, if the full path is specified in one string (and not concatenated), it gives an access denied error, even if the filesystem access is granted to the app and the windows folder can be accessed by Everyone. Using the ms-appx protocol, all I get is The system cannot find the file specified. The error should be self-explanatory, but the same exact code has worked inside of a C# Windows Forms App, but not in the UWP C# app.
Below is my code using the ms-appx protocol:
string InstallPath = "ms-appx:///App/InstallDir"
string batDir = InstallPath + "/Binaries/Win64/";
Proc = new Process();
Proc.StartInfo.WorkingDirectory = batDir;
Proc.StartInfo.FileName = batDir + "Launcher.bat";
Proc.StartInfo.CreateNoWindow = false;
Proc.Start();
The System.Diagnostics.Process.Start() method does not work in UWP. UWP applications much run in a sandbox. For the sake of system stability, the access to other processes is not supported.
You could try to use StorageFolder.GetFileAsync(String) method with a parameter which is the same full path, and the method will return a StorageFile instance. But the same full path used in Process.Start() will cause a Win32Exception.

WPF Using .Net 3.1 - Process.Start Excel File Error: "The specified executable is not a valid application for this OS platform."

I am trying to open an Excel file (.xlsx) within a WPF .NET Core 3.1 app. Using Winforms, I am able to do
process.start("Resources/test.xlsx")
and the file will open.
In the WPF application doing the same thing results in an error
The specified executable is not a valid application for this OS platform
I am using the same code and opening the same file using both apps. Only the Winforms app will work, WPF will throw that error.
Is there a new way of opening files is handled using System.Diagnostics.Process.Start in .Net 3?
Looking around further, it seems that in .Net Core the UseShellExecute value is defaulted to false. Manually setting it to true fixed the issue. Here is the blog article I used to discover this fix: https://jeremybytes.blogspot.com/2019/08/converting-net-framework-to-net-core.html
Something likes this
private void barButtonItem4_ItemClick(object sender, ItemClickEventArgs e)
{
// Old way (.NET Framework 4.8)
// string path = "Resources/test.xlsx";
// Process.Start(path);
// New way (.NET 6)
ProcessStartInfo psInfo = new ProcessStartInfo
{
FileName = "Resources/test.xlsx",
UseShellExecute = true
};
Process.Start(psInfo);
}

Start.Process not run scipt in separate process

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.

Categories

Resources