#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