Cannot run cmd.exe through service. No commands appear to be working [duplicate] - winapi

Hey, I am trying to get a service to start my program but it isn't showing the GUI. The process starts but nothing is shown. I have tried enabling 'Allow service to interact with desktop' but that still isn't working.
My program is a computer locking device to stop unauthorised users from accessing the computer. I am running windows 7 with a 64 bit OS.
Here is the code for my service:
protected override void OnStart(string[] args)
{
Process p = new Process();
p.StartInfo.FileName = "notepad.exe";
p.Start();
FileStream fs = new FileStream(#"C:\Users\David\Documents\Visual Studio 2010\Projects\LockPCService\LockPCService\bin\Debug\ServiceLog.dj",
FileMode.OpenOrCreate, FileAccess.Write);
StreamWriter m_streamWriter = new StreamWriter(fs);
m_streamWriter.BaseStream.Seek(0, SeekOrigin.End);
m_streamWriter.WriteLine(" LockPCService: Service Started " + DateTime.Now + "\n" + "\n");
m_streamWriter.Flush();
m_streamWriter.Close();
}
protected override void OnStop()
{
FileStream fs = new FileStream(#"C:\Users\David\Documents\Visual Studio 2010\Projects\LockPCService\LockPCService\bin\Debug\ServiceLog.dj",
FileMode.OpenOrCreate, FileAccess.Write);
StreamWriter m_streamWriter = new StreamWriter(fs);
m_streamWriter.BaseStream.Seek(0, SeekOrigin.End);
m_streamWriter.WriteLine(" LockPCService: Service Stopped " + DateTime.Now + "\n"); m_streamWriter.Flush();
m_streamWriter.Close();
}
To try and get the service working I am using notepad.exe. When I look at the processes notepad is running but there is no GUI. Also the ServiceLog is there and working each time I run it.
Any ideas on why this isn't working?
Thanks.

This article explains Session 0 Isolation which among other things disallows services from creating a UI in Windows Vista/7. In your service starts another process, it starts in Session 0 and also will not show any UI. (By the way, the UI is created, it's just that Session 0 is never displayed). This article on CodeProject can help you create a process from a service on the user's desktop and show its UI.
Also, please consider wrapping you stream objects in a using statement so that they are properly disposed.

Services run under different account so notepad is run by another user and on another desktop so that's why you cannot see it. 'Allow service to interact with desktop' is not supported anymore starting from Vista.

I know this is a late post, but I found that this article was very helpful to me. I am running Windows 7 and the solution provided in this article works great.
If you download the code, there is a class called ApplicationLoader. Include that class in your project and then it's as simple as this:
// the name of the application to launch
String applicationName = "cmd.exe";
// launch the application
ApplicationLoader.PROCESS_INFORMATION procInfo;
ApplicationLoader.StartProcessAndBypassUAC(applicationName, out procInfo);

Services run in a different logon session and have a different window station from the user. That means that all GUI activity is segregated from the user's programs, not that the service can't display a GUI. Actually, this design makes it much easier to temporarily block access to the user's programs.
You'll need to call SwitchDesktop.

Related

Download Progress stopped on Screen lock in iOS

I have developed an Xamarin forms application. Provided download option to download file in our application. I have clicked download file and download progress show in app itself. If lock the iphone while download is in progress and unlock it again download stopped. How can I process download even locked phone?. This occurs only in iOS and works properly in Android.
I have used webclient DownloadFileTaskAsync process to download a file and maintain progress value in it.
WebClient client = new WebClient();
client.DownloadFileTaskAsync(new Uri(DownloadUrl), FileName);
Updated Query:
I have implemented the back-grounding process into my source. I have used "Creating Background-Safe Tasks" concept for my download process. I can download more than one file, so put this process in Task itself previously. Now, I have used BeginBackgroundTask in my download process but download process not carried to UI, even BeginBackgroundTask code doesn't hit while debug the code.
Below function put in native and called this function from forms when click download button.
public async Task DownloadFile(string DownloadUrl, string FileName)
{
var taskID = UIApplication.SharedApplication.BeginBackgroundTask(async() =>
{
WebClient client = new WebClient();
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);
client.DownloadFileCompleted += new AsyncCompletedEventHandler(client_DownloadFileCompleted);
client.DownloadFileTaskAsync(new Uri(DownloadUrl), FileName);
});
UIApplication.SharedApplication.EndBackgroundTask(taskID);
}
Also registered the app into Background fetch registration categories and now also progress not carried out while lock screen or minimize the app.
Am I missing any process in background techniques? Could you please help me to resolve this or suggest some simple sample as my scenario?
Please help me on this to resolve it.
Regards,
Cheran
You will need to use NSURLSession instead and create a background session for it. You can read how to do this in the official Xamarin Documentation.
You might get away with using WebClient in a background session, but only for a very short time span by using the pattern described in the "Handle iOS Background Limits" docs:
Task.Factory.StartNew(() =>
{
//expirationHandler only called if background time allowed exceeded
var taskId = UIApplication.SharedApplication.BeginBackgroundTask(() => {
Console.WriteLine("Exhausted time");
UIApplication.SharedApplication.EndBackgroundTask(taskId);
});
while(myFlag == true)
{
Console.WriteLine(UIApplication.SharedApplication.TimeRemaining);
myFlag = SomeCalculationNeedsMoreTime();
}
//Only called if loop terminated due to myFlag and not expiration of time
UIApplication.SharedApplication.EndBackgroundTask(taskId);
});
Where you would replace the while with your WebClient code.
However, as mentioned you really need to use Background Transfers for this to work properly.

Running executable program with no UI from windows service

I am running a console application with no UI and generate thumbmail images from pdf files. The compile file for this application works fine. However I have to call this compile file from windows service application that implement the the FileSystemWatcher class to detect when new pdf files are uploaded into the directory.
and I am using the suggestion from this link
How to run console application from Windows Service?
ProcessStartInfo info = new ProcessStartInfo(appName);
info.UseShellExecute = false;
info.RedirectStandardError = true;
info.RedirectStandardInput = true;
info.RedirectStandardOutput = true;
info.CreateNoWindow = true;
info.ErrorDialog = false;
info.WindowStyle = ProcessWindowStyle.Hidden;
Process process = Process.Start(info);
if (!process.HasExited)
{
LogEvent(process.ProcessName + "has started and called Thumbnail application");
}
else
{ LogEvent(process.ProcessName + "has been terminated"); }
I can see the process involking the "pdfThumbnail.exe" but I am getting this error when the application try to execute.
"System.Exception: Cannot create ActiveX component.
at Microsoft.VisualBasic.Interaction.CreateObject(String ProgId, String ServerName)
at PDFThumbnailCsharp.Main(String[] args)
"
As I have said above the pdfThumbnail.exe execute fine when i run the exe file.
Updates
This is the error from the SysInternals' Process Monitor
The machine-default permission settings do not grant Local Activation permission for the COM Server application with CLSID {FF76CB60-2E68-101B-B02E-04021C009402} and APPID
Unavailable to the user NT AUTHORITY\LOCAL SERVICE SID (S-1-5-19) from address LocalHost (Using LRPC). This security permission can be modified using the Component Services administrative tool.
I have changed the ownership of this CLSID to Administrator with Full control as described on this link
http://social.technet.microsoft.com/Forums/en-US/windowsserver2008r2general/thread/e303c7e1-16de-42fd-a1a4-7512c1261957
However I am still getting the same error.
Any help will be appreciated.
Thanks
This CLSID {FF76CB60-2E68-101B-B02E-04021C009402} is for Acrobat.Excha.PDDoc on my computer registry. Further investigation with Acrobat on this link https://forums.adobe.com/thread/1467460 revealed that Acrobat cannot be run from service.
What I have done for now until I have a better approach is to create a windows Task Scheduler that listen to an event raised by the windows service when new pdf are created and then trigger the console app that create the thumbnails.

Background worker blocking UI when using web service call

For some reason when i put a long running web service call (doesn't matter if its a legacy one or WCF) in a background thread it seems to be locking up the UI main thread.
I cant see anything wrong with the code im putting in.
workerThreadInitialNotify = new BackgroundWorker();
workerThreadInitialNotify.WorkerSupportsCancellation = true;
workerThreadInitialNotify.DoWork += new DoWorkEventHandler(workerThreadInitialNotify_DoWork);
workerThreadInitialNotify.RunWorkerCompleted += new RunWorkerCompletedEventHandler(workerThreadInitialNotify_RunWorkerCompleted);
workerThreadInitialNotify.RunWorkerAsync();
Then in my do work i have a webservice call like:
void workerThreadInitialNotify_DoWork(object sender, DoWorkEventArgs e)
{
if (!(sender as BackgroundWorker).CancellationPending)
{
try
{
TestWebService service = new TestWebService();
service.RunLongRunningMethod();
}
catch(Exception ex)
{
}
}
}
When this thread is called, it occasionally locks up the UI thread, now i have setup the RunLongRunningMethod to purposely run slow and timeout (for testing purposes), but technically this shouldn't lockup the UI thread at all as its in a seperate thread.
Here is what the method contains:
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["customConnection"].ConnectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand("TestDelay", conn))
{
cmd.CommandType = CommandType.StoredProcedure;
try
{
cmd.ExecuteNonQuery();
}
catch (Exception ee)
{
}
}
}
and TestDelay stored proc just contains this to simulate a delay so that the web service times out:
ALTER PROCEDURE [dbo].[TestDelay]
AS
WAITFOR DELAY '00:05:20';
The strange thing is that if i replace the web service call with a Thread.Sleep(20000); in the dowork, it runs perfectly, or even if i put a long running while loop it runs perfectly also.
I have no idea why specifically the webservice makes it lock up the UI.
ps: if i set up the webservice to be hosted locally to the Win Forms app, it runs ok, only when the webservice is running on another service, the strange lockup occurs.
ps (2): i am using devexpress library for ui controls of forms while the background thread runs in the background, not sure if this is related. I cant imagine why, if this is run in a seperate thread correctly
This ended up being a maxconnection .net setting in the App.config (its defaulted to a very low 2 by microsoft)
<system.net>
<connectionManagement>
<add address="*" maxconnection="40"/>
</connectionManagement>
</system.net>
Its now set to 40 and the issue has gone away.
There was multiple threads running at the same time, each calling web services, each of them were blocking each other.
There is more information in these links:
http://blogs.msdn.com/b/adarshk/archive/2005/01/02/345411.aspx
What is limiting the # of simultaneous connections my ASP.NET application can make to a web service?
http://msdn.microsoft.com/en-us/library/fb6y0fyc.aspx

How to elevate .net application permissions?

I have an application that would check for updates upon start and, if updates are found, it would copy some files over the network to the program files folder. Obviously such task can't be performed by Standard Users under normal scenarios.
I tried creating a service to do the update process but I had some security issues and I asked this question about it in superusers.
Now, considering the fact that most applications require elevated privileges to perform such task I think that might be the right approach. But how do I request elevation for the updater under all Windows version as of XP, included. I've found many topics about a manifest file, but since I need this to work with XP I can't create a solution specifically for UAC.
Privileges can only be elevated at startup for a process; a running process' privileges cannot be elevated. In order to elevate an existing application, a new instance of the application process must be created, with the verb “runas”:
private static string ElevatedExecute(NameValueCollection parameters)
{
string tempFile = Path.GetTempFileName();
File.WriteAllText(tempFile, ConstructQueryString(parameters));
try
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.UseShellExecute = true;
startInfo.WorkingDirectory = Environment.CurrentDirectory;
Uri uri = new Uri(Assembly.GetExecutingAssembly().GetName().CodeBase);
startInfo.FileName = uri.LocalPath;
startInfo.Arguments = "\"" + tempFile + "\"";
startInfo.Verb = "runas";
Process p = Process.Start(startInfo);
p.WaitForExit();
return File.ReadAllText(tempFile);
}
catch (Win32Exception exception)
{
return exception.Message;
}
finally
{
File.Delete(tempFile);
}
}
After the user confirms the execution of the program as administrator, another instance of the same application is executed without a UI; one can display a UI running without elevated privileges, and another one running in the background with elevated privileges. The first process waits until the second finishes its execution. For more information and a working example you can check out the MSDN archive.
To prevent all this dialog shenanigans in the middle of some lengthy process, you'll need to run your entire host process with elevated permissions by embedding the appropriate manifest in your application to require the 'highestAvailable' execution level: this will cause the UAC prompt to appear as soon as your app is started, and cause all child processes to run with elevated permissions without additional prompting.

Using Pgp.exe from a MVC application

I've been tasked with converting a legacy application to mvc. The app used pgp.exe to pgp sign user input and send it as an email. The application works locally and on a test server but won't run on a live server. I've had to jump though hoops such as running a specified user in the application pool so that we can set the keys in the users profile BUT it worked.
For some reason on the live server which is windows 2003 IIS 6 and identical to the testing server it fails. The problem is pgp.exe just wont seem to sign and create files the message I get from the console out put is. "Signature Error"?? When I put the command into a shell window logged in as the app pool user it runs no problem (after a fight with some permissions) but when running through the mvc application/IIS server it fails. The code used to call the process is below.
var startInfo = new ProcessStartInfo();
startInfo.FileName = _pgpexeLocation;
//startInfo.FileName = "pgp.exe";
startInfo.Arguments = string.Format("-sta \"{0}\" -u keyuser-z keypass +COMPATIBLE +FORCE", _tempFilePath);
startInfo.UseShellExecute = false;
startInfo.RedirectStandardOutput = true;
startInfo.LoadUserProfile = true;
using (Process exeProcess = Process.Start(startInfo))
{
// TODO: set limit to wait for and deal with exit
exeProcess.WaitForExit();
//var stringItem = exeProcess.StandardOutput.ReadToEnd();
//Logger.Info(stringItem);
}
I'm clutching at straws here hoping somebody has done something similar before and can help. I'm guessing it's key location or file location not being picked up somewhere but not sure what else to try?
Turns out that even though the app pool was using a specific user and I'd set the keys up in that users appdata folder when I checked the underlying process call it was actually trying to pick the keys up from the Default User profile. Not sure if this was an IIS config or something similar but moving the keys and pgp folder to this appdata instead worked?

Resources