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

  • IDE Irony: Coding Errors Cause 'Critical' Vulnerability in Visual Studio

    In a larger-than-normal Patch Tuesday, Microsoft warned of a "critical" vulnerability in Visual Studio that should be fixed immediately if automatic patching isn't enabled, ironically caused by coding errors.

  • Building Blazor Applications

    A trio of Blazor experts will conduct a full-day workshop for devs to learn everything about the tech a a March developer conference in Las Vegas keynoted by Microsoft execs and featuring many Microsoft devs.

  • Gradient Boosting Regression Using C#

    Dr. James McCaffrey from Microsoft Research presents a complete end-to-end demonstration of the gradient boosting regression technique, where the goal is to predict a single numeric value. Compared to existing library implementations of gradient boosting regression, a from-scratch implementation allows much easier customization and integration with other .NET systems.

  • Microsoft Execs to Tackle AI and Cloud in Dev Conference Keynotes

    AI unsurprisingly is all over keynotes that Microsoft execs will helm to kick off the Visual Studio Live! developer conference in Las Vegas, March 10-14, which the company described as "a must-attend event."

  • Copilot Agentic AI Dev Environment Opens Up to All

    Microsoft removed waitlist restrictions for some of its most advanced GenAI tech, Copilot Workspace, recently made available as a technical preview.

Subscribe on YouTube