Code Focused

Replace a Running Application with a New Version

One situation that can prevent a successful file transfer is when the destination file is, in fact, the program that's doing the copying. Here's how to work around such problems.

The .NET Framework was designed for lazy programmers. Sure, I could write all the code to open a file stream, extract its contents bit by bit and deposit said bits in another location on the hard disk. But why should I, when I have a prepackaged method to do it for me:

System.IO.File.Copy(sourceFile, destFile);

Of course, playing the sluggard has its disadvantages, including the complete failure of such method calls due to security limits, incorrect paths, locked files and other concerns that I like to collectively call "your bug." One situation that can prevent a successful file transfer is when the destination file is, in fact, the program that's doing the copying. An assembly called MyFileCopy.exe cannot replace the active version of MyFileCopy.exe -- at least not directly.

Fortunately, .NET provides sufficient tools to work around this, especially when matched to this bit of Windows insider information: Though you can't replace a running application, you can rename it. To determine if such extra logic is necessary, you need to check whether the destination path is also the running program. That information is available through the assembly objects expressed via reflection:

// Assumes: using System.Reflection;
Assembly currentAssembly = Assembly.GetEntryAssembly();
if (currentAssembly == null)
  currentAssembly = Assembly.GetCallingAssembly();
if (currentAssembly.Location.ToUpper() == destinationFile.ToUpper())
{
  // ----- Workaround code here.
}

If the destination is the running assembly, a rename will be required before bringing in a new copy of the application. It doesn't really matter what you call the renamed version, as long as it makes sense for your application environment. The following statements convert a file with a name like ThisProgram.exe to ThisProgram_OldVersion.exe:

// Assumes: using System.IO;
string appFolder = Path.GetDirectoryName(currentAssembly.Location);
string appName = Path.GetFileNameWithoutExtension(currentAssembly.Location);
string appExtension = Path.GetExtension(currentAssembly.Location);
string archivePath = Path.Combine(appFolder, appName + "_OldVersion" + appExtension);

If such a conflict is happening now, there's a good chance it happened before. Just in case, purge any old version that might already be present:

if (File.Exists(archivePath))
  File.Delete(archivePath);

Now there's nothing to stop the code from renaming the current application:

File.Move(destinationFile, archivePath);

Finally, with the running application no longer taking up space under the destination path name, the file copy can proceed as expected:

// ----- The "true" argument permits overwriting.
File.Copy(sourceFile, destinationFile, true);

Naturally, all of this code should be wrapped up in try/catch blocks, because all of those "your bugs" can so easily detract from my lazy programmer lifestyle.

About the Author

Tim Patrick has spent more than thirty years as a software architect and developer. His two most recent books on .NET development -- Start-to-Finish Visual C# 2015, and Start-to-Finish Visual Basic 2015 -- are available from http://owanipress.com. He blogs regularly at http://wellreadman.com.

comments powered by Disqus

Featured

  • Cloud-Focused .NET Aspire 9.1 Released

    Along with .NET 10 Preview 1, Microsoft released.NET Aspire 9.1, the latest update to its opinionated, cloud-ready stack for building resilient, observable, and configurable cloud-native applications with .NET.

  • Microsoft Ships First .NET 10 Preview

    Microsoft shipped .NET 10 Preview 1, introducing a raft of improvements and fixes across performance, libraries, and the developer experience.

  • C# Dev Kit Previews .NET Aspire Orchestration

    Microsoft's dev team has been busy updating the C# Dev Kit, a Visual Studio Code extension that enhances the C# development experience by providing tools for managing, debugging, and editing C# projects.

  • Hands On: New VS Code Insiders Build Creates Web Page from Image in Seconds

    New Vision support with GitHub Copilot in the latest Visual Studio Code Insiders build takes a user-supplied mockup image and creates a web page from it in seconds, handling all the HTML and CSS.

  • Naive Bayes Regression Using C#

    Dr. James McCaffrey from Microsoft Research presents a complete end-to-end demonstration of the naive Bayes regression technique, where the goal is to predict a single numeric value. Compared to other machine learning regression techniques, naive Bayes regression is usually less accurate, but is simple, easy to implement and customize, works on both large and small datasets, is highly interpretable, and doesn't require tuning any hyperparameters.

Subscribe on YouTube

Upcoming Training Events