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

  • 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.

  • VS Code Copilot Previews New GPT-4o AI Code Completion Model

    The 4o upgrade includes additional training on more than 275,000 high-quality public repositories in over 30 popular programming languages, said Microsoft-owned GitHub, which created the original "AI pair programmer" years ago.

  • Microsoft's Rust Embrace Continues with Azure SDK Beta

    "Rust's strong type system and ownership model help prevent common programming errors such as null pointer dereferencing and buffer overflows, leading to more secure and stable code."

  • Xcode IDE from Microsoft Archrival Apple Gets Copilot AI

    Just after expanding the reach of its Copilot AI coding assistant to the open-source Eclipse IDE, Microsoft showcased how it's going even further, providing details about a preview version for the Xcode IDE from archrival Apple.

Subscribe on YouTube

Upcoming Training Events