Closed pyed closed 8 years ago
Are you running your application with admin privileges?
Yes, right click run as admin will show the same message, also cmd.exe will stop working after it.
And I tried calling it from a windows service I'm running, which runs under the account "SYSTEM" and the same error occurred
Did you try running the demo service in the repo? That works for me...
What will the demo service do when I install it as a service ?
I'm interested to have a command-line executable that uses ProcessExtensions
which other installed services will call to run something like calc.exe
on the active user session, is that possible ?
Look here. All it does is launch calc.exe
when it starts.
What you are proposing should be possible, yes. So long as the cmd line process is started with the same permissions that the service has, it should be good.
I tried to install the demo using installutil
and I got the following in the InstallLog
file
Installing assembly 'C:\Users\pyed\Desktop\CreateProcessAsUser\DemoService\bin\DemoService.exe'.
Affected parameters are:
logtoconsole =
logfile = C:\Users\pyed\Desktop\CreateProcessAsUser\DemoService\bin\DemoService.InstallLog
assemblypath = C:\Users\pyed\Desktop\CreateProcessAsUser\DemoService\bin\DemoService.exe
Installing service DemoService...
Creating EventLog source DemoService in log Application...
Rolling back assembly 'C:\Users\pyed\Desktop\CreateProcessAsUser\DemoService\bin\DemoService.exe'.
Affected parameters are:
logtoconsole =
logfile = C:\Users\pyed\Desktop\CreateProcessAsUser\DemoService\bin\DemoService.InstallLog
assemblypath = C:\Users\pyed\Desktop\CreateProcessAsUser\DemoService\bin\DemoService.exe
Restoring event log to previous state for source DemoService.
An exception occurred during the Rollback phase of the System.Diagnostics.EventLogInstaller installer.
System.Security.SecurityException: The source was not found, but some or all event logs could not be searched. Inaccessible logs: Security.
An exception occurred during the Rollback phase of the installation. This exception will be ignored and the rollback will continue. However, the machine might not fully revert to its initial state after the rollback is complete.
and yes, my service will run the cmd with the services account which is "SYSTEM", this would be awesome.
Make sure you successfully built the project (in visual studio), and that your are running createservice.bat
as an admin.
well, I built it in visual studio sure, and I ran createservice.bat
as admin, I got a cmd.exe
window for a split of a second and nothing happened after, I opened the services
application, there's no service with the word demo
in it
Ok, I'll look into it more tomorrow.
I really appreciate your time, this is important for me, I will work more on it, and I will report back
Ok, just tried running the demo from scratch, it definitely works. Try following these steps exactly:
cmd.exe
as Administratorgit clone https://github.com/murrayju/CreateProcessAsUser
cd CreateProcessAsUser
%windir%\Microsoft.NET\Framework\v4.0.30319\msbuild.exe solution.sln
cd DemoService
createService.bat
I just ran this on Windows 8.1 x64. If it doesn't work for you, there must be something different about your environment. Let me know.
I really appreciate your time, I followed your steps and indeed the Demo worked for me on a Windows 7.
But I'm still not able to achieve the command-line program that I need, I created a new repo with my code in it, it's a C# command-line project with ProcessExtensions.cs
included, I would like you to take a look at it : https://github.com/pyed/spawnproc
when I try to run it, I hit this exception:
if (!GetSessionUserToken(ref hUserToken))
{
throw new Exception("StartProcessAsCurrentUser: GetSessionUserToken failed.");
}
You need SE_TCB_NAME privilege. If you ran from a service (LocalSystem) it's held by default, if you are running it from command line, like you do, it's up to you to obtain it.
Yes, what @AndrewSav said. If you intend to run your code from the system account, you should just do your testing in that same environment and it should work. Otherwise, as an admin you will be able to acquire the necessary permissions, but you'll have to figure out the necessary win32 calls to do so.
Also, that is not the only privilege that you will need, the CreateProcessAsUser doc lists others.
Okay, I'm not a Windows guy, but I have this service that I'm executing commands from, so when I execute whoami
I will get nt authority/system
, but when I try to execute spawnproc.exe
I will hit the same exception, aren't I running spawnproc.exe
via the nt authority/system
account which should have the privileges I need ?
Well yes and no. It will be the same user account, but C# by default does not spawn the child process with all of the same privileges. Windows services are special, and are granted privileges by default that other processes are not. This isn't something that I've personally tried to do, so I'm not sure if there is a C# way, but I'm guessing that you'll have to call the win32 apis I linked above (via pinvoke).
Honestly, it would probably be easier to just modify the service(s) to use my library directly, rather than hand off to another process.
What I'd suggest doing is trying your best, and then posting your failed attempt at Stack Overflow. I'm sure helpful folk there will be able to give a hand, you just would need to demonstrate that you've put enough efforts in it yourself and not just asking people to write your code for you.
@murrayju okay, one last question, is your DemoService
designed to "only" run calc.exe
?
this may sound weird, but changing only line 15 in this file from calc.exe
to something like stikynot.exe
or osk.exe
will not have the same effect as having calc.exe
there !! and just by changing the source to calc.exe
again will show the Calculator, but for the Sticky Note and other apps it will not show them !! is the PATH that the service calling calc.exe
differ from the global path "which is usually C:\Windows\System32\calc.exe"
@pyed No it should work with any process. It will resolve the process path using the system %PATH%
variable. If all else fails, just use the absolute path.
You could be running into 32/64 bit problems, or even string encoding problems. If you can't get it to work, let me know and I'll dig deeper.
@murrayju I'm sure that this worth your time to dig into, I used absolute paths and it's not working, only calc.exe
works !
@murrayju I'm still interested to know your answer, just change calc.exe
in the DemoService
to any application in the %PATH%
and try to run it, it won't work ¯\_(ツ)_/¯
This is the description of CreateProcessAsUser
https://msdn.microsoft.com/en-us/library/windows/desktop/ms682429(v=vs.85).aspx It explicitly says, that if you use lpApplicationName
parameter then:
The string can specify the full path and file name of the module to execute or it can specify a partial name. In the case of a partial name, the function uses the current drive and current directory to complete the specification. The function will not use the search path. This parameter must include the file name extension; no default extension is assumed.
If you want path, use lpCommandLine
parameter that is described in the same article below.
@AndrewSav Okay I see now, but it still does NOT work, even with absolute paths, it only works with calc.exe
, try it yourself, change "calc.exe"
in the file DemoService/DemoService.cs
to C:/Windows/System32/StikyNot.exe
, the question is simple, after running createService.bat
Are You Getting A Sticky Note ??
I tried. Works fine. Not with a sitky, but with a handful of other programs in different folders. I'm not sure what the stiky is.
@AndrewSav I see that it works for some applications, and doesn't for others, I'm not sure about the reason tho.
Perhaps you are running on 64 bit system and trying to run a program from system folder with file system redirection on. If after redirection the program is not in the redirected folder (calc.exe is stikyno.exe is not) it cannot find it. Copy your stickynot to C:\Windows\SysWOW64 or for that matter anywhere else and run it from there. Reading: https://msdn.microsoft.com/en-us/library/windows/desktop/aa384187
@pyed Maybe you don't use double backslashes in full path (in example you must set path to mspaint like this: "C:\Windows\System32\mspaint.exe".
And remember that you can always use murrayju DemoService to run application from another system account service. In Demo service code just replace application to run (set proper path), compile solution. Don't use attached createService.bat but install DemoService by running %windir%\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe bin\DemoService.exe. Set your service to run some cmd script (in example RunApp.cmd filed with this commands:
sc start DemoService sc stop DemoService
). When your service (working with system accounts rights) run RunApp.cmd , this script will run DemoService, Demo service at start will run your application as user, script will stop DemoService ( by sc stop DemoService command) and will be ready to run your application next time ;)
@murrayju @kukucz @AndrewSav thanks for helping.
I got it to work the way I want it to work, I didn't want to use full-paths to run my application, I wanted to run it just how calc.exe
was running, including my application in the %PATH%
wasn't a solution as @AndrewSav explained that earlier, so I moved my application to C:/Windows/SysWOW64
and now I can call it just like calc.exe
. ¯\_(ツ)_/¯
Closing as resolved.
Hi i also getting the following error: StartProcessAsCurrentUser: GetSessionUserToken failed. at ProcessExtension.ProcessExtensions.StartProcessAsCurrentUser(String appPath, String cmdLine, String workDir, Boolean visible) at Scheduler_Service.Service1.StartEXE(String s) at Scheduler_Service.Service1.folderfound(String path)
Iam using this in the network drive location
Hi Justin,
Thanks for your useful piece of code. I am to capture the standard output of the program which is executed with ProcessExtensions.StartProcessAsCurrentUser. Could you add a return value StartProcessAsCurrentUser that returns the standard output of program who is executed?
Hi murrayju, I am trying to use the ProcessExtnesions.StartProcessAsCussrentUser in window application (.net framework 4.8 and windows 10). I want to start a pinned web application in task bar if someone closed it and using the following code var app_key = "nfhlhahcgkadabofgdcfegfbdcbdghgg";
var path = @"C:\Program Files (x86)\Microsoft\Edge\Application\msedge_proxy.exe";
var arg1s = $"--profile-directory=Default --app-id={app_key} --app-url=https://myapp/auth/realms/abc_Org/protocol/openid-connect/auth?response_type=code&client";
var str = $"\"{path}\" {arg1s}";
ProcessExtensions.StartProcessAsCurrentUser(str);
I am getting unable to ger GetSessionTokenUser. IT works fine with calling "calc.exe". Please advise. Thanks.
Hi folks. This isn't the place to get support. Try stack overflow for that.
If you have reproducible steps for a bug, please make a new ticket.
I couldn't get this to work for me, I'm new to C# so maybe I'm doing something wrong, here's the code
trying to run this will return the following error, with exit status code 255