Unable to load executable - c#

I'm attempting to create a service which opens an application, however I have had no luck. Thus, I downloaded the following sample code, and attempted to create a service based on it. However, it does not work either. What happens is that the code executes, however the executable is never called (in the following case, the calculator is not opened).
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
namespace Open_Calculator
{
public partial class Service1 : ServiceBase
{
public static Process process;
public Service1()
{
//InitializeComponent();
string[] args = { "1", "2" };
OnStart(args);
}
protected override void OnStart(string[] args)
{
start_calc();
}
protected override void OnStop()
{
}
static protected void start_calc()
{
process = new Process();
process.StartInfo.FileName = #"C:\Windows\system32\calc.exe";
process.StartInfo.CreateNoWindow = true;
process.StartInfo.ErrorDialog = false;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.UseShellExecute = false;
process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
process.Start();
}
}
}
The same exact code copy-pasted in a console application works.
The service is set to interact with the desktop, and it is set to run as "LocalSystem".
The account running the service does have access to C:\Windows\System32 as I tested it. Process.Start() does not return any errors, and calc is not running in the background (checked through task manager)

Execute it with "Run as administrator" permission

This question has been the cause of great frustration, and I have finally solved my problem. Yes, I have managed to make a service load a GUI application, even though everyone says that it is impossible. There is a warning though - the "fix" can be considered as exploiting a loophole in Windows, as the code which I used basically passes the Vista and Windows 7 UAC. Essentially, the application is always executed with full rights and bypasses the UAC.
If anyone has this same problem, what you need to do is iterate through a list of logged in users on the PC, and choose to open the UI application in this session (which has the user's desktop), rather than in session 0 where the service is supposed to be running (and which does not have a desktop).
For some people, this might not be a solution as it is not secure. But in my case, security is not a main concern, and I just needed it to work (had to be a service by force).
Hope this helps anyone who has the same problem that I had.

Related

Running an application from my program does not launch it the same way as when double clicking manually

To launch an application from my C# program, I have tried the solutions listed in the thread at the following link : Launching an application (.EXE) from C#? .
I am facing a puzzling situation : no new window shows during the time my program runs, so I opened the processes list hoping to get more info. Here is what happens : when I double click my executable (case 1 : not using the code to execute the app), 5 different processes bearing the same name but different PIDs are raised and if I close the app, all of them shut down too so here I assume that all of these should run for my app to launch correctly; on the other hand, whenever I use the program to launch the app, only one process is initiated and no window is displayed (this is not a matter of ProcessStartInfo since I made sure to change the parameters so that a new window is displayed if needed). Any idea as to why there are two different behaviors depending on whether I "double click" manually or launch through a C# instruction ? If it is an "argument matter" is there a way for me to get more intelligence about the arguments that are implicitly used when I double click (and do not provide with my script as for now) ?
Thanks !
Appendix :
C# code :
using System;
using System.Diagnostics;
using System.IO;
namespace GradeBook
{
class Program
{
static void Main(string[] args)
{
ProcessStartInfo start = new ProcessStartInfo();
start.Arguments = "";
Directory.SetCurrentDirectory("C:\\Users\\sthg\\AppData\\Local\\Programs\\sthg");
start.FileName = "myApp.exe";
start.WindowStyle = ProcessWindowStyle.Normal;
start.CreateNoWindow = false;
int exitCode;
using (Process proc = Process.Start(start))
{
proc.WaitForExit();
exitCode = proc.ExitCode;
}
}
}
}

How to run Outlook using Process.Start("outlook.exe") and get the control back

My C# program needs to launch Office Outlook and get the current "running outlook application".
In order to do that I've implemented the following simple program (so if you want you can test it simply):
using Outlook = Microsoft.Office.Interop.Outlook;
using System.Runtime.InteropServices;
static void Main(string[] args)
{
Outlook.Application outlookObj = null;
if (Process.GetProcessesByName("OUTLOOK").Count().Equals(0))
{
Process.Start("outlook.exe"); // MY PROGRAM STOPS HERE
}
var process = Process.GetProcessesByName("OUTLOOK").First();
while (!process.HasExited)
{
try
{
outlookObj = (Outlook.Application)Marshal.GetActiveObject("Outlook.Application");
break;
}
catch
{
outlookObj = null;
}
System.Threading.Thread.Sleep(10);
}
string result = (outlookObj== null)? "DOES NOT WORK" : "OK";
Console.WriteLine(result);
Console.ReadLine();
}
My problem is that once Office Outlook starts running then my C# console application does not continue its job. After the Process.Start("outlook.exe"); instruction is executed then I must click on Visual Studio GUI in order to restart the console application and finally read "OK" on my console application.
How can I solve my problem?
Microsoft wrote a example about how to log into a outlook instance. Although this is directly what you asked for in your question, the example contains how to start a new outlook application in the intended way
application = new Outlook.Application();
as a side note: in your example you use the following code:
while (!process.HasExited)
{
try
{
outlookObj = (Outlook.Application)Marshal.GetActiveObject("Outlook.Application");
break;
}
catch
{
outlookObj = null;
}
System.Threading.Thread.Sleep(10);
}
This is bad practice in your main thread as your applying 'busy waiting' by using the thread.sleep. This means you will 1. use CPU power while your application is doing nothing. 2. make your GUI completely unresponsive and if the thread.sleep is called to many times Windows will suggest to shut the process down (the whole screen gets white and eventually you get a popup asking you if you want to wait or just shut it down). There are plenty of ways in the .net framework to prevent both of these issues (for example using a waithandle, background worker or locking)
There is no need to run the a new process using the Process.Start method. Instead, you can add the Outlook reference to your C# project and create a new instance of the Application class. See C# app automates Outlook (CSAutomateOutlook) sample project for more information.
Also you may find the following articles helpful:
How to automate Outlook and Word by using Visual C# .NET to create a pre-populated e-mail message that can be edited
How to use Visual C# to automate a running instance of an Office program
This works:
public static void StartOutlookIfNotRunning()
{
string OutlookFilepath = #"C:\Program Files (x86)\Microsoft Office\Office12\OUTLOOK.EXE";
if (Process.GetProcessesByName("OUTLOOK").Count() > 0) return;
Process process = new Process();
process.StartInfo = new ProcessStartInfo(OutlookFilepath);
process.Start();
}
Use the Process.Start overload that takes a ProcessStartInfo instead so you can set UseShellExecute
var startInfo = new ProcessStartInfo()
{
FileName = "Outlook.exe",
UseShellExecute = true
};
Process.Start(startInfo);
MAYBE the process need some time to start.
Try this:
if (Process.GetProcessesByName("OUTLOOK").Count().Equals(0))
{
Process.Start("outlook.exe"); // MY PROGRAM STOPS HERE
}
while ((Process.GetProcessesByName("OUTLOOK").Count().Equals(0));
var process = Process.GetProcessesByName("OUTLOOK").First();
This should cause starting process and waiting until it is avaible before trying to catch it...

how to give commands to the cmd through a windows 8 app in c# for wifi hotspot

We are planning to develop a wifi hotspot app in windows appstore using XAML and C# in visual studio. We were unable to find any class or methods to access the command prompt from the desktop. We need to type the below code to start a hotspot connection using internet sharing in windows 8:
netsh wlan set hostednetwork mode=allow
ssid=ConnectionName key=8Characters
We need to have a solution to this problem somehow through which we can send the above commands to the command prompt and start a connection using windows 8 app.
Please help me.
Thank You.
Use System.Diagnostics.Process to execute commands.
Sample code, copied almost verbatim from the documentation, modified for your needs:
using System;
using System.Diagnostics;
using System.ComponentModel;
namespace MyProcessSample
{
class MyProcess
{
public static void Main()
{
Process myProcess = new Process();
try
{
myProcess.StartInfo.UseShellExecute = false;
// You can start any process, HelloWorld is a do-nothing example.
myProcess.StartInfo.FileName = "%Windir%\System32\netsh.exe";
myProcess.StartInfo.CreateNoWindow = true;
myProcess.StartInfo.Arguments = "wlan set hostednetwork mode=allow ssid=ConnectionName key=8Characters ";
myProcess.Start();
// This code assumes the process you are starting will terminate itself.
// Given that is is started without a window so you cannot terminate it
// on the desktop, it must terminate itself or you can do it programmatically
// from this application using the Kill method.
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
}
you can create a batch file and have your program run that file on startup.
something.bat with
netsh wlan set hostednetwork mode=allow ssid=ConnectionName key=8Characters

Windows Services - operating system is shutting down too quickly

Firstly I would like to apologize for my English language. I try to create a Windows Service which run program for BuckUp data when the computer is shutting down.
Problem is that the operating system during shutdown to kill my Windows Service before BackUp data is executed by to the end of. I changed the registry value HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\WaitToKillServiceTimeout to 3600000 but it didn't help, my Windows Service is killed before it is executed. Maybe someone knows how to make the operating system does't kill the Windows Service as quickly to BackUp data could be made. Please help me, I'm waiting for your response. Below I include my code Windows Service:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.IO;
namespace backUp_ser
{
public partial class Service1 : ServiceBase
{
public Service1()
{
InitializeComponent();
this.CanShutdown = true;
}
protected override void OnStart(string[] args)
{
}
protected override void OnStop()
{
}
protected override void OnShutdown()
{
ProcessStartInfo stratInfo = new ProcessStartInfo();
stratInfo.WindowStyle = ProcessWindowStyle.Hidden;
stratInfo.FileName = "C:\\Program Files\\Cobian Backup 10\\Cobian.exe";
stratInfo.Arguments = "list:C:\\Program Files\\Cobian Backup 10\\DB\\MainList.lst -bu -nogui -autoclose";
Process process = Process.Start(stratInfo);
process.WaitForExit(360000);
}
}
}
Apart from your query, I want to remind you that the services are running in a separate logon session and the services won't interact with the logged in desktop session (mostly).
So, you need to intercept the shutdown event in your service code. Then, you need to hold the shutdown event till you complete your backup process. You can hook those Windows events through message pumps/queues. You need to intercept the WM_ENDSESSION/ WM_QUERYENDSESSION events.
This query is already discussed in this post. You can refer that.

Best way of determining a remote computer has booted and running

I am writing a test application which is controlling another computer. The test computer is started by sending a command string via the RS-232 port (from a control computer running Windows XP SP2 using a C# application), at which time the test computer will power-on and boot into Windows XP. I would like to know what would be the best method to determine when that computer has completed it boot process and running normally.
I was thinking of the following:
1) I was either thinking of pinging that computer, or
2) Have a shared drive and if able to access that shared drive, or
3) Writing a small service which I can communicate with
Is there different/better approach?
Mark
It all depends on what you consider "completed its boot process and is running normally". For instance, if all you care is the moment the network card is initialized, pinging might be good (as long as the ECHO port isn't closed).
A share is not a good idea as they generally only become available when a user is logged in, which may or may not be the case depending on your situation. But even if, what if you change the configuration or decide it is a security breach to open up a share?
If you want to play it certain or if you just need to wait until all services have started, you should consider your third option. It's easiest to do. Let it listen on port 80 and run from IIS. When queried, it can answer with some details of the machine. This will also give you the most flexibility. Using IIS helps you for not having to write your own service and makes it trivial to install and configure.
If IIS is not an option, you can of course consider writing your own service. Not that hard to do, but it'll require you to write the code to listen to certain ports yourself.
I had the exact problem you did, I found writing a custom service was the most useful. (I actually needed to know when a headless machine had the Remote Desktop service ready to accept connections, the program I wrote actually beeps the PC speaker a little tune when it is ready to be logged in.
EDIT: I dug up the source in case you where interested.
using System.ComponentModel;
using System.Configuration.Install;
using System.Runtime.InteropServices;
using System.ServiceProcess;
using System.Threading;
namespace Beeper
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new Beeper()
};
ServiceBase.Run(ServicesToRun);
}
}
public partial class Beeper : ServiceBase
{
public Beeper()
{
}
protected override void OnStart(string[] args)
{
if (MainThread != null)
MainThread.Abort();
MainThread = new Thread(new ThreadStart(MainLoop));
MainThread.Start();
}
protected override void OnStop()
{
if (MainThread != null)
MainThread.Abort();
}
protected void MainLoop()
{
try
{
//main code here
}
catch (ThreadAbortException)
{
//Do cleanup code here.
}
}
System.Threading.Thread MainThread;
}
[RunInstaller(true)]
public class BeeperInstaller : Installer
{
private ServiceProcessInstaller processInstaller;
private ServiceInstaller serviceInstaller;
public BeeperInstaller()
{
processInstaller = new ServiceProcessInstaller();
serviceInstaller = new ServiceInstaller();
processInstaller.Account = ServiceAccount.LocalSystem;
serviceInstaller.StartType = ServiceStartMode.Automatic;
serviceInstaller.ServiceName = "MyProgram";
serviceInstaller.ServicesDependedOn = new string[] { "TermService" }; //Optional, this line makes sure the terminal services is up and running before it starts.
Installers.Add(serviceInstaller);
Installers.Add(processInstaller);
}
}
}

Categories

Resources