writing environment variable and reading it from the same process - c#

I am trying to set environment variable from a console application by executing it from my windows application. I invoke console application and send the value of environment variable as parameter to it, then set the thread to wait for 10 seconds to proceed with next execution.
In the next step i try to load a new .exe which reads the value set to the environment variable.
The exe will not read the new value and continue to refer the value set earlier.
Once the solution of application is closed and open then it reads the new value i.e reload the vshost.

betting you set up the variable only for the current process. You should try this overload of the Environment.SetEnvironmentVariable method :
Environment.SetEnvironmentVariable("YourVar", "YourValue",
EnvironmentVariableTarget.User);
[Edit] Re-Reading your question, you said in the title "same process", and in the question "new exe". In term of Env varialble, spanning a new process implies a new process scope for env variables. They won't share env variables with process scope just because it's the same executable. Maybe you should explain what you are trying to do at a higher level.
[Edit2] not sure to understand why it fails... But you can specify env variable when spawning process using a ProcessStartInfo.EnvironmentVariables Property
Basically, it can be (not tested) :
var psi = new ProcessStartInfo {
FileName="yourExe"
};
psi.EnvironmentVariables.Add("YourVariable","YourValue");
var process = Process.Start(psi);

Related

pyinstaller .exe works locally but fails when called by C#?

I have created a script using Python2.7 and compiled it using pyinstaller into an exe of the same name, in this case "GeneralStats.py" turns into "GeneralStats.exe" using --onefile and -w arguments.
When called with C# I use:
var pythonDirectory = (Directory.GetCurrentDirectory());
var filePathExe1 = Path.Combine(pythonDirectory + "\\Python\\GeneralStats.exe");
Process.Start(filePathExe1);
When called outside of C#, so in my local files I can run the .exe and the result is a text file with lots of values in (Running correctly).
However, when ran with C# in this format, I get an error that "GeneralStats returned -1!"
Which I have had issues with before, but it was a simple python error that when I returned to my code and ran it, I would receive an error that I overlooked.
This time my python code returns no errors and works outside of C#.
Any ideas of why this could be? I can provide any code or file directories necessary, please just ask if you feel it would help with debugging.
EDIT:
Solved by removing:
var filePathExe1 = Path.Combine(pythonDirectory + "\\Python\\GeneralStats.exe");
Process.Start(filePathExe1);
And replacing with:
ProcessStartInfo _processStartInfo = new ProcessStartInfo();
_processStartInfo.WorkingDirectory = Path.Combine(pythonDirectory + "\\Python");
_processStartInfo.FileName = #"GeneralStats.exe";
_processStartInfo.CreateNoWindow = true;
Process myProcess = Process.Start(_processStartInfo);
You need to set the working directory for the Process - it is probably trying to load files from its working directory but isn't finding them.
See, e.g. this:
Use the ProcessStartInfo.WorkingDirectory property to set it prior to starting the process. If the property is not set, the default working directory is %SYSTEMROOT%\system32.
Set it to the path where GeneralStats.exe is.

C# Environment variable value doesn't get added [duplicate]

This question already has an answer here:
How to set system environment variable in C#?
(1 answer)
Closed 7 years ago.
I'm trying to add a value to the Path environment variable, but I can't seem to get it to work. I've went through a couple of similar questions and I'm pretty sure I have exactly the same code, but still it won't add the variable or I can't see it. I've checked both the administrator and local user account for changes. I've checked both during and after the running (debugging) of the application. I've also close VS2013 completely and checked.
Here's the code I'm using
string path = #"C:\Users\bono\Documents\Visual Studio 2013\Projects\3D-Scanner\AddEnviromentToPath\bin\Debug\AddEnviromentToPath.exe";
ProcessStartInfo process_start_info = new ProcessStartInfo();
process_start_info.FileName = path;
process_start_info.Verb = "runas";
process_start_info.WindowStyle = ProcessWindowStyle.Normal;
process_start_info.UseShellExecute = true;
process_start_info.Arguments = PATH_TO_PCL;
Process.Start(process_start_info); //Process that handles the adding of the value
AddEnviromentToPath program:
class Program {
static void Main(string[] args) {
//Just to make sure we're adding both
AddToEnvironmentPath(args[0], EnvironmentVariableTarget.User);
AddToEnvironmentPath(args[0], EnvironmentVariableTarget.Machine);
}
static void AddToEnvironmentPath(string pathComponent, EnvironmentVariableTarget target) {
string targetPath = System.Environment.GetEnvironmentVariable("Path", target) ?? string.Empty;
if (!string.IsNullOrEmpty(targetPath) && !targetPath.EndsWith(";")) {
targetPath = targetPath + ';';
}
targetPath = targetPath + pathComponent;
Environment.SetEnvironmentVariable("Path", targetPath, target);
}
}
Note that I'm running VS2013 and the main application as a standard user. When the AddEnviromentToPath program runs I get an admin verification panel. I log in here with an admin account.
Edit:
Other people seem to get it working with basically the same code:
How do I get and set Environment variables in C#?
Environment is not being set in windows using c#. Where am I going wrong?
Assuming that Environment.SetEnvironmentVariable calls the Win32 SetEnvironmentVariable function behind the scenes, this note is probably applicable:
Sets the contents of the specified environment variable for the
current process
...
This function has no effect on the system
environment variables or the environment variables of other processes.
If you want to change a global environment variable and have existing processes notice it, you need to:
Save it to the registry under HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
Notify existing processes of the change with the WM_SETTINGCHANGE message.
See the MSDN Environment Variables documentation for more information.
ProcessStartInfo to the rescue!
You need to check this documentation out:
https://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.environmentvariables%28v=vs.110%29.aspx
The key text which addresses your concerns:
Although you cannot set the EnvironmentVariables property, you can
modify the StringDictionary returned by the property.

environmental variable in a c#

I am using the following command to set a value to the environmental variable in a c# Console application.
System.Environment.SetEnvironmentVariable(envvar, result,EnvironmentVariableTarget.Process);
After running the application in the command window, when I try to echo that variable ,I cannot see the value.
I have to use this application in a batch file.
I want the functionality like SET command. Please help..
Edit:
I tried using System.Environment.SetEnvironmentVariable(envvar,result,EnvironmentVariableTarget.user) and to propagate the change I tried this Propagating Change in Env VAr. But I cant echo the variable in same command window.
Let me rephrase the question:
I want to set a value to a Env Var in c#. I must be able to use that variable in same command window (ie i should not open a new cmd window to see the change). We use SET command and we can use that variable immediately .. rt ? I want such functionality. Plzz help
When you use EnvironmentVariableTarget.Process the variable set will only visible in the current process as you can see in this sample:
System.Environment.SetEnvironmentVariable("myVar", "myValue", EnvironmentVariableTarget.Process);
string s = System.Environment.GetEnvironmentVariable("myVar",EnvironmentVariableTarget.Process);
Above myVar will show s = "myValue" but not visible in command window.
If you want to set the value visible at command windows then you need to use EnvironmentVariableTarget.User:
System.Environment.SetEnvironmentVariable("myVar", "myValue", EnvironmentVariableTarget.User);
This way the setting myVar=myValue will be stored and then you can see on command windows.
A detailed sample is located here
In order to see the env in the current batch process. You have to output it in you program as string and parse it and call set in the batch file.
Or you can try EnvironmentVariableTarget.User. The env will be visible in all new processes when setted with this option.

How can I set the AppData folder for a new process?

I would like to start a new process but I need it to use a different folder for AppData. In a windows batch file you can do it like this:
set APPDATA=C:\MyDataFolder
It will set the AppData for any program launched in the batch file, so how can I do this in C#?
You can add environment variables to the ProcessStartInfo:
ProcessStartInfo p = new ProcessStartInfo("some_executable.exe");
p.UseShellExecute = false; // apparently required when adding environment variables
p.EnvironmentVariables.Add("APPDATA", #"C:\MyDataFolder");
Process.Start(p);
Off the top of my head: Environment.SetEnvironmentVariable
According to MSDN:
Creates, modifies, or deletes an environment variable stored in the
current process.
Current process being the operative word...

Starting time of a process

How do I retrieve the starting time of a process using c# code? I'd also like to know how to do it with the functionality built into Widows, if possible.
public DateTime GetProcessStartTime(string processName)
{
Process[] p = Process.GetProcessesByName(processName);
if (p.Length <= 0) throw new Exception("Process not found!");
return p[0].StartTime;
}
If you know the ID of the process, you can use Process.GetProcessById(int processId). Additionaly if the process is on a different machine on the network, for both GetProcessesByName() and GetProcessById() you can specify the machine name as the second paramter.
To get the process name, make sure the app is running. Then go to task manager on the Applications tab, right click on your app and select Go to process. In the processes tab you'll see your process name highlighted. Use the name before .exe in the c# code. For e.g. a windows forms app will be listed as "myform.vshost.exe". In the code you should say
Process.GetProcessesByName("myform.vshost");
Process has a property "StartTime":
http://msdn.microsoft.com/en-us/library/system.diagnostics.process.starttime.aspx
Do you want the start time of the "current" process? Process.GetCurrentProcess will give you that:
http://msdn.microsoft.com/en-us/library/system.diagnostics.process.getcurrentprocess.aspx
In Code
Suppose you want to find the start time of Notepad, currently running with PID 4548. You can find it, using the PID or the process name, and print it to the debug window like this:
//pick one of the following two declarations
var procStartTime = System.Diagnostics.Process.GetProcessById(4548).StartTime;
var procStartTime = System.Diagnostics.Process.GetProcessesByName("notepad").FirstOrDefault().StartTime;
System.Diagnostics.Debug.WriteLine(procStartTime.ToLongTimeString());
In Windows
You can use Process Explorer, which has an option to display the process start time, or you can list all the currently running processes, and their start times, from the command line with the following:
wmic process get caption,creationdate
You can get process metadata by inspecting the Process object returned by Process.GetProcessesByName().
System.Diagnostics.Process.GetProcessById(xxx).StartTime;//fails for certain processes with access denied

Categories