#region CPL License
/*
Nuclex.NAnt.Tasks
Copyright (C) 2009 Nuclex Development Labs
This library is free software; you can redistribute it and/or
modify it under the terms of the IBM Common Public License as
published by the IBM Corporation; either version 1.0 of the
License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
IBM Common Public License for more details.
You should have received a copy of the IBM Common Public
License along with this library
*/
#endregion
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using Microsoft.Win32;
namespace Nuclex.NAnt.Tasks.Helpers {
/// Helper class that tries to locate the 7-Zip executable
internal static class SevenZipLocator {
/// Tries to locate the 7-Zip executable on the current system
///
/// You do not need to call this normally. The 'Location' property will
/// automatically initiate a search the first time it is called. Only call
/// this method if you suspect the system might have changed and wish to
/// rescan for the 7-Zip executable.
///
public static void Locate() {
if(OsHelper.IsWindows) {
location = findUsingRegistry();
if(location == null) {
location = findOnWindows();
}
} else {
location = findOnUnix();
}
locationAttempted = true;
}
/// The location of the 7-Zip executable or null if not found
///
/// Will search for 7-Zip on the system the first time it is called, so it
/// may block for a moment before returning.
///
public static string Location {
get {
if(!locationAttempted) {
Locate();
}
return location;
}
}
/// Tries to locate 7-Zip using its registry path
/// The path to the 7-Zip executable or null if not found
private static string findUsingRegistry() {
Debug.Assert(OsHelper.IsWindows);
// This has a major issue on x64 systems because NAnt runs in x86 mode,
// so it will look in the Wow6432Node whereas 7-Zip's registry key
// (assuming the x64 version is being used) is in the normal SOFTWARE node.
using(
RegistryKey sevenZipKey = Registry.LocalMachine.OpenSubKey(
@"SOFTWARE\7-Zip"
)
) {
if(sevenZipKey == null) {
return null;
}
string location = (string)sevenZipKey.GetValue("Path");
if(Directory.Exists(location)) {
location = Path.Combine(location, "7z.exe");
if(File.Exists(location)) {
return location;
}
}
}
return null;
}
/// Tries to locate 7-Zip in its default path on a windows system
/// The path to the 7-Zip executable or null if not found
private static string findOnWindows() {
Debug.Assert(OsHelper.IsWindows);
// If we're running on a 64 bit OS, search the 64 bit program files folder, too.
// 7-Zip provides 64 bit executables, so it might very well be in this folder.
if(EnvironmentHelper.RunningOn64BitOS) {
string location = searchWindowsProgramFilesFolder(KnownFolders.ProgramFiles64Path);
if(location != null) {
return location;
}
}
return searchWindowsProgramFilesFolder(KnownFolders.ProgramFiles32Path);
}
/// Searches the program files folder for a 7-Zip executable
/// The path to the 7-Zip executable or null if not found
private static string searchWindowsProgramFilesFolder(string programFilesFolder) {
string[] sevenZipFolders = Directory.GetDirectories(
programFilesFolder, "7-Zip*"
);
for(int index = 0; index < sevenZipFolders.Length; ++index) {
string potentialLocation = Path.Combine(sevenZipFolders[index], "7z.exe");
if(File.Exists(potentialLocation)) {
return potentialLocation;
}
}
return null;
}
/// Tries to locate 7-Zip in its default path on a unix system
/// The path to the 7-Zip executable or null if not found
private static string findOnUnix() {
Debug.Assert(OsHelper.IsUnix);
string sevenZipPath = "/usr/local/bin/7za";
if(File.Exists(sevenZipPath)) {
return sevenZipPath;
}
sevenZipPath = "/usr/bin/7za";
if(File.Exists(sevenZipPath)) {
return sevenZipPath;
}
sevenZipPath = "/bin/7za";
if(File.Exists(sevenZipPath)) {
return sevenZipPath;
}
return null;
}
/// Whether we attempted to locate 7-Zip already
private static volatile bool locationAttempted;
/// The location of the 7-Zip executable or null
private static string location;
}
} // namespace Nuclex.NAnt.Tasks.Helpers