Re: Redirect Process Input/Output with Windows API
Yeah that is definitely a problem with the service EXE rather than the way you are trying to start it. It basically means that you have something in your service's "Start" method (or it might be called OnStart or something like that) that hangs or takes too long. That Start method needs to complete and return within a maximum of I think 30 seconds - most services start within a couple of seconds. So I would do some debugging within that method of your service and see where it is getting stuck on the Windows 7 machines.
Oh and by the way, you can start services via managed .NET code, you don't need to use Windows API for that Just use the System.ServiceProcess.ServiceController class (although I guess it might be easier to use that Windows API if you already have a handle to the service from creating it)
Re: Redirect Process Input/Output with Windows API
Hi Chris, I did some digging and what I think the problem might be is that on Windows 7 machines, services are no longer permitted to communicate interactively with any window stations and my service was explicitly creating the service as interactive and succeeding at doing so using windows API in a nice .net wrapper that I created. I think it may be failing on start due to the interactive parameter so I'm going to test this tomorrow. This is all I can think of because the xp service starts in seconds.
Re: Redirect Process Input/Output with Windows API
Services can still be marked as interactive in Windows 7 - they will still start, but just when they try to display something interactively the user will be prompted to switch to another desktop to see the message. I think this is to encourage developers not to show things interactively from services (as it is not a nice experience for the user having to switch to a separate desktop just to see your service's message) but to make sure users do still see the things that services display in case it is something important
Re: Redirect Process Input/Output with Windows API
Oh ok, so if that is true then my interactive prompts should still technically work. I haven't had a chance to test on Win 7 until now but I need to at least get the service started. I can't even start my service manually from the computer management console. It works perfect in XP. Do you have an example of any working windows 7 services that can run as the system account?
Re: Redirect Process Input/Output with Windows API
I just recently changed it as you can see from the commented line and I just added the base.onstart(args). I haven't gotten to test it yet.
Code:
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.ServiceProcess;
namespace NRP
{
internal sealed class NRPServer : ServiceBase
{
static void Main()
{
ServiceBase.Run(new NRPServer() { ServiceName = "NiRDs Remote Process", CanStop = true });
//NRPServer.Run(new NRPServer() { ServiceName = "NiRDs Remote Process", CanStop = true });
}
protected override void OnStart(string[] args)
{
base.OnStart(args);
Thread t = new Thread(Start);
t.IsBackground = true;
t.Start();
}
private void Start()
{
Thread t = new Thread(RemoteProcessPipes.StartCommandPipe); //New background thread to listen for new connections..
t.IsBackground = true;
t.Start(); //Start the thread
while (t.IsAlive)
Thread.Sleep(1000); //Loop in the main thread until the primary server pipe thread has ended. Then exit.
}
}
}
Re: Redirect Process Input/Output with Windows API
Well there's your problem - the Start method is going to continuously loop until the other thread ends (which presumably doesn't happen for a while) so the Start method never finishes. Why do you need to do that loop? Why not just start the other thread and that's it?
EDIT: Oh sorry, I didn't look at the OnStart method, didn't realise that Start method was being run in another thread (though I still don't see the need for that loop)
Re: Redirect Process Input/Output with Windows API
True, that loop does look strange and I don't know why I added it but it wasn't causing an issue in XP. The OnStart method of the service itself completes after starting the new thread....I dunno. I'm going to test again later. lol
Re: Redirect Process Input/Output with Windows API
Did you create this project by using the Windows Service project template in Visual Studio or did you just use a console app and edited that to make it a service?
Re: Redirect Process Input/Output with Windows API
Yes I'll definitely take a copy of a service project that works and ill try compiling it and running it on a win7 machine that we have at work. It might just have something to do with the custom win7 image that they create.
Re: Redirect Process Input/Output with Windows API
Hey Chris,
So what I did was copied that service template and compile a service that literally does nothing. I tested this service on an XP machine and it started fine. I tried on a Windows 7 machine, it tries to start, but immediately, within milliseconds, replies back stating that the service did not start in time.....
Does it matter that I'm compiling the service executable on a windows XP machine? I didn't think that would make a difference.
Re: Redirect Process Input/Output with Windows API
That is weird. I've created services with that same template in the past that have worked fine on Windows 7. Are you sure its not just your Windows 7 test machine that has a general problem? Does it definitely have the version of the .NET Framework that you are targeting installed on it for example?
EDIT: I just tested it with that exact template that I sent you, literally didn't change anything and just compiled it. Then I used the sc.exe built in to windows (which calls the CreateService API) to create the service like so:
Code:
sc create displayname= test binpath= C:\ExampleService.exe
and then I started it and it started fine (this is on a Windows 7 x64 machine)
Last edited by chris128; Jul 28th, 2011 at 03:13 AM.
Re: Redirect Process Input/Output with Windows API
I have just recently made a slight change to the way the service starts. I'm just waiting to test it. I will make sure that .Net 4.0 is installed on the test Win7 machine. Also, I should probably try just compiling a standard executable and see if it runs normally on the system. You don't think that there would be any issue with compiling it on a WinXP machine do you?
Re: Redirect Process Input/Output with Windows API
No there should be absolutely no difference in compiling it on an XP machine compared to Windows 7 - its the same compiler that will be running and that has nothing to do with the OS or the development machine because it compiles to MS IL code rather than machine code.
Re: Redirect Process Input/Output with Windows API
Hey Chris,
Just to update you on my remote execution tool, I have sucessfully created a working application with a GUI interface that allows the creation of a remote processes on a Windows XP machine as either the currently logged in user, a domain user, or the SYSTEM account with console output re-direction through a named pipe from server to client. Also interactively on a Windows 7 machine, as the SYSTEM account on the seperate SYSTEM account's window station, and non-interactively for the domain account.
The issue with locating the security context of the currently logged in user was resolved by using API rather than using the security token of explorer.exe, to make a query on whether or not someone is currently using the console session or if it is a remote desktop session. This tool will NOT work if there are multiple active remote desktop sessions as currently it is targetting the first one available that is in use. I could potentially prompt the user with a list of active remote desktop sessions to make a choice, listing the userid's of each session for clarity, but I haven't gotten around to this yet.
If no one is logged into the machine then the option for an interactive process is disabled.
The tool also distinguishes which version of windows is running on the remote machine through the registry. Basically to use this tool you would need admin rights to the remote registry, access to create and modify services and write access to the Windows System32 folder on the remote machine.
Also, I did not implement any support for Windows 2000 OS.
There is no point in targeting the Current Users security context to make a process run interactively on Windows 7 OS unless you want to install some kind of service on every single machine that you want to have the process interact with the user for and make it start under the security context of the user when they log in using a policy or something. Our security policy at work doesn't permit us to run processes non-interactively as another user so I didn't implement that.
I also included an option to prompt the remote user to start the process with a default timeout that notifies the client application. This option can be specified when calling the function to remotely start the process from the DLL. Also you can specify custom prompt strings in case you want a different message for the user to see when accepting the request to start the process. I did this because I also created another executable that installs a print queue so I copy the executable to the remote machine, use the remote tool to start the process and provide queue information, and prompt the user to install the particular queue name onto the machine.
I've tested this remote execution with MSIExec, cscript, and wscript processes to install/un-install application on a remote machine or queue the install or removal in the SMS delivery client that our workstations have and receive back a return value from the process exiting.
This tool was implemented into a much larger network admin application that I have also created that is now being used by several hundred IT analysts in my place of work, that is under copy write protection, but the remote execution portion of the application is owned by myself.
As soon as I have time I am going to re-create the visual interface of the copy written code for use with the pre-compiled library that does all the real work and make a few modifications with some more testing and I will distribute a copy of both the application and library as a package for others to use.
So as a conclusion to the entire topic of creating an application that functions in the same way as the PSEXEC binary, it is 100% possible to make this work using either MS Visual C# or MS Visual Basic .NET programming languages.
Re: Redirect Process Input/Output with Windows API
I'm impressed and glad to see you got it all working in the end. Hope my contributions did help a little I would love to see your library if you get chance to release it too
Re: Redirect Process Input/Output with Windows API
You certainly did help very much with several aspects especially re-directing the standard output/input. It took a while to get it through the named pipe to the client machine but it works flawlessly now. I'm still debating on sharing any of the actual code because there is a LOT of money in having that type of source code secured but I'm definately willing to help anyone else out that needs some tips and release a copy of the binary when I have the time. It may be a few more months before I release it but it will definately be worth it because of the capabilities it has. I'll keep you up to date.