Open Network And Sharing Center programatically without explorer.exe - c#

Is there a way of opening this from a C# application without needing explorer.exe to be running? I have a Windows 10 IoT device running with a custom shell, but needs to be able allow the user to set up WiFi connections.
I have tried this:
ProcessStartInfo psInfo = new ProcessStartInfo("control.exe", "/name Microsoft.NetworkAndSharingCenter");
However while this works fine when running normally in Windows, when I run it in the custom shell (explorer.exe is not running), nothing happens.
This differs from the Network Connections applet which runs fine even within the custom shell...
ProcessStartInfo psInfo = new ProcessStartInfo("rundll32.exe", "shell32.dll,Control_RunDLL ncpa.cpl");
Is there a way to get rundll32 to run the "Network and Sharing center"? I can't find another .cpl that does it and any research on the 'net just points me back to the original command I tried above.

Related

Console application starting another process environment variables not accessible

I have a VB6 executable which is accessing some system environment variables. I have implemented a .NET console application which checks if those environment variables exist, creates them if needed, and then runs the VB6 application by calling Process.Start.
Doing this, the VB6 application cannot find the environment variables and it says they don't exist.
If I run the VB6 application from Windows Explorer it works fine and can find the variables.
So it seems the VB6 app is running under the context of .NET console app and cannot access the system environment variables!
Code to set the environment vars .NET Cosnole app:
foreach(var varObject in Variables)
{
var envVar = Envrionment.GetEnvironmentVariable(varObject.Name ,
EnvironmentVariableTarget.Machine);
if(string.IsNullOrEmpty(envVar)
{
Environment.SetEnvironmentVariable(varObject.Name,varObject.Value,
EnvironmentVariableTarget.Machine);
}
}
Code to run the VB6 app from .NET Cosnole app:
var processInfo = new ProcessStartInfo(VB6ApplicationFilePath);
processInfo.UseShellExecute = true
processInfo.WindwoStyle= ProcessWindowStyle.Hidden;
Process.Start(processInfo);
A copy of a program's environment is passed to a program that it starts. As it is a copy the second program only sees the state it was in when given it (and changes it made). No other program can change another program's environment.
When using ShellExecute (which you tell ProcessStart to) you are asking Explorer to start the program for you. The program will get a copy of Explorer's environment.
When changing the system environment, programs can send a message to all windows open saying environment has changed (as setx does - see setx /?). But ONLY Explorer.exe pays attention to this message. So only programs started by explorer after explorer receives this message will see the changes.
These are the API calls that .NET calls. In Windows all programs are started by CreateProcessEx (or older programs CreateProcess). Shellexecute and ShellexecuteEx process the command like you typed it in Explorer's Start - Run dialog (Winkey + R) then changes it and calls CreateProcessEx.
At the command prompt. Type
set MyCat=PewResearch
cmd /k echo %MyCat%
We set an environment variable, start a new command prompt that prints that variable.
This is the message that notifies
WM_SETTINGCHANGE
The system sends the WM_SETTINGCHANGE message to all
top-level windows when the SystemParametersInfo function changes a
system-wide setting or when policy settings have changed.
Applications should send WM_SETTINGCHANGE to all top-level windows
when they make changes to system parameters. (This message cannot be
sent directly to a window.) To send the WM_SETTINGCHANGE message to
all top-level windows, use the SendMessageTimeout function with the
hwnd parameter set to HWND_BROADCAST.

Process.Start won't work

I am trying to launch a process from a web page's back-end code/app pool. This process will launch an App that i built myself.
For some reason, the process only works / runs when i start it from VS2013... it never works when i launch it from IIS(7.5) itself.
I am on a Windows 7 machine (both IIS host, and App location), and I've setup my web site to only be accessible via internal network.
Here's the code, followed by the config / attempts to fix the issue:
protected void btn_DoIt_Click(object sender, EventArgs e)
{
string file_text = this.txt_Urls.Text;
if (!String.IsNullOrWhiteSpace(file_text))
File.WriteAllText(ConfigurationManager.AppSettings["filePath"], file_text);
ProcessStartInfo inf = new ProcessStartInfo();
SecureString ss = GetSecureString("SomePassword");
inf.FileName = #"........\bin\Release\SomeExecutable.exe";
inf.Arguments = ConfigurationManager.AppSettings["filePath"];
inf.UserName = "SomeUserName";
inf.Password = ss;
inf.UseShellExecute = false;
//launch desktop app, but don't close it in case we want to see the results!
try
{
Process.Start(inf);
}
catch(Exception ex)
{
this.txt_Urls.Text = ex.Message;
}
this.txt_Urls.Enabled = false;
this.btn_DoIt.Enabled = false;
this.txt_Urls.Text = "Entries received and process started. Check local machine for status update, or use refresh below.";
}
Here are the things I've tried to resolve the issue:
Made sure the executing assembly was built with AnyCPU instead of
x86
Ensured that the AppPool that runs the app, also runs under the same account (SomeUsername) as the ProcessStartInfo specified.
Ensured that the specific user account has full access to the executable's folder.
Ensured that IIS_USR has full access to the executable's folder.
Restarted both the app pool and IIS itself many times over implementing these fixes
I am now at a loss as to why this simply will not launch the app... when i first looked into the event log, i saw that the app would die immediately with code 1000:KERNELBASE.dll, which got me on the AnyCPU config instead of X86 fix... that fixed the event log entries but the app still doesn't start (nothing comes up in task manager), and i get no errors in the event log...
if someone could help me fix this problem i would really appreciate it. This would allow me to perform specific tasks on my main computer from any device on my network (phone, tablet, laptop, etc etc) without having to be in front of my main PC...
UPDATE
The comment to my OP, and ultimate answer from #Bradley Uffner actually nailed the problem on the head: My "app" is actually a desktop application with a UI, and in order to run that application, IIS would need to be able to get access to the desktop and the UI, just like if it were a person sitting down in front of the PC. This of course is not the case since IIS is running only as a service account and it makes sense that it shouldn't be launching UI programs in the background. Also see his answer for one way of getting around this.
Your best bet might be to try writing this as 2 parts. A web site that posts commands to a text file (or database, or some other persistent storage), and a desktop application that periodically polls that file (database, etc) for changes and executes those commands. You could write out the entire command line, including exe path command arguments, and switches.
This is the only way I can really think of to allow a service application like IIS to execute applications that require a desktop context with a logged in user.
You should assign a technical user with enough high priviliges to the running application pool. By default the application pool is running with ApplicationPoolIdentity identy which has a very low priviliges.

Invoke console app from windows service

I have a simple windows service which i need to use to invoke a console application.The console app generates pdf to print by opening the adobe reader window.Running the console app works fine to print pdf.But invoking it from service not successful.It doesnt even show up the console window where i log events.
Process pdfprocess = new Process();
pdfprocess.StartInfo.FileName = #"C:\Documents and Settings\xyz\Desktop\dgdfg\PdfReportGeneration\bin\Debug\PdfReportGeneration.exe";
pdfprocess.StartInfo.UseShellExecute = false;
pdfprocess.StartInfo.RedirectStandardOutput = true;
pdfprocess.Start();
But invoking other application like
pdfprocess.StartInfo.FileName = #"C:\Program Files\Adobe\Reader 11.0\Reader\AcroRd32.exe";
works fine.
What will be the reason?
There is probably some permissions issue there (PdfReportGeneration.exe inaccessible under service account or maybe something that it uses...)
I would advise to capture Process Monitor log to see where exactly it fails.
Windows services run in a different window station and cannot interact with the desktop, unless you're using an older version of Windows and tick a checkbox in the service properties in the service manager.

c# Open IE From Scheduled Task

I have a c# console application that I want to run from task scheduler that has 2 main functions: 1) Closes all Internet Explorer processes; and 2) Restarts Internet Explorer and loads the appropriate website.
The console app does exactly what it is supposed to do if run from the command line, but fails if executed from Task Scheduler.
The app is designed to run on the client computer the only function of which is to load a single website and broadcast the website to our internal TV Channel 195. We have connection issues with our ISP and while the connection issue is usually temporary, Internet explorer needs to be restarted to re-show the website.
I want to set it up to run multiple times each day to eliminate any possible connection issues between the web server and the client.
private static void StartExplorer()
{
Process _process;
ProcessStartInfo psi = new ProcessStartInfo
{
FileName = "iexplore.exe",
Arguments = "-noframemerging -private -k \"http://tv.TheelmAtClark.Com\""
};
try{
_process = Process.Start(psi);
}
catch(Exception Ex)
{
Console.WriteLine(Ex.ToString());
}
}
Is it possible to run the app using task scheduler?
I would recommend that you look at alternative approaches, if possible.
A Firefox plugin like Reload Every is designed to do just this. I use this in our to project to a big screen TV.
However, if you are keen on doing this via Internet explorer, again there are two approaches
1) Something similar to the Firefox plugin I mentioned above - Autorefresher for IE
2) If you insist on having a task scheduler, as you mentioned above, here is how I think you can do it-
To kill all Internet Explorer instances, use PSKill. Invoke it via Process.Start with arguments to kill Internet Explorer.
To launch a new instance, try invoking Process.Start with UseShellExecute=true.

Printing by executing a process in a Windows Service

I have a Windows Service that needs to start a process to send a file to the printer (I found that solution there https://stackoverflow.com/a/4875755/1228738) . I do this using the Process.Start().
My problem is that nothing happens.
The service is actually installed on my developer machine (win7, x64). I tried installing it as LOCAL SYSTEM, NETWORK SERVICE, LOCAL SERVICE with the same result every time.
I tried those way of starting my process :
Process p = new Process();
p.StartInfo.FileName = "C:\\Program Files (x86)\\Foxit Software\\Foxit Reader\\Foxit Reader.exe";
p.StartInfo.Arguments = "-p myFile.pdf";
p.Start();
and
Process.Start("C:\\Program Files (x86)\\Foxit Software\\Foxit Reader\\Foxit Reader.exe", "-p myFile.pdf");
and also
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = "C:\\Program Files (x86)\\Foxit Software\\Foxit Reader\\Foxit Reader.exe";
startInfo.Arguments = "-p myFile.pdf";
Process.Start(startInfo);
When I execute the same code in a winform application, everything works fine, the file is sent to the printer. But in the Windows Service, nothing happens.
I saw that post https://stackoverflow.com/a/6271309/1228738, which explains why I would not see the UI, that's fine I don't have any UI anyway. But as said in the comment section, a process with no user input should be OK. The process that I start don't need any user input.
The only thing I can think of right now, is that because of session isolation (https://stackoverflow.com/a/5063750/1228738), the service can't find any installed printers... Can that be the case ? If so, any suggestion how to work around that ? And if not, any idea of what's wrong ?
Thanks!
EDIT #1
I tried running the service with my user account, and it's working, so I guess my fears are confirmed... the users LOCAL SYSTEM and NETWORK SERVICE have no installed printers.
So I'll refine my question a little bit. Is there a way for those account to access printers installed on the computer ?
EDIT #2
We finally decided that a user will be created for running that service and in that user accounts we'll install the printer on which to print.
I guess this question can be closed now.
Thank you all for your help.
I had this issue too, this trick solved it
Go to services ---> Double click the required service ---> proceed to logon tab
Supply the Log-in credentials from which printer was installed.
Run your service, then check the printer queue.
Reason: Local system account does not have those printer installed !
See screen shot below.
Check out this MSDN Page: http://support.microsoft.com/kb/324565
According to this page, you cannot print from ASP.NET pages or Windows services using .NET.
The solution here is tho share your local printer and call Foxit with
-/t yourfile.pdf \\localhost\YourSharedPrinter
That way your service does not need an UserProfile and no DefaultPrinter.

Categories