So I've read a few questions regarding setting the system time on Windows 10 and the requirement to either have the process elevated or disabling the UAC on the machine. The issue I face is that I am not able to do either.
So to give clarity, I'm have a WinForms application that has to run as a standard user as the machine is an unattended terminal that automatically logs in and executes the application using the Startup folder to execute the application. Once the application is open it performs some operations of which one is retrieving a DateTime value from the server (a RESTful API) and needs to persist this value to the system. I know that this is sort of "reinventing the wheel", but this is what the customer wants as they don't wish to use SNTP and disabling the UAC is out of the question as it creates security holes and the network/system admin will not allow this to be done.
So now I've gone ahead and updated the Group Policy for "Computer Configuration > Windows Settings > Security Settings > Local Policies > User Rights Assignment > Change the system time" to include "Everyone", yet I'm still receiving an Error 1314 when I call public static extern bool SetSystemTime(ref SYSTEMTIME st) from the imported DLL [DllImport("kernel32.dll", SetLastError = true)].
An idea was to set the system time using a Windows Service that is installed with admin privileges that would be able to update the system time no problem, yet the OnCustomCommand only allows for the passing of a single integer value per command type and won't allow for extra parameters without writing some inter-process communication or pipeline for changing the system time to the provided value.
Am I missing something or is there no simple, easy, clean and safe way to perform this action or would it be best that the client just put aside preferences and use SNTP?
Thank you in advance.
Thanks to #ADyson for the comment:
"P.S. If you really have to do this, you could pass data to the background service simply by writing it to a file, and telling the service to look in that file for the data. Or...just don't use a winforms app at all. Basically you could write your service to be something that's installed on every machine that needs it, runs in the background constantly, gets the data from the API on a regular basis and updates the system time. So basically an alternative to SNTP (albeit probably lower-quality overall, but does a similar job)."
This will literally be the best solution to easily and quickly implement the required functionality. I know it is not "the right way", but for the requirements and constraints, it is "the best way".
Related
I need to create an application that will run on a server and be able to be configured to run commands at certain times. For instance, there will be a web interface allowing a user to set an engage time and a disengage time. Once those values have been saved by the user I need for the server to be able to fire off those commands precisely at the time specified each day.
I would also need to be able to set single use non recurring events that would occur... maybe 10 minutes from the time an event was triggered and have a command fired off when that 10 minute timer goes off.
I've already got a class library written that has the engage and disengage commands exposed. I would hope to be able to integrate this into whatever solution I end up with and simply be able to make calls directly to the class. Alternatively I could also compile the class library into an executable and have commands issued to it via command line. I'm hoping to not have to do the latter.
I've never written anything like this before. I've peeked a bit at Windows Services, but there is a lot of chatter out there saying that it isn't necessarily the best option. Can someone please guide me in the right direction please?
A windows service is not a bad idea, its perfect for this kind of application. Unless you end up using standard windows scheduled tasks as the trigger for your command, you need some sort of process that is always running to contain your scheduler. A windows service is an excellent candidate for this.
Using a windows service in conjunction with Quartz.NET and some sort of persistence layer so you can store your schedules (in case you need to restart the service or it crashes etc) would be a good way to go.
Alternatively, you could write an application that just adds and removes windows scheduled tasks, but considering you have existing class libraries, using Quartz.NET will fit in well with your existing libraries.
easiest solution:
make a console exe and run under scheduled task in windows.
Let web page to accept user input and modify a configuration file.
I found good advice how to change system time here.
It's ok... But what is the best strategy to change system local time for the WPF client application then?
For example my application periodically gets some data from server and I can pass the server time with it.
Or may be is better to use additional thread to ask server about the server time and change local system time always...
So I don't know which approach is better...
Thanks for any clue.
It is better not to do it at all - it requires admin privileges to change system time, so your program will have to run as admin (may be acceptable in your case, but normally not a good idea).
It is also requires some effort to correctly adjust for network latency when setting time. Please check out how it is normally done, i.e. starting with NTP - Network Time Protocol.
One option is to configure windows to check time more often itself instead doing it by hand as it already implements the functionality.
Let me give a back ground for everybody before I go to my problem. My company hosts website for many clients, my company also contracts some of the work to another company.
So when we first set up a website with all the informations to our clients, we pass that information to the other company we contracted and three of us have the same data. Problem is once the site is up and running, our clients will change some data and when ever they do that we should be able to update our contracted company.
The way we transfer data to the contracted company is by using a web service (httppost, xml data). Now my question is what it the best way to write a program which sends updated data to the contracted company everytime our clients change some data.
1) Write a windows service having a timer inside my code where every 30min or so connects to the database and find all changes and send it to the contracted company
2) Write the same code as #1 (with out the timer in it) but this time make it a simple program and let windows scheduler wake it every 30min
3) Any other suggestion you may have
Techenologies available for me are VS 2008, SQLServer 2005
Scheduled task is the way to go. Jon wrote up a good summary of why services are not well suited for this sort of thing: http://weblogs.asp.net/jgalloway/archive/2005/10/24/428303.aspx
A service is easy to create and install and is more "professional" feeling so why not go that way? Using a non-service EXE would also work of course and would be slightly easier to get running (permissions, etc.) but I think the difference in setup between the two is nearly negligible.
One possible solution would be to add a timestamp column to your data tables.
Once this is done, you can have one entry in each table that has the last collected time by your contracted company. They can pull all records since that last time and update their records accordingly.
A Windows Service is more self contained, and you can easily configure it to start up automatically when the OS is starting up. You might also need to create additional configuration options, as well as some way to trigger the synchronization immediately.
It will also give you more room to grow your functionality for the service in the future.
A standalone app should be easier to develop though, however you are reliant on the windows scheduler to execute the task always. My experience has been that it is easier to mess up things with the windows scheduler and have it not run, for example in cases where you reboot the OS but no user has logged in.
If you want a more professional approach go with the service, even though it might mean a little bit more work.
A windows service makes more sense in this case. Think about what happens after your server is restarted:
With a Windows Application you need to have someone restart the application, or manually copy a shortcut to the startup folder to make sure the application gets launched
OR,
With a Windows Service you set it to start automatically and forget about it. When the machine reboots your service starts up and continues processing.
One more consideration, what happens when there is an error? A Windows application would likely show an error dialog and wait for input before continuing; whereas a service would log the error in the event log and carry on.
I would like to be able to do an "inplace" update with my program. Basically, I want to be able to login remotely where the software is deployed, install it while other users are still using it (in a thin client way), and it update their program.
Is this possible without too much of a hassle? I've looked into clickonce technology, but I don't think that's really what I'm looking for.
What about the way firefox does it's updates? Just waits for you to restart the program, and notifies you when it's been updated.
UPDATE: I'm not remoting into the users' PC. This program is ran on a server, and I remote in and update it, the users run it directly off the server through remote access.
ClickOnce won't work because it requires a webserver.
I had some example code that I can't find right now but you can do something similar to Firefox with the System.Deployment.Application namespace.
If you use the ApplicationDeployment class, you should be able to do what you want.
From MSDN, this class...
Supports updates of the current deployment programmatically, and handles on-demand downloading of files.
Consider the MS APIs with BITS, just using bitsadmin.exe in a script or the Windows Update Services.
Some questions:
Are the users running the software locally, but the files are located on a networked share on your server?
Are they remoting into the same server you want to remote into, and execute it there?
If 2. are they executing the files where they are placed on the server, or are they copying them down to a "private folder"?
If you cannot change the location of the files, and everyone is remoting in, and everyone is executing the files in-place, then you have a problem. As long as even 1 user is running the program, the files will be locked. You can only update the files once everyone is out.
If, on the other hand, the users are able to run their own private copy of the files, then I would set up a system where you have a central folder with the latest version of the files, and when a user starts his program, it checks if the central folder has newer versions than the user is about to execute. If it does, copy the new version down first.
Or, if that will take too long, and the user will get impatient (what, huh, users getting impatient?), then having the program check the versions after startup, and remind the user to exit would work instead. In this case, the program would set a flag that upon next startup would do the copying, only now the user is aware of it happening.
The copying part would easily be handled by either having a separate executable that does the actual copying, and executing that instead, or the program could copy itself temporarily to another location and run that copy with parameters that says "update the original files".
While you can design your code to modify itself (maybe not in C#?), this is generally a bad idea. This means that you must restart something to get the update. (In Linux you are able to replace files that are in use, however an update does not happen until the new data is loaded into memory i.e. application restart)
The strategy used by Firefox (never actually looked into it) is storing the updated executable in a different file which is checked for when program starts to load. This allows the program to overwrite the program with the update before the resource is locked by the OS. You can also design you program more modular so that portions of it can be "restarted" without requiring a restart of the entire program.
How you actually do this is probably provided by the links given by others.
Edit:: In light of a response given to Lasse V. Karlsen
You can have your main program looking for the latest version of the program to load (This program wouldn't be able to get updates without everyone out). You then can remove older versions once people are no longer using it. Depending on how frequent people restart their program you may end up with a number of older programs versions.
ClickOnce and Silverlight (Out of browser) both support your scenario, if we talk about upgrades. Remote login to your users machine? Nope. And no, Firefox doesn't do that either as far as I can tell..
Please double-check both methods and add them to your question, explaining why they might not do what you need. Otherwise it's hard to move on and suggest better alternatives.
Edit: This "I just updated, please restart" thing you seem to like is one method call for Silverlight applications running outside of the browser. At this point I'm fairly certain that this might be the way to go for you.
ClickOnce doesn't require a webserver, it will let you publish updates while users are running the software. You can code your app to check for new update every few minutes and prompt the user to restart the app if a new version is found which will then take them through the upgrade process.
Another option is a Silverlight OOB application, but this would be more work if your app is already built as WinForms/WPF client app.
Various deployment/update scenarios (for .NET applications) are discussed with there pros and cons in Microsoft's Smart Client Architecture and Design Guide. Though a little bit old I find that most still holds today, as it is describing rather the basic architectural principles than technical details. There is a PDF version, but you find it online as well:
Deploying and Updating Smart Client Applications
Is this possible without too much of a hassle?
Considering the concurrency issues with thin clients and the complexity of Windows installations, yes hot updates will be a hassel without doing it the way the system demands.
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.