none
upgraded from .net 4.6.1 to 4.6.2 and started getting this error

    Question

  • in a third party product that fortunately we have the source to, we are getting the 'Not a legal path' error when this function is called in .net 4.6.2.  It works fine in .net 4.6.1.  Any thoughts?

    /// <summary>
    /// get directory path of Service.dll
    /// </summary>
    /// <returns></returns>
    protected string GetGetExecutingAssemblyDirectory()
    {
    string path=System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
    return path;
    }

    Thursday, April 20, 2017 10:30 PM

Answers

All replies

  • Hi Alltium,

    Thank you for posting here.

    For your question, I test your code and get the same error. The error caused by the difference between source code of .net framework 4.6.1 and source code of .net framework 4.6.2.

    .net framework 4.6.1 source code

       // Returns the directory path of a file path. This method effectively
            // removes the last element of the given file path, i.e. it returns a
            // string consisting of all characters up to but not including the last
            // backslash ("\") in the file path. The returned value is null if the file
            // path is null or if the file path denotes a root (such as "\", "C:", or
            // "\\server\share").
            //
            [ResourceExposure(ResourceScope.None)]
            [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
            public static String GetDirectoryName(String path)
            {
                if (path != null)
                {
                    CheckInvalidPathChars(path);
    
                  #if FEATURE_LEGACYNETCF
                    if (!CompatibilitySwitches.IsAppEarlierThanWindowsPhone8) {
                  #endif
    
                    string normalizedPath = NormalizePath(path, false);
    
                    // If there are no permissions for PathDiscovery to this path, we should NOT expand the short paths
                    // as this would leak information about paths to which the user would not have access to.
                    if (path.Length > 0)
                    {
                        try
                        {
                            // If we were passed in a path with \\?\ we need to remove it as FileIOPermission does not like it.
                            string tempPath = Path.RemoveLongPathPrefix(path);
    
                            // FileIOPermission cannot handle paths that contain ? or *
                            // So we only pass to FileIOPermission the text up to them.
                            int pos = 0;
                            while (pos < tempPath.Length && (tempPath[pos] != '?' && tempPath[pos] != '*'))
                                pos++;
    
                            // GetFullPath will Demand that we have the PathDiscovery FileIOPermission and thus throw 
                            // SecurityException if we don't. 
                            // While we don't use the result of this call we are using it as a consistent way of 
                            // doing the security checks. 
                            if (pos > 0)
                                Path.GetFullPath(tempPath.Substring(0, pos));
                        }
                        catch (SecurityException)
                        {
                            // If the user did not have permissions to the path, make sure that we don't leak expanded short paths
                            // Only re-normalize if the original path had a ~ in it.
                            if (path.IndexOf("~", StringComparison.Ordinal) != -1)
                            {
                                normalizedPath = NormalizePath(path, /*fullCheck*/ false, /*expandShortPaths*/ false);
                            }
                        }
                        catch (PathTooLongException) { }
                        catch (NotSupportedException) { }  // Security can throw this on "c:\foo:"
                        catch (IOException) { }
                        catch (ArgumentException) { } // The normalizePath with fullCheck will throw this for file: and http:
                    }
    
                    path = normalizedPath;
    
    #if FEATURE_LEGACYNETCF
                    }
    #endif
    
                    int root = GetRootLength(path);
                    int i = path.Length;
                    if (i > root)
                    {
                        i = path.Length;
                        if (i == root)
                            return null;
                        while (i > root && path[--i] != DirectorySeparatorChar && path[i] != AltDirectorySeparatorChar)
                            ;
                        String dir = path.Substring(0, i);
    #if FEATURE_LEGACYNETCF
                        if (CompatibilitySwitches.IsAppEarlierThanWindowsPhone8) {                        
                            if (dir.Length >= MAX_PATH - 1)
                                throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong"));
                        }                     
    #endif
                        return dir;
                    }
                }
                return null;
            }

    .net framework 4.6.2 source code

         // Returns the directory path of a file path. This method effectively
            // removes the last element of the given file path, i.e. it returns a
            // string consisting of all characters up to but not including the last
            // backslash ("\") in the file path. The returned value is null if the file
            // path is null or if the file path denotes a root (such as "\", "C:", or
            // "\\server\share").
            //
            [ResourceExposure(ResourceScope.None)]
            [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
            public static string GetDirectoryName(string path)
            {
                return InternalGetDirectoryName(path);
            }
    
            [ResourceExposure(ResourceScope.None)]
            [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
            [System.Security.SecuritySafeCritical]
    
            private static string InternalGetDirectoryName(string path)
            {
                if (path != null) {
                    CheckInvalidPathChars(path);
    
    #if FEATURE_LEGACYNETCF
                    if (!CompatibilitySwitches.IsAppEarlierThanWindowsPhone8) {
    #endif
    
                    // Expanding short paths is dangerous in this case as the results will change with the current directory.
                    //
                    // Suppose you have a path called "PICTUR~1\Foo". Now suppose you have two folders on disk "C:\Mine\Pictures Of Me"
                    // and "C:\Yours\Pictures of You". If the current directory is neither you'll get back "PICTUR~1". If it is "C:\Mine"
                    // get back "Pictures Of Me". "C:\Yours" would give back "Pictures of You".
                    //
                    // Because of this and as it isn't documented that short paths are expanded we will not expand short names unless
                    // we're in legacy mode.
                    string normalizedPath = NormalizePath(path, fullCheck: false, expandShortPaths: AppContextSwitches.UseLegacyPathHandling);
    
                    // If there are no permissions for PathDiscovery to this path, we should NOT expand the short paths
                    // as this would leak information about paths to which the user would not have access to.
                    if (path.Length > 0
    #if FEATURE_CAS_POLICY
                        // Only do the extra logic if we're not in full trust
                        && !CodeAccessSecurityEngine.QuickCheckForAllDemands()
    #endif
                        )
                    {
                        try
                        {
                            // If we were passed in a path with \\?\ we need to remove it as FileIOPermission does not like it.
                            string tempPath = RemoveLongPathPrefix(path);
    
                            // FileIOPermission cannot handle paths that contain ? or *
                            // So we only pass to FileIOPermission the text up to them.
                            int pos = 0;
                            while (pos < tempPath.Length && (tempPath[pos] != '?' && tempPath[pos] != '*')) 
                                pos++;
    
                            // GetFullPath will Demand that we have the PathDiscovery FileIOPermission and thus throw 
                            // SecurityException if we don't. 
                            // While we don't use the result of this call we are using it as a consistent way of 
                            // doing the security checks. 
                            if (pos > 0)
                                GetFullPath(tempPath.Substring(0, pos));
                        }
                        catch (SecurityException) {
                            // If the user did not have permissions to the path, make sure that we don't leak expanded short paths
                            // Only re-normalize if the original path had a ~ in it.
                            if (path.IndexOf("~", StringComparison.Ordinal) != -1)
                            {
                                normalizedPath = NormalizePath(path, fullCheck: false, expandShortPaths: false);
                            }
                        }
                        catch (PathTooLongException) { }
                        catch (NotSupportedException) { }  // Security can throw this on "c:\foo:"
                        catch (IOException) { }
                        catch (ArgumentException) { } // The normalizePath with fullCheck will throw this for file: and http:
                    }
    
                    path = normalizedPath;
    
    #if FEATURE_LEGACYNETCF
                    }
    #endif
    
                    int root = GetRootLength(path);
                    int i = path.Length;
                    if (i > root) {
                        i = path.Length;
                        if (i == root) return null;
                        while (i > root && path[--i] != DirectorySeparatorChar && path[i] != AltDirectorySeparatorChar);
                        String dir = path.Substring(0, i);
    #if FEATURE_LEGACYNETCF
                        if (CompatibilitySwitches.IsAppEarlierThanWindowsPhone8) {
                            if (dir.Length >= MAX_PATH - 1)
                                throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong"));
                        }
    #endif
                        return dir;
                    }
                }
                return null;
            }

    Hence you get error when use .net framework 4.6.2. 

    You could download the source file 4.6.1 and 4.6.2 for reference.

    I hope this would be helpful.

    Best Regards,

    Wendy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.




    Friday, April 21, 2017 7:39 AM
    Moderator
  • To work around the problem, try ‘Path.GetDirectoryName( Assembly.GetExecutingAssembly().Location )’.

    Friday, April 21, 2017 7:59 AM
  • thanks!  that worked perfectly.
    Friday, April 21, 2017 6:06 PM