I'd like to write some code that uses BITS for copying very large files between disks on the same server (the second disk being a SAN level clone\snapshot).
I looked into BITS as i thought it would be a good way to get progress\percentage complete data on the transfers, as well as resume functionality etc
I have a lot of hosted Powershell and I thought i'd have a stab at using the inbuilt BITS cmdlets, as this would be a super quick way of doing it, i could write wrappers to get the stuff i need etc Unfortunately i ran into this:
When you use *-BitsTransfer cmdlets from within a process that runs in a noninteractive context, such as a Windows service, you may not be able to add files to BITS jobs, which can result in a suspended state. For the job to proceed, the identity that was used to create a transfer job must be logged on. For example, when creating a BITS job in a PowerShell script that was executed as a Task Scheduler job, the BITS transfer will never complete unless the Task Scheduler's task setting "Run only when user is logged on" is enabled."
Doing anything through an impersonated Powershell runspace throws up the following error:
The operation being requested was not performed because the user has not logged on to the network. The specified service does not exist. (Exception from HRESULT: 0x800704DD)"
My web service is running as AppPoolIdentity, I impersonate when needed to do stuff. It makes sense this doesn't work via hosted Powershell, but can anyone think of a workaround? If this isn't possible, do i have any alternatives?
I was thinking of using BITS Compact Server as an alternative, but the documentation is ancient.
Have you thought of using robocopy? Running with the /ZB switch has always worked well for me, and you can improve performance with /J which enables unbuffered I/O. For output, run with /ETA and /TEE as well.
Related
I would like to create an application in C# which cannot be terminable by a user from task manager or taskkill.
I found some methods on the internet. but what would you recommend? What's the best practices method for this?
RegisterServiceProcess
Procected Services
Keep-alive processes
and so on.
Thanks,
Task manager is OS supplied way to stop/kick nonresponsive applications. You cannot bypass task manager. For that matter, you cannot bypass any tool whatsoever. Operating system is custodian of system's resources and is responsible for controlling its execution, managing resources etc.
OS provisions certain ways for its users so that they can view/interrupt running processes, allocate more memory, view other relevant parameters. Any sane OS (windows or not) never exposes interface whereby user can run amok through the system creating destroying whatever he or she wants. If it does, it will simply lose control over system internals - something only it can control and not the user.
If you are trying to develop something that works like antivirus, take a look at here - https://learn.microsoft.com/en-us/windows/win32/services/protecting-anti-malware-services- . This is vendor specific way provided by MS to create a process that stays around even if other processes try to kill it. Useful in scenarios like anti-malware defence.
There is a way to deal with this in Linux - https://unix.stackexchange.com/questions/227459/make-a-process-unkillable-on-linux . Note that root user can kill any process that it wants to.
The task needs to run under R0 privileges which sits above an elevated administrator. Our antivirus and several other security packages do this so it absolutely is possible. I'm a domain admin and cannot kill the task via task manager.
I wrote a console application that is currently running on the server. It doesn't require any user input (other than parameters at start which can be done via start parameter).
Unfortunately this solution is bad, because someone can accidentally turn it off (i.e. when connecting to server using Remote Desktop Connection and then logging off instead simply disconnecting). I need it to run all the time.
One solution would be to turn it into windows service, but so far using SC or third-party tools like nssm or RunAsService failed (SC and Nssm create a service but such service cannot be started).
I could completely rewrite my program to be a proper service... but to be honest I'm struggling with it (and from what I've read its not recommended practice).
Finally I could leave it as a console app and use task scheduler to run it -which does look like a decent solution, but (like I've mentioned) I need it to run all the time (it can be turned off and on - very short downtimes are not an issue).
Could I please ask for any help with setting such task?
SOLVED
After few attempts I've turned it into service using Topshelf andthis great guide.
There are two methods you can use to run a .net program constantly in windows. Both have advantages and disadvantages.
Windows Service
Recommended Solution
Will startup service on computer start (doesn't require someone to log on)
Has some (limited) error handling in the form of restarts
Good for very reliable services that can run for long periods of time
Service handles its own state
Can easily crash due to memory leaks
IIS Application Server
Not recommended solution
Starts with windows, but might not start your application
Requires newer windows to allow always on configuration
Always on configuration is complicated
State is handled by IIS
Much better resiliency to crappy programming, as IIS will restart for you
IIS will also likely kill your threads for you (so your scheduler will stop working)
I suspect the reason you were told that a windows service is not recommended was due to the fact that it could crash due to memory leaks. But that issue will occur no matter what, since your program needs to run for a long time (its not a problem with windows services, but long lived processes).
There are a number of rules that need to be followed to write a functional windows service including but not limited to
the ability to complete the initialization process in a specific time
a general understanding of threads
There is nothing inherently bad about writing a windows service they just require more effort and an installer.
Based on your description a scheduled job seems to fit your requirements
If you don't want to re-write your console app into a windows service and want it to be running all the time, the only solution I could see is:
Create a small window's service, that checks to see if your console process is running or not.
If it finds that there is no Console process, then start a new one.
Process[] pname = Process.GetProcessesByName("YourConsoleApp.exe");
if (pname.Length == 0)
Process.Start("YourConsole.exe")
else
//Do nothing
I have been working on many applications which run as windows service or scheduled tasks.
Now, i want to make sure that these applications will be fault tolerant and reliable. For example; i have a service that runs every hour. if the service crashes while its operating or running, i d like the application to run again for the same period (there are several things involved with this including transactions of data processing) , to avoid data loss. moreover, i d like the program to report the error with details. My goal is to avoid data loss and not falling behind for running the program.
I have built a class library that a user can import into a project. Library is supposed to keep information of running instance of the program, ie. program reads and writes information of running interval, running status etc. This data is stored in a database.
I was curious, if there are some best practices to make the scheduled tasks/ windows services fault tolerant and reliable.
Edit : I am talking about independent tasks or services which on different servers. and my goal is to make sure that the service will keep running, report any failures and recover from them.
I'm interested in what other people have to say, but I'll give you a few points that I've stumbled across:
Make an event handler for Unhandled Exceptions. This way you can clean up resources, write to a log file, email an administrator, or anything you need to instead of having it crash.
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(AppUnhandledExceptionEventHandler);
Override any servicebase event handlers you need in the main part of your application. OnStart and OnStop are pretty crucial, but there are many others you can use. http://msdn.microsoft.com/en-us/library/system.serviceprocess.servicebase%28v=VS.71%29.aspx
Beware of timers. Windows forms timers won't work right in a service. User System.Threading.Timers or System.Timers.Timer. Best Timer for using in a Windows service
If you are updating on a thread, make sure you use a lock() or monitor in key sections to make sure everything is threadsafe.
Be careful not to use anything user specific, as a service runs without a specific user context. I noticed some of my SQL connection strings were no longer working for windows authorizations, etc. Also have heard people having trouble with mapped drives.
Never make a service with a UI. In fact for Vista and 7 they make it nearly impossible to do anyway. It shouldn't require user interaction, the most you can do is send a message with a WIN32 function. MSDN claims making interactive services is bad practice. http://msdn.microsoft.com/en-us/library/ms683502%28VS.85%29.aspx
For debugging purposes, it is way cool to make a service run as a console application until you get it doing what you want it to. Awesome tutorial: http://mycomponent.blogspot.com/2009/04/create-debug-install-windows-service-in.html
Anyway, hope that helps a little, but that is just a couple thing I poked around to find on my own.
Something obvious - don't run all your tasks at the same time. Try to schedule them so only one task is using some expensive resource at any time (if possible). For example, if you need to send out newsletters and some specific notifications, schedule them at different times. If two tasks need to clean up something in the database, let the one run after another.
Also schedule tasks to run outside of normal business hours - at night obviously.
I've created an exe file that does some maintainance work on my server.
I want to be able to launch it from the website that sits on the server.
The exe has to be launched on the server itself and not on the client.
My instincts tell me it's not possible but I've had to check with you guys.
If I need to set certain permissions / security - I can.
Yes, it can be done, but it's not recommended.
An ideal solution for running maintenance scripts/executables is to schedule them using cron on Unix/Linux systems or using Scheduled Tasks in Windows. Some advantages of the automated approach vs. remote manual launch:
The server computer is self-maintaining. Clients can fail and people can forget. As long as the server is running the server will be keeping itself up to date, regardless of the status of client machines or persons.
When will the executable be launched? Every time a certain page is visited? What if the page is refreshed? For a resource-intensive script/executable this can severely degrade server performance. You'll need to code rules to handle multiple requests and monitor running maintenance processes. Cron & scheduled tasks handle these possibilities already.
A very crude option, Assuming IIS: Change Execute Access from "Scripts Only" or "None" to "Scripts and Executables"
To make this less crude, you should have the executable implement a CGI interface (if that is under your control.
And, if you want to use ASP.NET to add autorization/authentication, the code (C#) to do this would be:
System.Diagnostics.Process process;
var startInfo = New System.Diagnostics.ProcessStartInfo("C:\file.exe")
process.StartInfo = startInfo;
process.Start();
process.WaitForExit();
It's possible, but almost certainly it's a bad idea. What environment/webserver? You should just need to set the relevant 'execute' permissions for the file.
I really suggest that you don't do this, however, and configure the task to run automatically in the background. The reasoning is that, configured badly, you could end up letting people run any executable, and depending on other factors, completely take over your machine.
Depends what language you're using; most server side scripting languages give you a way to exectue shell commands, for example:
$result=`wc -l /etc/passwd`;
executed a unix command from perl.
Most web languages (I know at least Java and PHP) allow you to execute a command line argument from within a program.
Is it possible to run a windows form application or a console application under system account? Like asp.net application can run under system account by changing machine config file :
<processModel userName="machine" password="AutoGenerate" />
This is to give more privileges to the program ...
It sounds like you're attacking the symptom rather than the problem. What exactly does your program need to do that requires additional permissions? Maybe there's a different way of accomplishing that task without requiring any kind of elevation.
Yes. You can run any app under the system account. One technique is to launch it as a scheduled task, or by using the "at" command line utility.
Unfortunately, however, since Windows Vista, applications run in this way can't interact with the user, since they run in a different session.
This means that running a WinForms (or any kind of GUI, really) application in this way is kinda pointless. Similarly for a console app, if you want to see the output.
If it's for a one-off, you can probably live with it. Otherwise, you should be looking at creating a Windows Service, which can be configured to run under any user account (including SYSTEM). If you want to interact with it, you'll need to implement a separate app that talks to it through (e.g.) .NET remoting.
Can't you do that by launching it from a scheduled task in Windows?
That depends on what your goal is. If you want it to run under the system account and let a user interact with it, you can't do that. If you absolutely need to do this your best bet it to create a service that handles the operations that require additional priveleges and runs as System, and the connect to that service from a GUI running as user. However, if you go this route, realize that you're creating a hole in the security boundary between what a standard user can do and what System can do so be sure you protect the connection between the GUI and the service and limit the scope of the service to only what you absolutely need it to do.
As lassevk mentions if you just need to do this once or occasionally you can use runas to run in another security context but still have an interactive GUI / console.
On the other hand, if you just want it to run unattended at a certain time, you should be able to use the task scheduler like Martin suggests.