Programatically batch files to copy at night - c#

I need to create an Intranet website (page) which allows users to indicate a local network folder to copy to a production location. Currently this is done manually using xcopy in batch files.
What I am looking for is approaches on triggering the copy so it's done in the middle of the night and an approach to copy the files. I suppose I can run xcopy from my application, but is this a good way to do this? Should I use System.IO name space objects to copy the files? Is there a better way all together?
The application will be written in C# and ASP.NET. We currently use .NET 2.0/3.0, but I have no issues using .NET 3.5 if it contains better libraries for the solution.
Basically a user will indicate which network folder they need copied along with some other business information. The folder indicated and all sub-folders need to be copied to target location (not set by user).
If there is already an application out there which does this, I am not opposed to that either. I have no need to write stuff that already exists.

For the first problem (copying at midnight), I suggest setting up a scheduled task that runs the already existing batch file (or any program, for that matter)

For the scheduling part you could use Quartz.NET
It won't be difficult to write an xcopy operation in C# using System.IO. In fact, this would give you the greatest degree of flexibility.

I think you should consider using Windows Powershell to do your copying (or another scripting language if you prefer), driven by Windows Scheduled Tasks. Though you could write an application to do this, I think it would be much more maintainable to have a script that others could edit.

The simplest solution would be to wrap your xcopy commands in a command file and schedule it to run whenever you want as a Scheduled Task on your web server.
If you want to get fancy, you can write up a web interface to the task scheduler - I'm pretty sure I've seen open source examples of that type of application too.

you've tagged this ASP but if you aren't fussy I'd recommend a combination of Windows builtin Scheduled Tasks and rsync. If it really has to be automated from an intranet page (and you're in IE) then some form of ActiveX or downloadable script/application would be needed to configure the schedule.

Related

Is there a way to monitor the state of a console application?

Is there a way to monitor the state of a console application?
I am trying to build a user interface which shows whether or not a console application is currently running on the server (processing files). If it is running, I would like to show the current state: how many files processed, what file currently being processed, etc.
The only way that I can think of doing this:
Create a text/xml file when application is started
Update text file with information about current state for each object it processes
Delete text file when the application is finished processing
To me, this doesn't seem like a very good or efficient way to do it. Is there a way to detect if the ClickOnce application is running, and perhaps some other way to access the "Messages" or Log of it to show the progress?
Note - I am also looking into using NodeJS to do this, but unsure if it has this capability.
First, you should consider writing this as a Windows service instead of a console application.
That said, scraping a log file that your application is writing is a reasonable approach. Just ensure that it never gets too big.
Alternatively, you could look at using custom performance counters. That would open the door to using System Monitor/perfmon as your monitoring tool, so no need to write any client code.
There are at least two ways to achieve that:
Your console application writes some logs, some state files, during its run, so other processes can read those files and understand what is going on in that console process.
Implement an IPC mechanism. There are different ways to do that. It may help you look in What is the easiest way to do inter process communication in C#?.

Automatic update

I have a system with two web applications, one web service, one Windows service and a WPF application running 24 hours a day on a touch screen. All of them are connected to a database.
I want to be able to upgrade all of those applications by uploading upgrade files to the database and set the date and time for the upgrade to occur.
I have one idea on how to do this.
An application has a thread running to look for available upgrades.
When an upgrade is found, the file is downloaded to the application's computer.
When download is complete, the applications triggers a restart.
When application starts, it looks for an upgrade file on the local computer.
If upgrade is available, the application upgrades itself.
I'm not really sure how all these steps should be done yet, especially the last one. But I want some comments about this. Is this completely wrong? Am I on the right track? Any tips on how to do it like this or in another way?
I think you're going down the right lines here. A polling application to check the database for the existence of a new update followed by an xcopy deployment script would do it.
This might be doable from a PowerShell script too, that runs on a schedule, say every 10 minutes. It could check the database, close the process and service, xcopy the application (from a shared source) and restart the said service and app.
All this assumes that you are not using Windows Installer to package and deploy your application initially. Although an xcopy to directly replace binaries wouldn't hurt an MSI package, it's not recommended. We use AD MSI deployment at work and it's a pain at the best of times!
MSDN contains references for MSI vs XCopy deployment for WPF applications (as well as the security requirements).
This was the first link I found for querying SQL from PowerShell: http://elegantcode.com/2008/03/27/discovering-windows-powershell/
Good luck!
You will have trouble doing this with ClickOnce. ClickOnce would only work for your WPF app, it can't do anything with the services or web application. You could write a separate ClickOnce-deployed "Updater" app whose job is to update the other apps, but that still seems a little iffy.
It may sound stupid, but I'd start with the simplest thing I could think of. How about using Dropbox to push your update files; then an AutoHotKey script that runs on startup, watches the Dropbox folder for new updates, and runs them?
Sounds hokey, but it's something you could prove out in an hour or two.
Microsoft have an Updater Application Block which might be what you are looking for.
Do you really want to run an update from the database or is this just a possible solution? You are reinventing the wheel.
Have a look at ClickOnce deployment, everything you need is already done for you and integrated into VisualStudio. If you use something that already exists you have the benefit of existing documentation, helpful blogs of people who have already gone through the pain points and updates and fixes.
ClickOnce Deployment
ClickOnce Deployment in .NET Framework 2.0
How you want to use ClickOnce depends on what you want to get out of it. Out of the box you can very easily create a deployment that checks for an upgrade every time you run the application but you can also with a little bit of code have the application check for updates whilst it is running.
The Updater Application BlockVersion that Dominic Zukiewicz mentioned is the pre cursor to ClickOnce.
EDIT
ClickOnce provides a roll-back scenario on both the Server and Client end. The client can roll back to a previous version using the normal add remove programs dialogue and you can easily republish a previous version.
You could create another Windows Service that does the updates on a daily basis. The service would look on a specific folder if there are any updates to be process. For example it could look for an xml file which tells it the new version of the application and what the files to update are. It would shut down the application/services, backup the files that it needs to update, start the application/services, and clean up backup files keeping at least three backup files. The service should keep track of the last and current version installed so that when it reads the xml file it can check if it is a new update or not or you can simply delete the xml file when it completes.
How about Google Omaha? It's an open source tool, currently used to push updates of Google Chrome and Google Earth. Omaha can handle application installation, too. A high-level design overview can be found here.

What's wrong with installation of an application by copying Bin>Debug folder content?

For a testing usage of not very complex WPF applications I often don't make installer - just, after building project, copy Bin>Debug folder content of a VS2008 project folder to a hard drive of a user computer and put an icon to a desktop. No records to windows registry.
Are there any drawbacks of such a way of using windows applications for testing period?
There's nothing wrong with this approach at all - it is what's called xcopy deployment. You don't get a few things doing it this way:
an entry in the add/remove programs for users to uninstall with
the ability to add shortcuts to desktop/start menu/quick launch
any changes to the registry for settings etc...
Another benefit is that you can get your application onto a computer by a user who does not need administrative privileges to install.
It really comes down to your requirements. If you don't need any features of an installer, then just copying the files is a good approach.
I'd agree with the other comments about using a release build though - especially if you are deploying for real use and not just testing.
The only change you might want to make is to build the app in Release rather than Debug and take the files from the Bin>Release folder.
more info: http://haacked.com/archive/2004/02/14/difference-between-debug-vs-release-build.aspx
When you have multiple files to deploy along with your exe, dll's to register, file associations to set up, then an installer is a neat way to deliver all of that in a reliable manner. If you don't do this with an installer the user could easily screw things up.
In addition to that, the installer is sometimes used as a means to ensure the computer is truly ready for the application. For example, the installers I've written check to ensure the proper version of .NET is installed, and will download & install it if necessary.
However, there are many times when these characteristics are simply not worth it and deploying a standalone application in a single exe is perfectly acceptable. Simple applications that don't need to store a lot of settings on your computer and don't have a lot of prerequisites are perfect examples. The first thing that comes to mind are all the utilities from Sysinternals.
I see only one potencial drawback. There is nowthing wrong in your approach as long as you don't have more than 1 to 3 users and changes during test session are not often.
When changes are often and you have to copy library to more than 3 users (hosts etc.) the drawbac I mean is maintenance time. I know what I'm talking about because in place where I work, we have such issue.
Last time I've started to more taking care about maintaining our application and copying files from one host to another than coding. :(
In my honest opinion sometimes is better to invest your time on the beggining and write an installer than have a lot mainteneance and copy things later.
To solve the number of users problem, there's a very simple solution that does not require to setup a full installer.
Basic setup for multi-users xcopy/.bat deployment:
A shared drive, with one folder for the .bat files, one for the binaries.
Upload the binaries to the shared
drive and update the install script
if needed.
Have every user run the install script.
By the way, some very complex information systems are ENTIRELY deployed by .bat files (even when not testing!).

Patch an application

I need to create a patching routine for my application,
it's really small but I need to update it daily or weekly
how does the xdelta and the others work?
i've read around about those but I didn't understand much of it
the user shouldn't be prompted at all
Ok this post got flagged on meta for the answers given, so I'm going to weigh in on this.
xdelta is a binary difference program that, rather than providing you with a full image, only gives you what has changed and where. An example of a text diff will have + and - signs before lines of text showing you that these have been added or removed in the new version.
There are two ways to update a binary image: replace it using your own program or replace it using some form of package management. For example, Linux Systems use rpm etc to push out updates to packages. In a windows environment your options are limited by what is installed if you're not on a corporate network. If you are, try WSUS and MSI packaging. That'll give you an easier life, or ClickOnce as someone has mentioned.
If you're not however, you will need to bear in mind the following:
You need to be an administrator to update anything in certain folders as others have said. I would strongly encourage you to accept this behaviour.
If the user is an administrator, you can offer to check for updates. Then, you can do one of two things. You can download a whole new version of your application and write it over the image on the hard disk (i.e. the file - remember images are loaded into memory so you can re-write your own program file). You then need to tell the user the update has succeeded and reload the program as the new image will be different.
Or, you can apply a diff if bandwidth is a concern. Probably not in your case but you will need to know from the client program the two versions to diff between so that the update server gives you the correct patch. Otherwise, the diff might not succeed.
I don't think for your purposes xdelta is going to give you much gain anyway. Just replace the entire image.
Edit if the user must not be prompted at all, just reload the app. However, I would strongly encourage informing the user you are talking on their network and ask permission to do so / enable a manual update mode, otherwise people like me will block it.
What kind of application is this ? Perhaps you could use clickonce to deploy your application. Clickonce very easily allows you to push updates to your users.
The short story is, Clickonce creates an installation that allows your users to install the application from a web server or a file share, you enable automatic updates, and whenever you place a new version of the app on the server the app will automatically(or ask the user wether to) update the app. The clickonce framework takes care of the rest - fetching the update , figure out which files have changed and need to be downloaded again and performs the update. You can also check/perform the update programatically.
That said, clickonce leaves you with little control over the actual installation procedure, and you have nowhere close to the freedom of building your own .msi.
I wouldn't go with a patching solution, since it really complicates things when you have a lot of revisions. How will the patching solution handle different versions asking to be updated? What if user A is 10 revisions behind the current revision? Or 100 revisions, etc? It would probably be best to just download the latest exe(s) and dll(s) and replace them.
That said, I think this SO question on silent updates might help you.
There is a solution for efficient patching - it works on all platforms and can run in completely silent mode, without the user noticing anything. On .NET, it provides seamless integration of the update process using a custom UserControl declaratively bound to events from your own UI.
It's called wyUpdate.
While the updating client (wyUpdate) is open source, a paid for wybuild tool is used to build and publish the patches.
Depending on the size of your application, you'd probably have it split up into several dll's, an exe, and other files.
What you could do is have the main program check for updates. If updates are available, the main program would close and the update program would take over - updating old files, creating new ones, and deleting current files as specified by the instructions sent along with a patch file (probably a compressed format such as .zip) downloaded by the updater.
If your application is small (say, a single exe) it would suffice to simply have the updater replace that one exe.
Edit:
Another way to do this would be to (upon compilation of the new exe), compare the new one to the old one, and just send the differences over to the updater. It would then make the appropriate adjustments.
You can make your function reside in a separate DLL. So you can just replace the DLL instead of patching the whole program. (Assuming Windows as the target platform for a C# program.)

best way to write a polled FTP download in C#

I currently have a manual process where we upload a text file to a business partner, they have an automated process which reads in the file, processes it and then generates a 'results' log file any where from 3-10minutes (typically) after the initial upload. I need to automate this process via a .NET application.
I already have the upload completed, what I do not have is the download of the result. Since I dont know exactly when the file will be ready to download I figure that I must need to poll the remote site every so often, get a listing of the files in the results directory and see if one matches what I am expecting.
I have done some reading and found some references to AsyncCallBack but I'm not really sure how to proceed with it. the solution has to be something I can manage without any third-party libraries outside of .net since I have a budget of 0 for this little project.
Any help would be greatly appreciated!
Just have a thread (or your main thread) sleep for x milliseconds and attempt to do the download when it's not sleeping. No need to buy a 3rd party FTP library, FTP is built into .NET (FtpWebRequest and FtpWebResponse). They aren't very good (very bare bones) but will probably do for what you want.

Categories

Resources