示例#1
0
        /// <summary>
        /// Registry string value alterer which makes virtual registry rebase path string values
        /// to the current directory or subdirs if the file exists there.
        /// </summary>
        /// <param name="value">string value being read</param>
        /// <returns>altered string value</returns>
        internal string RebasePath(KeyIdentity key, string valueName, string value)
        {
            // Performance heuristic: return if it has no path or file name components inside the string.
            if (!(value.Contains("\\") || value.Contains(".")))
            {
                return(value);
            }
            // Performance heuristic: return if it is version/progid in HKCR
            if ((key.BaseKey == (IntPtr)Win32Api.RegPredefinedKeys.HKEY_CLASSES_ROOT ||
                 (key.BaseKey == (IntPtr)Win32Api.RegPredefinedKeys.HKEY_CURRENT_USER &&
                  key.GetRegPath().StartsWith(@"Software\Classes\", StringComparison.CurrentCultureIgnoreCase))))
            {
                if (string.Compare(valueName, "Version", ignoreCase: true) == 0 ||
                    string.Compare(valueName, "Progid", ignoreCase: true) == 0
                    // InprocServer32 value is not the same as default value of InprocServer32 key
                    // and it contains not a path but "Darwin Descriptor" used by installer
                    || string.Compare(valueName, "InprocServer32", ignoreCase: true) == 0)
                {
                    return(value);
                }
                if (string.IsNullOrEmpty(valueName) &&
                    key.GetRegPath().EndsWith(@"\Progid", StringComparison.CurrentCultureIgnoreCase))
                {
                    return(value);
                }
            }

            value = value.TrimEnd('\\');//some of the code below depends on a trailing \ not being there

            // Checking if it is a path and the path exists
            if (File.Exists(value) || Directory.Exists(value))
            {
                DebugLogger.WriteLine("RebasePath skipped, path already exists: {0}", value);
                return(value);
            }
            string filename;

            try
            {
                filename = Path.GetFileName(value);
            }
            catch (Exception ex)
            {
                DebugLogger.WriteLine("RebasePath failed {0} ex: {1}", value, ex.Message);
                return(value);
            }

            // Checking if file pointed by path exists in the directory where .exe resides
            try
            {
                //TODO: this is expensive, do it once for the whole process i.e. cache list of directories and files after first retrieval ... check impact in memory usage though
                //TODO: this can lead to *very* hard to debug situations.
                //One special situation is filenames without extensions that could also map to the name of a folder in some other path
                //Another situation happened with 1379, a zip file contained a path c\program files\..., which can actually happen in some titles (although may have been due to auto conversion issues)
                //Another situation would be parts of paths that repeat in the tree, and rebasing a relative path ... we'd match the deepest one while there is no way to know the intended one
                string titleRoot = Utils.GetRootSearchDir();

                List <string> files   = new List <string>();
                List <string> folders = new List <string>();
                GetFilesAndFoldersFromCache(filename, folders, files);

                var fileList = files.ToArray(); //Directory.GetFiles(titleRoot, filename, SearchOption.AllDirectories);
                if (fileList.Length > 0)
                {
                    string newFilePath = fileList[MaxMatch(fileList, value)];
                    DebugLogger.WriteLine("RebasePath {0} to: {1}", value, newFilePath);
                    return(newFilePath);
                }
                var dirList = folders.ToArray(); //Directory.GetDirectories(titleRoot, filename, SearchOption.AllDirectories);
                if (dirList.Length > 0)
                {
                    string newFilePath = dirList[MaxMatch(dirList, value)];
                    DebugLogger.WriteLine("RebasePath {0} to: {1}", value, newFilePath);
                    return(newFilePath);
                }
                DebugLogger.WriteLine("RebasePath failed to find {0}, title root: {1}, filename: {2}", value, titleRoot, filename);
            }
            catch (Exception ex)
            {
                DebugLogger.WriteLine("RebasePath failed to find {0} ex: {1}", value, ex.ToString());
                return(value);
            }
            return(value);
        }
示例#2
0
 private void InitCache()
 {
     GetFilesAndFolders(Utils.GetRootSearchDir(), "*", folders_, files_);
 }