示例#1
0
        public IEnumerable <string> GetBindPaths(BindStage stage = BindStage.Normal, string name = null)
        {
            List <string> paths;

            if (this.bindPaths[(int)stage].TryGetValue(name ?? String.Empty, out paths))
            {
                return(paths);
            }

            return(Enumerable.Empty <string>());
        }
示例#2
0
        public void AddBindPaths(IEnumerable <BindPath> paths, BindStage stage)
        {
            Dictionary <string, List <string> > dict = this.bindPaths[(int)stage];

            foreach (BindPath bindPath in paths)
            {
                List <string> values;
                if (!dict.TryGetValue(bindPath.Name, out values))
                {
                    values = new List <string>();
                    dict.Add(bindPath.Name, values);
                }

                if (!values.Contains(bindPath.Path))
                {
                    values.Add(bindPath.Path);
                }
            }
        }
        public void AddBindPaths(IEnumerable <BindPath> paths, BindStage stage)
        {
            Dictionary <string, List <string> > dict;

            if (!this.bindPaths.TryGetValue(stage, out dict))
            {
                throw new ArgumentException("stage");
            }

            foreach (BindPath bindPath in paths)
            {
                List <string> values;
                if (!dict.TryGetValue(bindPath.Name, out values))
                {
                    values = new List <string>();
                    dict.Add(bindPath.Name, values);
                }

                if (!values.Contains(bindPath.Path))
                {
                    values.Add(bindPath.Path);
                }
            }
        }
 public virtual string ResolveFile(string source, IntermediateTupleDefinition tupleDefinition, SourceLineNumber sourceLineNumbers, BindStage bindStage)
 {
     return(null);
 }
示例#5
0
        /// <summary>
        /// Resolves the source path of a file.
        /// </summary>
        /// <param name="source">Original source value.</param>
        /// <param name="type">Optional type of source file being resolved.</param>
        /// <param name="sourceLineNumbers">Optional source line of source file being resolved.</param>
        /// <param name="bindStage">The binding stage used to determine what collection of bind paths will be used</param>
        /// <returns>Should return a valid path for the stream to be imported.</returns>
        public virtual string ResolveFile(string source, string type, SourceLineNumber sourceLineNumbers, BindStage bindStage)
        {
            if (String.IsNullOrEmpty(source))
            {
                throw new ArgumentNullException("source");
            }

            if (BinderFileManager.CheckFileExists(source)) // if the file exists, we're good to go.
            {
                return(source);
            }
            else if (Path.IsPathRooted(source)) // path is rooted so bindpaths won't help, bail since the file apparently doesn't exist.
            {
                return(null);
            }
            else // not a rooted path so let's try applying all the different source resolution options.
            {
                const string bindPathOpenString = "!(bindpath.";

                string bindName             = String.Empty;
                string path                 = source;
                string pathWithoutSourceDir = null;

                if (source.StartsWith(bindPathOpenString, StringComparison.Ordinal))
                {
                    int closeParen = source.IndexOf(')', bindPathOpenString.Length);
                    if (-1 != closeParen)
                    {
                        bindName = source.Substring(bindPathOpenString.Length, closeParen - bindPathOpenString.Length);
                        path     = source.Substring(bindPathOpenString.Length + bindName.Length + 1); // +1 for the closing brace.
                        path     = path.TrimStart('\\');                                              // remove starting '\\' char so the path doesn't look rooted.
                    }
                }
                else if (source.StartsWith("SourceDir\\", StringComparison.Ordinal) || source.StartsWith("SourceDir/", StringComparison.Ordinal))
                {
                    pathWithoutSourceDir = path.Substring(10);
                }

                var bindPaths = this.Core.GetBindPaths(bindStage, bindName);
                foreach (string bindPath in bindPaths)
                {
                    string filePath;
                    if (!String.IsNullOrEmpty(pathWithoutSourceDir))
                    {
                        filePath = Path.Combine(bindPath, pathWithoutSourceDir);
                        if (BinderFileManager.CheckFileExists(filePath))
                        {
                            return(filePath);
                        }
                    }

                    filePath = Path.Combine(bindPath, path);
                    if (BinderFileManager.CheckFileExists(filePath))
                    {
                        return(filePath);
                    }
                }
            }

            // Didn't find the file.
            return(null);
        }
示例#6
0
        /// <summary>
        /// Resolves the source path of a file related to another file's source.
        /// </summary>
        /// <param name="source">Original source value.</param>
        /// <param name="relatedSource">Source related to original source.</param>
        /// <param name="type">Optional type of source file being resolved.</param>
        /// <param name="sourceLineNumbers">Optional source line of source file being resolved.</param>
        /// <param name="bindStage">The binding stage used to determine what collection of bind paths will be used</param>
        /// <returns>Should return a valid path for the stream to be imported.</returns>
        public virtual string ResolveRelatedFile(string source, string relatedSource, string type, SourceLineNumber sourceLineNumbers, BindStage bindStage)
        {
            string resolvedSource = this.ResolveFile(source, type, sourceLineNumbers, bindStage);

            return(Path.Combine(Path.GetDirectoryName(resolvedSource), relatedSource));
        }
示例#7
0
        /// <summary>
        /// Resolves the source path of a file using binder extensions.
        /// </summary>
        /// <param name="source">Original source value.</param>
        /// <param name="type">Optional type of source file being resolved.</param>
        /// <param name="sourceLineNumbers">Optional source line of source file being resolved.</param>
        /// <param name="bindStage">The binding stage used to determine what collection of bind paths will be used</param>
        /// <returns>Should return a valid path for the stream to be imported.</returns>
        public string ResolveFile(string source, IntermediateTupleDefinition tupleDefinition, SourceLineNumber sourceLineNumbers, BindStage bindStage)
        {
            foreach (var extension in this.ResolverExtensions)
            {
                var resolved = extension.ResolveFile(source, tupleDefinition, sourceLineNumbers, bindStage);

                if (null != resolved)
                {
                    return(resolved);
                }
            }

            return(this.ResolveUsingBindPaths(source, tupleDefinition, sourceLineNumbers, bindStage));
        }
示例#8
0
        /// <summary>
        /// Resolves the source path of a file using binder extensions.
        /// </summary>
        /// <param name="source">Original source value.</param>
        /// <param name="type">Optional type of source file being resolved.</param>
        /// <param name="sourceLineNumbers">Optional source line of source file being resolved.</param>
        /// <param name="bindStage">The binding stage used to determine what collection of bind paths will be used</param>
        /// <param name="alreadyCheckedPaths">Optional collection of paths already checked.</param>
        /// <returns>Should return a valid path for the stream to be imported.</returns>
        public string ResolveFile(string source, IntermediateSymbolDefinition symbolDefinition, SourceLineNumber sourceLineNumbers, BindStage bindStage, IEnumerable <string> alreadyCheckedPaths = null)
        {
            var checkedPaths = new List <string>();

            if (alreadyCheckedPaths != null)
            {
                checkedPaths.AddRange(alreadyCheckedPaths);
            }

            foreach (var extension in this.ResolverExtensions)
            {
                var resolved = extension.ResolveFile(source, symbolDefinition, sourceLineNumbers, bindStage);

                if (resolved?.CheckedPaths != null)
                {
                    checkedPaths.AddRange(resolved.CheckedPaths);
                }

                if (!String.IsNullOrEmpty(resolved?.Path))
                {
                    return(resolved?.Path);
                }
            }

            return(this.MustResolveUsingBindPaths(source, symbolDefinition, sourceLineNumbers, bindStage, checkedPaths));
        }
示例#9
0
        private string ResolveFile(string source, string type, SourceLineNumber sourceLineNumbers, BindStage bindStage)
        {
            string path = null;

            foreach (IBinderFileManager fileManager in this.FileManagers)
            {
                path = fileManager.ResolveFile(source, type, sourceLineNumbers, bindStage);
                if (null != path)
                {
                    break;
                }
            }

            if (null == path)
            {
                throw new WixFileNotFoundException(sourceLineNumbers, source, type);
            }

            return(path);
        }
示例#10
0
        private string ResolveFile(string source, string type, SourceLineNumber sourceLineNumbers, BindStage bindStage = BindStage.Normal)
        {
            string path = null;

            foreach (var extension in this.Extensions)
            {
                path = extension.ResolveFile(source, type, sourceLineNumbers, bindStage);
                if (null != path)
                {
                    break;
                }
            }

            throw new NotImplementedException(); // need to do default binder stuff

            //if (null == path)
            //{
            //    throw new WixFileNotFoundException(sourceLineNumbers, source, type);
            //}

            //return path;
        }
        private string ResolveRelatedFile(string resolvedSource, string unresolvedSource, string relatedSource, string type, SourceLineNumber sourceLineNumbers, BindStage stage)
        {
            var checkedPaths = new List <string>();

            foreach (var extension in this.BackendExtensions)
            {
                var resolved = extension.ResolveRelatedFile(unresolvedSource, relatedSource, type, sourceLineNumbers, stage);

                if (resolved?.CheckedPaths != null)
                {
                    checkedPaths.AddRange(resolved.CheckedPaths);
                }

                if (!String.IsNullOrEmpty(resolved?.Path))
                {
                    return(resolved?.Path);
                }
            }

            var resolvedPath = Path.Combine(Path.GetDirectoryName(resolvedSource), relatedSource);

            if (!File.Exists(resolvedPath))
            {
                checkedPaths.Add(resolvedPath);
                this.Messaging.Write(ErrorMessages.FileNotFound(sourceLineNumbers, resolvedPath, type, checkedPaths));
            }

            return(resolvedPath);
        }
 /// <summary>
 ///
 /// </summary>
 /// <param name="source"></param>
 /// <param name="relatedSource"></param>
 /// <param name="type"></param>
 /// <param name="sourceLineNumbers"></param>
 /// <param name="bindStage"></param>
 /// <returns></returns>
 public virtual IResolveFileResult ResolveRelatedFile(string source, string relatedSource, string type, SourceLineNumber sourceLineNumbers, BindStage bindStage)
 {
     return(null);
 }
示例#13
0
        private string ResolveRelatedFile(string sourceFile, string relatedSource, string type, SourceLineNumber sourceLineNumbers, BindStage stage)
        {
            foreach (var extension in this.BackendExtensions)
            {
                var relatedFile = extension.ResolveRelatedFile(sourceFile, relatedSource, type, sourceLineNumbers, stage);

                if (!String.IsNullOrEmpty(relatedFile))
                {
                    return(relatedFile);
                }
            }

            return(null);
        }
示例#14
0
文件: retina.cs 项目: zooba/wix3
            /// <summary>
            /// Resolves the source path of a file to a normalized path relative to the Wixlib.
            /// </summary>
            /// <param name="source">Original source value.</param>
            /// <param name="type">Optional type of source file being resolved.</param>
            /// <param name="sourceLineNumbers">Optional source line of source file being resolved.</param>
            /// <param name="bindStage">The binding stage used to determine what collection of bind paths will be used</param>
            /// <returns>Should return a valid path for the stream to be imported.</returns>
            public override string ResolveFile(string source, string type, SourceLineNumberCollection sourceLineNumbers, BindStage bindStage)
            {
                Match match = BlastBinderFileManager.WixVariableRegex.Match(source);
                if (match.Success)
                {
                    string variableNamespace = match.Groups["namespace"].Value;
                    if ("wix" == variableNamespace && match.Groups["value"].Success)
                    {
                        source = match.Groups["value"].Value;
                    }
                    else if ("bindpath" == variableNamespace)
                    {
                        string dir = String.Concat("bindpath_", match.Groups["fullname"].Value);
                        // bindpaths might or might not be followed by a backslash, depending on the pedantic nature of the author
                        string file = source.Substring(match.Length).TrimStart(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
                        source = Path.Combine(dir, file);
                    }
                }

                if (Path.IsPathRooted(source))
                {
                    source = Path.GetFileName(source);
                }

                if (source.StartsWith("SourceDir\\", StringComparison.Ordinal) || source.StartsWith("SourceDir/", StringComparison.Ordinal))
                {
                    source = source.Substring(10);
                }

                return Path.Combine(this.basePath, source);
            }
示例#15
0
        /// <summary>
        /// Resolves the source path of a file.
        /// </summary>
        /// <param name="source">Original source value.</param>
        /// <param name="type">Optional type of source file being resolved.</param>
        /// <param name="sourceLineNumbers">Optional source line of source file being resolved.</param>
        /// <param name="bindStage">The binding stage used to determine what collection of bind paths will be used</param>
        /// <returns>Should return a valid path for the stream to be imported.</returns>
        public virtual string ResolveFile(string source, string type, SourceLineNumberCollection sourceLineNumbers, BindStage bindStage)
        {
            // the following new local variables are used for bind path and protect the changes to object field.
            StringCollection currentBindPaths = null;
            NameValueCollection currentNamedBindPaths = null;
            StringCollection currentSourcePaths = null;

            if (String.IsNullOrEmpty(source))
            {
                throw new ArgumentNullException("source");
            }

            // Call the original override function first. If it returns an answer then return that,
            // otherwise using the default resolving logic
            string filePath = this.ResolveFile(source, type, sourceLineNumbers);
            if (!String.IsNullOrEmpty(filePath))
            {
                return filePath;
            }

            // Assign the correct bind path to file manager
            currentSourcePaths = this.sourcePaths[bindStage];
            currentNamedBindPaths = this.namedBindPaths[bindStage];
            if (BindStage.Target != bindStage && BindStage.Updated != bindStage)
            {
                currentBindPaths = this.bindPaths[bindStage];
            }
            else
            {
                currentBindPaths = this.sourcePaths[bindStage];
            }

            // If the path is rooted, it better exist or we're not going to find it.
            if (Path.IsPathRooted(source))
            {
                if (BinderFileManager.CheckFileExists(source))
                {
                    return source;
                }
            }
            else // not a rooted path so let's try applying all the different source resolution options.
            {
                const string bindPathOpenString = "!(bindpath.";

                if (source.StartsWith(bindPathOpenString, StringComparison.Ordinal) && source.IndexOf(')') != -1)
                {
                    int bindpathSignatureLength = bindPathOpenString.Length;
                    string name = source.Substring(bindpathSignatureLength, source.IndexOf(')') - bindpathSignatureLength);
                    string[] values = currentNamedBindPaths.GetValues(name);

                    if (null != values)
                    {
                        foreach (string bindPath in values)
                        {
                            // Parse out '\\' chars that separate the "bindpath" variable and the next part of the path, 
                            // because Path.Combine() thinks that rooted second paths don't need the first path.
                            string nameSection = string.Empty;
                            int nameStart = bindpathSignatureLength + 1 + name.Length;  // +1 for the closing bracket.

                            nameSection = source.Substring(nameStart).TrimStart('\\');
                            filePath = Path.Combine(bindPath, nameSection);

                            if (BinderFileManager.CheckFileExists(filePath))
                            {
                                return filePath;
                            }
                        }
                    }
                }
                else if (source.StartsWith("SourceDir\\", StringComparison.Ordinal) || source.StartsWith("SourceDir/", StringComparison.Ordinal))
                {
                    foreach (string bindPath in currentBindPaths)
                    {
                        filePath = Path.Combine(bindPath, source.Substring(10));
                        if (BinderFileManager.CheckFileExists(filePath))
                        {
                            return filePath;
                        }
                    }
                }
                else if (BinderFileManager.CheckFileExists(source))
                {
                    return source;
                }

                foreach (string path in currentSourcePaths)
                {
                    filePath = Path.Combine(path, source);
                    if (BinderFileManager.CheckFileExists(filePath))
                    {
                        return filePath;
                    }

                    if (source.StartsWith("SourceDir\\", StringComparison.Ordinal) || source.StartsWith("SourceDir/", StringComparison.Ordinal))
                    {
                        filePath = Path.Combine(path, source.Substring(10));
                        if (BinderFileManager.CheckFileExists(filePath))
                        {
                            return filePath;
                        }
                    }
                }
            }

            // Didn't find the file.
            throw new WixFileNotFoundException(sourceLineNumbers, source, type);
        }
示例#16
0
 /// <summary>
 /// See <see cref="IResolverExtension.ResolveFile(string, IntermediateSymbolDefinition, SourceLineNumber, BindStage)"/>
 /// </summary>
 /// <param name="source"></param>
 /// <param name="symbolDefinition"></param>
 /// <param name="sourceLineNumbers"></param>
 /// <param name="bindStage"></param>
 /// <returns></returns>
 public virtual IResolveFileResult ResolveFile(string source, IntermediateSymbolDefinition symbolDefinition, SourceLineNumber sourceLineNumbers, BindStage bindStage)
 {
     return(null);
 }
示例#17
0
 /// <summary>
 /// Resolves the source path of a file related to another file's source.
 /// </summary>
 /// <param name="source">Original source value.</param>
 /// <param name="relatedSource">Source related to original source.</param>
 /// <param name="type">Optional type of source file being resolved.</param>
 /// <param name="sourceLineNumbers">Optional source line of source file being resolved.</param>
 /// <param name="bindStage">The binding stage used to determine what collection of bind paths will be used</param>
 /// <returns>Should return a valid path for the stream to be imported.</returns>
 public virtual string ResolveRelatedFile(string source, string relatedSource, string type, SourceLineNumberCollection sourceLineNumbers, BindStage bindStage)
 {
     string resolvedSource = this.ResolveFile(source, type, sourceLineNumbers, bindStage);
     return Path.Combine(Path.GetDirectoryName(resolvedSource), relatedSource);
 }
示例#18
0
        private string MustResolveUsingBindPaths(string source, IntermediateSymbolDefinition symbolDefinition, SourceLineNumber sourceLineNumbers, BindStage bindStage, List <string> checkedPaths)
        {
            string resolved = null;

            // If the file exists, we're good to go.
            checkedPaths.Add(source);
            if (CheckFileExists(source))
            {
                resolved = source;
            }
            else if (Path.IsPathRooted(source)) // path is rooted so bindpaths won't help, bail since the file apparently doesn't exist.
            {
                resolved = null;
            }
            else // not a rooted path so let's try applying all the different source resolution options.
            {
                string bindName             = null;
                var    path                 = source;
                string pathWithoutSourceDir = null;

                if (source.StartsWith(BindPathOpenString, StringComparison.Ordinal))
                {
                    int closeParen = source.IndexOf(')', BindPathOpenString.Length);
                    if (-1 != closeParen)
                    {
                        bindName = source.Substring(BindPathOpenString.Length, closeParen - BindPathOpenString.Length);
                        path     = source.Substring(BindPathOpenString.Length + bindName.Length + 1); // +1 for the closing brace.
                        path     = path.TrimStart('\\');                                              // remove starting '\\' char so the path doesn't look rooted.
                    }
                }
                else if (source.StartsWith("SourceDir\\", StringComparison.Ordinal) || source.StartsWith("SourceDir/", StringComparison.Ordinal))
                {
                    pathWithoutSourceDir = path.Substring(10);
                }

                var bindPaths = this.BindPaths[bindStage];

                foreach (var bindPath in bindPaths)
                {
                    if (!String.IsNullOrEmpty(bindName) && !String.IsNullOrEmpty(bindPath.Name))
                    {
                        if (String.Equals(bindName, bindPath.Name, StringComparison.OrdinalIgnoreCase) && String.IsNullOrEmpty(resolved))
                        {
                            var filePath = Path.Combine(bindPath.Path, path);

                            checkedPaths.Add(filePath);
                            if (CheckFileExists(filePath))
                            {
                                resolved = filePath;
                            }
                        }
                    }
                    else
                    {
                        if (!String.IsNullOrEmpty(pathWithoutSourceDir))
                        {
                            var filePath = Path.Combine(bindPath.Path, pathWithoutSourceDir);

                            checkedPaths.Add(filePath);
                            if (CheckFileExists(filePath))
                            {
                                resolved = filePath;
                            }
                        }

                        if (String.IsNullOrEmpty(resolved))
                        {
                            var filePath = Path.Combine(bindPath.Path, path);

                            checkedPaths.Add(filePath);
                            if (CheckFileExists(filePath))
                            {
                                resolved = filePath;
                            }
                        }
                    }
                }
            }

            if (null == resolved)
            {
                throw new WixException(ErrorMessages.FileNotFound(sourceLineNumbers, source, symbolDefinition.Name, checkedPaths));
            }

            return(resolved);
        }
示例#19
0
        /// <summary>
        /// Resolves the source path of a file.
        /// </summary>
        /// <param name="source">Original source value.</param>
        /// <param name="type">Optional type of source file being resolved.</param>
        /// <param name="sourceLineNumbers">Optional source line of source file being resolved.</param>
        /// <param name="bindStage">The binding stage used to determine what collection of bind paths will be used</param>
        /// <returns>Should return a valid path for the stream to be imported.</returns>
        public virtual string ResolveFile(string source, string type, SourceLineNumberCollection sourceLineNumbers, BindStage bindStage)
        {
            // the following new local variables are used for bind path and protect the changes to object field.
            StringCollection    currentBindPaths      = null;
            NameValueCollection currentNamedBindPaths = null;
            StringCollection    currentSourcePaths    = null;

            if (String.IsNullOrEmpty(source))
            {
                throw new ArgumentNullException("source");
            }

            // Call the original override function first. If it returns an answer then return that,
            // otherwise using the default resolving logic
            string filePath = this.ResolveFile(source, type, sourceLineNumbers);

            if (!String.IsNullOrEmpty(filePath))
            {
                return(filePath);
            }

            // Assign the correct bind path to file manager
            currentSourcePaths    = this.sourcePaths[bindStage];
            currentNamedBindPaths = this.namedBindPaths[bindStage];
            if (BindStage.Target != bindStage && BindStage.Updated != bindStage)
            {
                currentBindPaths = this.bindPaths[bindStage];
            }
            else
            {
                currentBindPaths = this.sourcePaths[bindStage];
            }

            // If the path is rooted, it better exist or we're not going to find it.
            if (Path.IsPathRooted(source))
            {
                if (BinderFileManager.CheckFileExists(source))
                {
                    return(source);
                }
            }
            else // not a rooted path so let's try applying all the different source resolution options.
            {
                const string bindPathOpenString = "!(bindpath.";

                if (source.StartsWith(bindPathOpenString, StringComparison.Ordinal) && source.IndexOf(')') != -1)
                {
                    int      bindpathSignatureLength = bindPathOpenString.Length;
                    string   name   = source.Substring(bindpathSignatureLength, source.IndexOf(')') - bindpathSignatureLength);
                    string[] values = currentNamedBindPaths.GetValues(name);

                    if (null != values)
                    {
                        foreach (string bindPath in values)
                        {
                            // Parse out '\\' chars that separate the "bindpath" variable and the next part of the path,
                            // because Path.Combine() thinks that rooted second paths don't need the first path.
                            string nameSection = string.Empty;
                            int    nameStart   = bindpathSignatureLength + 1 + name.Length; // +1 for the closing bracket.

                            nameSection = source.Substring(nameStart).TrimStart('\\');
                            filePath    = Path.Combine(bindPath, nameSection);

                            if (BinderFileManager.CheckFileExists(filePath))
                            {
                                return(filePath);
                            }
                        }
                    }
                }
                else if (source.StartsWith("SourceDir\\", StringComparison.Ordinal) || source.StartsWith("SourceDir/", StringComparison.Ordinal))
                {
                    foreach (string bindPath in currentBindPaths)
                    {
                        filePath = Path.Combine(bindPath, source.Substring(10));
                        if (BinderFileManager.CheckFileExists(filePath))
                        {
                            return(filePath);
                        }
                    }
                }
                else if (BinderFileManager.CheckFileExists(source))
                {
                    return(source);
                }

                foreach (string path in currentSourcePaths)
                {
                    filePath = Path.Combine(path, source);
                    if (BinderFileManager.CheckFileExists(filePath))
                    {
                        return(filePath);
                    }

                    if (source.StartsWith("SourceDir\\", StringComparison.Ordinal) || source.StartsWith("SourceDir/", StringComparison.Ordinal))
                    {
                        filePath = Path.Combine(path, source.Substring(10));
                        if (BinderFileManager.CheckFileExists(filePath))
                        {
                            return(filePath);
                        }
                    }
                }
            }

            // Didn't find the file.
            throw new WixFileNotFoundException(sourceLineNumbers, source, type);
        }
示例#20
0
            /// <summary>
            /// Resolves the source path of a file to a normalized path relative to the Wixlib.
            /// </summary>
            /// <param name="source">Original source value.</param>
            /// <param name="type">Optional type of source file being resolved.</param>
            /// <param name="sourceLineNumbers">Optional source line of source file being resolved.</param>
            /// <param name="bindStage">The binding stage used to determine what collection of bind paths will be used</param>
            /// <returns>Should return a valid path for the stream to be imported.</returns>
            public override string ResolveFile(string source, string type, SourceLineNumber sourceLineNumbers, BindStage bindStage)
            {
                Match match = BlastBinderFileManager.WixVariableRegex.Match(source);

                if (match.Success)
                {
                    string variableNamespace = match.Groups["namespace"].Value;
                    if ("wix" == variableNamespace && match.Groups["value"].Success)
                    {
                        source = match.Groups["value"].Value;
                    }
                    else if ("bindpath" == variableNamespace)
                    {
                        string dir = String.Concat("bindpath_", match.Groups["fullname"].Value);
                        // bindpaths might or might not be followed by a backslash, depending on the pedantic nature of the author
                        string file = source.Substring(match.Length).TrimStart(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
                        source = Path.Combine(dir, file);
                    }
                }

                if (Path.IsPathRooted(source))
                {
                    source = Path.GetFileName(source);
                }

                if (source.StartsWith("SourceDir\\", StringComparison.Ordinal) || source.StartsWith("SourceDir/", StringComparison.Ordinal))
                {
                    source = source.Substring(10);
                }

                return(Path.Combine(this.basePath, source));
            }
 /// <summary>
 /// Unused.
 /// </summary>
 public IResolveFileResult ResolveFile(string source, IntermediateSymbolDefinition symbolDefinition, SourceLineNumber sourceLineNumbers, BindStage bindStage) => null;