Add environment variables in UWP with FullTrustProcessLauncher - c#

I am trying to create environment variables in Windows through a UWP application using the SetEnvironmentVariable method, but it seems that UWP as it runs in a sandbox prevents the application from being able to create environment variables.
So I have created a console app to call it from UWP:
var value = Environment.GetEnvironmentVariable("Test1", EnvironmentVariableTarget.User);
if (value == null)
{
var path = "pathTest";
Environment.SetEnvironmentVariable("Test1", path, EnvironmentVariableTarget.User);
Console.WriteLine("The environment variable has been created successfully");
}
else
{
Console.WriteLine("Environment variable already exists");
}
UWP code to run the console application that I have added in the application package:
public class TestService : ITestService
{
public async Task ExecuteSampleApp()
{
await FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync();
}
}
and I have added the .exe in the same UWP application package, and I have added the necessary permissions (runFullTrust) in the Package.appxmanifest to be able to run external applications (that are in the application package), up to this point everything is fine , I can run the console app from my UWP app but it seems that the console app when run from the UWP app can't create the environment variable it's like access is taken away (I think somehow the app sandbox UWP adds the same security restrictions even to the .exe added in the application package), however if I run the same console application in the bin folder that is created when compiling the UWP app it works, the problem occurs only when the UWP app calls the .exe. Anyone have any other ideas on how I could create environment variables in UWP either with this approach I was following or with another?
And with this console app, would it be possible to run cmd commands bypassing the UWP sandbox security restrictions?
Answer to #RoyLi-MSFT:
No, there are no exceptions, the UWP application executes the console application and it shows the message "Environment variable already exists" detecting as if it already exists, however it has not created it at any time, it seems that the console application when it is executed by the UWP app it is not able to really obtain if the environment variable exists or not in the operating system and it returns an incorrect state (indicating that it exists when it does not). However, if the console application is run regardless, it does work, which suggests that it is a UWP problem that somehow isolates the console application to the same sandbox as the UWP app when it is executed by the UWP app. Regarding your other question with placing the exe file in the application package, I mean that I add in the Assets folder the console application in charge of registering the environment variables to be able to execute it with FullTrustProcessLauncher through UWP since it is the only way of running a win32 app from a sandbox environment.
2º Answer to #RoyLi-MSFT:
I use EnvironmentVariableTarget.User in my code, the code I had put here was an example (I have updated the example to clarify it), but I tried to use the 3 available enumerations: Process, User and Machine, the User type is the one that works correctly and is the one that I use in my console application, but as I mentioned before, when the UWP application is the one running the console application it cannot create the environment variable and the console shows: "The environment variable already exists" despite using EnvironmentVariableTarget.User.
I clarify this point: when the console application is run manually if it works, it only shows the message "The environment variable already exists" when the UWP application is in charge of executing it with FullTrustProcessLauncher.

Based on the document-SetEnvironmentVariable(String, String), the Environment Variable you created is stored in the current process, which means the process environment block. I tested your code inside of a console app. Every time when I launched the console app, it shows The environment variable has been created successfully. If I tried to read the value after I write it, I could get the correct value. This behavior matches the document.
So the behavior you mentioned should be expected. You could try directly read the Environment Variable when you haven't closed the console app and you should be able to get the value you set. And #jerry's comment should make sense, you might need to try SetEnvironmentVariable(String, String, EnvironmentVariableTarget) with other options like EnvironmentVariableTarget.User.
Update:
Based on your previous comment, you mentioned that you put the .exe file in the Assets folder of your UWP app. I would suggest you using the Windows Application Package Project to package the console app together with the UWP app. In that way under my test, the console app will correctly add the Environment Variable to the current user block and you could get it as you want.
Here are the steps:
Create a new console app under the solution of your UWP app. Add the code you need.
Create a Windows Application Package Project, and add the console app and the UWP as application reference to the Package Project.
Declare the extension in the package manifest of the Package Project
launch it from the UWP app.
You could refer Stafen's blog for more details.
And the result:

In the end I managed to create the environment variables. Through the UWP application we have to execute the console application and through the console application execute the CMD setx command through the Process class, this is the code:
Process cmd = new Process();
cmd.StartInfo.FileName = "cmd.exe";
cmd.StartInfo.RedirectStandardInput = true;
cmd.StartInfo.RedirectStandardOutput = true;
cmd.StartInfo.CreateNoWindow = true;
cmd.StartInfo.UseShellExecute = false;
cmd.Start();
var testPath = "c:\...";
cmd.StandardInput.WriteLine(#"setx testName + " \"" + testPath + "\"");
And with this we manage to bypass the restrictions that UWP has in the sandbox in which the applications are executed:

Related

How to make autorun in C# when registry doesnt work

I can see the app in registers but it wont startup.
RegistryKey rkApp = Registry.CurrentUser.OpenSubKey(#"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true); // Add the value in the registry so that the application runs at startup
rkApp.SetValue("WindowsSelfRepairTool", System.Reflection.Assembly.GetEntryAssembly().Location);
This is the code I copied from internet, it gets my application to registers because I can see it "On startup" in task manager as well as in the registry editor. But for some reason, when I restart the computer the app wont start.
Also I tried this code in Console App and added code Process.Launch("..") to launch the WPF one. Console starts successfuly but it doesnt run the WPF.. Any help?

How to pass command to termux using dotnet? [duplicate]

I am working on automating the process of launching the dependencies for an android project.
One of the dependencies is launching Termux (Installed through F-Droid not Play store as recommended).
I am trying to launch the installed Termux application through another application and add some commands to its ~./bashrc file for the sake of automation.
I know that an installed app can be launched trough another android app (more details are here).
I wonder to know if this is possible for Termux as well? I wonder to know if we can use intent concept to launch Termux from an android app as well? If yes what is the Termux package name?
I tried using "com.termux" as its packagename in my sample code, but it did not work.
In other words, the following line returns null:
Intent launchIntent = getPackageManager().getLaunchIntentForPackage("com.termux");
Updated:
I can open another installed app (the app that I developed and installed its apk file on tablet) using Intent concept as shown above (by replacing the appropriate package name instead of termux package name).
Note:
I have installed the Termux through F-Drioid not google play store.
New observation:
I confirmed through Package names application the Termux package name is "com.termux" and its activity class name is also "com.termux.app.termuxActivity"
But seems like the "com.termux" is not accessible through package manager. When i try to pass "com.termux" to the following function it returns false.
Any idea or suggestion?
public boolean isPackageExisted(String targetPackage){
enter code here
PackageManager pm=getPackageManager();
try {
PackageInfo info=pm.getPackageInfo(targetPackage,PackageManager.GET_META_DATA);
} catch (PackageManager.NameNotFoundException e) {
return false;
}
return true;
}
Add com.termux to queries element or declare QUERY_ALL_PACKAGES permission in AndroidManifest.xml if targetSdkVersion is 30+. Check Package Visibility or this article for more info. Otherwise, you will will get PackageSetting{...... com.termux/......} BLOCKED errors in logcat.
<manifest
<queries>
<package android:name="com.termux" />
</queries>
</manifest>
Moreover, you can run commands in termux via RUN_COMMAND intent. The termux-shared lib is published on jitpack since v0.116, check Termux Libraries for import instructions.
Moreover, activity name is com.termux.app.TermuxActivity.

How to stop installing app every time when tests run in xamarine.uitest

I am new to mobile testing and working to test a native app using Xamarine.UITest on an android in which I am executing multiple BDD scenarios . Every time I run tests it installs the app again and I lose the data created by previous scenarios. How can I stop installation of app when app is already installed and check if installed skip installation and just launch the app. Below is the piece of code which I am using to install the app and return IApp. Thanks for looking into it.
public static IApp StartApp(Platform platform)
{
if (platform == Settings.Platform)
{
return ConfigureApp
.Android
.InstalledApp(Settings.AUTPackageName)
.StartApp();
}
return ConfigureApp
.iOS
.StartApp();
}
So I've run into the other side of this -- I have some different run behavior on first load, so I want to force it to install clean sometimes.
What I've found is that Android and iOS devices have different behavior on this. With Android, using the InstalledApp will always rebuild the application, it will check against the installed version and install the new build if different. Loss or caching of data is effected by the AppDataMode.
So, if the issue is the building of the application, because it can be slow on a slow machine, I'd suggest looking at using a pre-built APK file to run the tests, using .ApkFile("") instead of .InstalledApp.
If the concern is the loss of data (which is more what your question sounds like), then you should do something like:
{
_app = ConfigureApp
.Android
.InstalledApp(Settings.AUTPackageName)
.StartApp(AppDataMode.DoNotClear);
}
iOS is a different beast, but I think you're looking at Android specifically here.

Unable to delete .exe file through c#

I have an update button within the windows form application.When the user clicks on the update button, the application checks the current version of the application with the version available in the server obtained from the webservice. If there is mismatch among versions,the application will download the new version from the path obtained from the webservice.
I am currently using two projects within the same solution
Main project where the application is running
Update project -Its purpose is used to delete the .exe file and download the new .exe file. (Update project is added as a reference of Main project)
The problem is when i try to delete the mainproject.exe through code in update project,it shows an exception saying "Unauthorized exception caught". Does anyone knows why this is happening?OR Does anyone have a better idea to use update function within the application??
This is the code that i am using for the deleting the file.
Unauthorized Exception in Windows Forms - C#
Edit:-
While i was debugging the application,iam able to delete the .exe file.But when i try to delete the application after installing in the desktop,again iam getting the exception message as "Access is denied".
In you update button, you start another small app as a separate process , in the small app, you can use the following code to kill your process, and then delete the original app.
try
{
Process [] proc Process.GetProcessesByName("YourAppName");
proc[0].Kill();
}
I found the solution why iam getting the "access is denied" exception in my application.
Since iam deleting a file inside the application through code i need to have the privilege of "Administrator".
One way is to make the user login manually as administrator.But that is not a better option.
Another way is to create an App Manifest file within your project and set the level as "administartor."
Creating App Manifest--> Right click on the project->Add new item-->Select App Manifest option from the right pane->Click ok
Open the manifest file and change the level to "requireAdministartor".
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
This will solve the issue while running the application,it will prompt user to run as administrator.
Hope this will be helpful to someone in future. :) Thank you guys for your support.
Is the application running and that's why it is unable to delete the executable? If so, you could rename the running executable and put the new version in its place. The new version will then be executed the next time the application is started.

How To Run And Test a Windows Services In VS

I created a windows service in VS:File->New Project->C#->Windows Services
But I don't know how to run and test it.VS says I have to install my windows services to run it.but I Just want to test it and I don't want to install it.Can anybody Help me???
To debug your Windows service, add the following in your Main():
if (!Environment.UserInteractive) {
// We are not in debug mode, startup as service
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[] { new MyServer() };
ServiceBase.Run(ServicesToRun);
} else {
// We are in debug mode, startup as application
MyServer service = new MyServer();
service.StartService();
System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);
}
And the following method in your class MyServer:
public void StartService() {
this.OnStart(new string[0]);
}
Now hit F5 to debug, as any winform or console application.
When creating a Windows Service I usually put all functionality into a separate class library... for testing I create a "normal app" which makes use of the class library...
AFTER the functionality is tested and the bugs are gone I do build/install the Windows Service... there can be problems specific to Windows Service like permissions etc. - these need to be addressed accordingly (some logging is usually very helpful).
Debugging a Windows Service with VS is a bit different from debugging an application - for details see http://msdn.microsoft.com/en-us/library/7a50syb3.aspx
A windows service is not really a normal executable, it builds as exe but has to be installed and started with Services icon from Control Panel.
Once you got it installed and started you can use Visual Studio Debug menu, Attach to process and attach to the service to debug it, not the simplest and fastest way to debug because if you need to change anything you have to build it again and install it again, start and attach again.
Usually a nice approach is to anyway split and isolate the logic of the service in a class library (probably the service business logic) which can be used also from let's say a console application.
At this point you create a test console application which calls some methods and behaves kind of like the service from the Main method and you test and debug this one.
Once everything has been tested and verified and you are satisfied with the results you copy the code you have put in the Main method of the test console application in the Service class, probably in the OnStart method or similar, details depend on your specific design.
we do this also to debug and test WCF services which are hosted in a test console app during development and in a Windows Service in production.
you should use visual studio command prompt with the following command:
installutil "the path of the exe"
and the go to Services (start-> run-> services.msc) you will find the service. click on start and you're done.
P.S: to debug your service in vs: tools-> attach to process and find your service in the list)
You cannot debug service directly from VS. Need to attach the debugger to Windows Service.
To do it, in VS do following:
From the Debug menu, select Attach To Process…
Near the bottom of the window, select Show processes in all sessions.
Left-click the compiled EXE to be run as the Windows Service in the list. Press Attach.
Result: you can place breakpoints at places in your functions, and you'll be able to debug the service execution.

Categories

Resources