Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Batch file 从批处理文件获取命令行参数的短文件名_Batch File_Filenames_Command Line Arguments_Substitution - Fatal编程技术网

Batch file 从批处理文件获取命令行参数的短文件名

Batch file 从批处理文件获取命令行参数的短文件名,batch-file,filenames,command-line-arguments,substitution,Batch File,Filenames,Command Line Arguments,Substitution,批处理文件中的以下命令无法按预期/希望的方式工作: echo%~nxs1 以下是我试图获得的示例显示: C:\>type test.bat @dir /b %1 @echo %~nxs1 C:\>test "C:\Documents and Settings\All Users\ntuser.dat" ntuser.dat NTUSER.DAT C:\>test "C:\Documents and Settings\All Users\ntuser.data" ntuse

批处理文件中的以下命令无法按预期/希望的方式工作:

echo%~nxs1


以下是我试图获得的示例显示:

C:\>type test.bat
@dir /b %1
@echo %~nxs1

C:\>test "C:\Documents and Settings\All Users\ntuser.dat"
ntuser.dat
NTUSER.DAT

C:\>test "C:\Documents and Settings\All Users\ntuser.data"
ntuser.data
NTUSER~1.DA~

C:\>test "C:\Documents and Settings\All Users\ntuser.dat.baz"
ntuser.dat.baz
NTUSER~1.BAZ

C:\>test "C:\Documents and Settings\All Users\foo.bar.baz"
File Not Found
foo.bar.baz (or FOO~1.BAZ or whatever, doesn’t really matter since
             file does not exist, though latter would be nice)
相反,我得到的是如下内容(取决于指定的短文件名):



基本上,我需要将一个文件名传递给一个BAT文件,并让脚本获取(例如显示)它作为一个短文件名,但只包含文件名和扩展名,没有驱动器或路径

例如,for的帮助信息提供了%~fsI,但它将整个路径作为一个短文件名,而不仅仅是文件。有人知道如何组合%~中的S参数而不获得整个路径吗


非常感谢



更新

  • 我不是在寻找另一种语言的解决方案,我需要BAT命令来工作

  • 它似乎对其他人有效,所以我正在检查它是否是某种替代配置问题。我目前正在测试命令处理器扩展是否是原因

  • 如果扩展被禁用(很明显),它将根本不起作用,因此我假设这是一个在后续服务包中修复的bug(我测试的系统是xpsp1)。我今天正在测试SP2和SP3


  • 我在执行批处理时没有问题。希望有人能尽快帮助你。但是,当您使用Vbscript时,这里有一个替代方法,我认为您应该熟悉它

    Set objArgs = WScript.Arguments
    strFile = objArgs(0)
    WScript.Echo CreateObject("Scripting.FileSystemObject").GetFile(strFile).ShortName
    
    在命令行(或批处理)上,按如下方式调用它

    C:\test>cscript //nologo getshortname.vbs "C:\Documents and Settings\All Users\Desktop\shortcut.lnk"
    shortcut.lnk
    

    还有另一种方法,在VS中编译此代码:

    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.Linq;
    using System.IO;
    using System.Text;
    using System.Runtime.InteropServices;
    
    namespace ConvFN
    {
        class Program
        {
            static void Main(string[] args)
            {
                if (args.Length == 3)
                {
                    if ((args[2].Length > 1) && System.IO.File.Exists(args[2]))
                    {
                        if (args[1].Equals("-l")) Console.WriteLine(ShortLongFName.GetLongPathName(args[2]));
                        if (args[1].Equals("-s")) Console.WriteLine(ShortLongFName.ToShortPathName(args[2]));
                    }
                }
            }
        }
    
        public class ShortLongFName
        {
            [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
            static extern uint GetShortPathName(
               [MarshalAs(UnmanagedType.LPTStr)]
       string lpszLongPath,
               [MarshalAs(UnmanagedType.LPTStr)]
       StringBuilder lpszShortPath,
               uint cchBuffer);
    
            [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
            [return: MarshalAs(UnmanagedType.U4)]
            private static extern int GetLongPathName(
                [MarshalAs(UnmanagedType.LPTStr)]
            string lpszShortPath,
                [MarshalAs(UnmanagedType.LPTStr)]
            StringBuilder lpszLongPath,
                [MarshalAs(UnmanagedType.U4)]
            int cchBuffer);
    
            /// <summary>
            /// Converts a short path to a long path.
            /// </summary>
            /// <param name="shortPath">A path that may contain short path elements (~1).</param>
            /// <returns>The long path.  Null or empty if the input is null or empty.</returns>
            internal static string GetLongPathName(string shortPath)
            {
                if (String.IsNullOrEmpty(shortPath))
                {
                    return shortPath;
                }
    
                StringBuilder builder = new StringBuilder(255);
                int result = GetLongPathName(shortPath, builder, builder.Capacity);
                if (result &gt; 0 && result &lt; builder.Capacity)
                {
                    return builder.ToString(0, result);
                }
                else
                {
                    if (result &gt; 0)
                    {
                        builder = new StringBuilder(result);
                        result = GetLongPathName(shortPath, builder, builder.Capacity);
                        return builder.ToString(0, result);
                    }
                    else
                    {
                        throw new FileNotFoundException(
                            string.Format(
                            CultureInfo.CurrentCulture,
                            "{0} Not Found",
                            shortPath),
                            shortPath);
                    }
                }
            }
            /// <summary>
            /// The ToLongPathNameToShortPathName function retrieves the short path form of a specified long input path
            /// </summary>
            /// <param name="longName">The long name path</param>
            /// <returns>A short name path string</returns>
            public static string ToShortPathName(string longName)
            {
                uint bufferSize = 256;
    
                // don´t allocate stringbuilder here but outside of the function for fast access
                StringBuilder shortNameBuffer = new StringBuilder((int)bufferSize);
    
                uint result = GetShortPathName(longName, shortNameBuffer, bufferSize);
    
                return shortNameBuffer.ToString();
            }
        }
    }
    
    使用系统;
    使用System.Collections.Generic;
    利用制度全球化;
    使用System.Linq;
    使用System.IO;
    使用系统文本;
    使用System.Runtime.InteropServices;
    名称空间ConvFN
    {
    班级计划
    {
    静态void Main(字符串[]参数)
    {
    如果(args.Length==3)
    {
    如果((args[2].Length 1)和&System.IO.File.Exists(args[2]))
    {
    if(args[1].Equals(“-l”))Console.WriteLine(ShortLongFName.GetLongPathName(args[2]);
    if(args[1].Equals(“-s”))Console.WriteLine(ShortLongFName.ToShortPathName(args[2]);
    }
    }
    }
    }
    公共类ShortLongFName
    {
    [DllImport(“kernel32.dll”,CharSet=CharSet.Auto,SetLastError=true)]
    静态外部uint GetShortPathName(
    [Marshallas(UnmanagedType.LPTStr)]
    字符串lpszLongPath,
    [Marshallas(UnmanagedType.LPTStr)]
    StringBuilder lpszShortPath,
    uint cchBuffer);
    [DllImport(“kernel32.dll”,SetLastError=true,CharSet=CharSet.Auto)]
    [返回:Marshallas(UnmanagedType.U4)]
    私有静态外部int GetLongPathName(
    [Marshallas(UnmanagedType.LPTStr)]
    字符串lpszShortPath,
    [Marshallas(UnmanagedType.LPTStr)]
    StringBuilder lpszLongPath,
    [Marshallas(UnmanagedType.U4)]
    int cchBuffer);
    /// 
    ///将短路径转换为长路径。
    /// 
    ///可能包含短路径元素(~1)的路径。
    ///长路径。如果输入为Null或空,则为Null或空。
    内部静态字符串GetLongPathName(字符串短路径)
    {
    if(String.IsNullOrEmpty(短路径))
    {
    返回短路径;
    }
    StringBuilder=新的StringBuilder(255);
    int result=GetLongPathName(短路径、生成器、builder.Capacity);
    if(结果0&&result builder.Capacity)
    {
    返回builder.ToString(0,结果);
    }
    其他的
    {
    如果(结果0)
    {
    生成器=新的StringBuilder(结果);
    结果=GetLongPathName(短路径、构建器、构建器容量);
    返回builder.ToString(0,结果);
    }
    其他的
    {
    抛出新的FileNotFoundException(
    字符串格式(
    CultureInfo.CurrentCulture,
    “{0}未找到”,
    短路径),
    短路径);
    }
    }
    }
    /// 
    ///ToLongPathNameToSortPathName函数检索指定长输入路径的短路径形式
    /// 
    ///长名称路径
    ///短名称路径字符串
    公共静态字符串ToSortPathName(字符串longName)
    {
    uint bufferSize=256;
    //不要在此处分配stringbuilder,而是在功能之外,以便快速访问
    StringBuilder shortNameBuffer=新的StringBuilder((int)bufferSize);
    uint结果=GetShortPathName(longName、shortNameBuffer、bufferSize);
    返回shortNameBuffer.ToString();
    }
    }
    }
    
    将其添加到名为ConvFN的控制台C#项目中并构建它。然后从批处理文件中调用ConvFN-s%1,其中%1参数是一个长文件名,它将输出等效的短文件名…与此相反,ConvFN-l%1其中%1是短文件名,它将输出等效的长文件名


    这段代码取自pinvoke.net。

    我刚刚确认过。我使用xpsp1、SP2和SP3中的CMD.EXE以及SP2虚拟机安装测试了脚本。它在SP1版本中给出了上述错误结果,但在SP2和SP3版本中工作正常。因此,这确实是一个已修复的bug。对于遇到此问题的任何其他人,SP2+中的CMD.EXE文件可以毫无问题地放入SP1安装中(假设更新不可行)。

    1-将代码保存在ShortFileName中
    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.Linq;
    using System.IO;
    using System.Text;
    using System.Runtime.InteropServices;
    
    namespace ConvFN
    {
        class Program
        {
            static void Main(string[] args)
            {
                if (args.Length == 3)
                {
                    if ((args[2].Length &gt; 1) && System.IO.File.Exists(args[2]))
                    {
                        if (args[1].Equals("-l")) Console.WriteLine(ShortLongFName.GetLongPathName(args[2]));
                        if (args[1].Equals("-s")) Console.WriteLine(ShortLongFName.ToShortPathName(args[2]));
                    }
                }
            }
        }
    
        public class ShortLongFName
        {
            [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
            static extern uint GetShortPathName(
               [MarshalAs(UnmanagedType.LPTStr)]
       string lpszLongPath,
               [MarshalAs(UnmanagedType.LPTStr)]
       StringBuilder lpszShortPath,
               uint cchBuffer);
    
            [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
            [return: MarshalAs(UnmanagedType.U4)]
            private static extern int GetLongPathName(
                [MarshalAs(UnmanagedType.LPTStr)]
            string lpszShortPath,
                [MarshalAs(UnmanagedType.LPTStr)]
            StringBuilder lpszLongPath,
                [MarshalAs(UnmanagedType.U4)]
            int cchBuffer);
    
            /// <summary>
            /// Converts a short path to a long path.
            /// </summary>
            /// <param name="shortPath">A path that may contain short path elements (~1).</param>
            /// <returns>The long path.  Null or empty if the input is null or empty.</returns>
            internal static string GetLongPathName(string shortPath)
            {
                if (String.IsNullOrEmpty(shortPath))
                {
                    return shortPath;
                }
    
                StringBuilder builder = new StringBuilder(255);
                int result = GetLongPathName(shortPath, builder, builder.Capacity);
                if (result &gt; 0 && result &lt; builder.Capacity)
                {
                    return builder.ToString(0, result);
                }
                else
                {
                    if (result &gt; 0)
                    {
                        builder = new StringBuilder(result);
                        result = GetLongPathName(shortPath, builder, builder.Capacity);
                        return builder.ToString(0, result);
                    }
                    else
                    {
                        throw new FileNotFoundException(
                            string.Format(
                            CultureInfo.CurrentCulture,
                            "{0} Not Found",
                            shortPath),
                            shortPath);
                    }
                }
            }
            /// <summary>
            /// The ToLongPathNameToShortPathName function retrieves the short path form of a specified long input path
            /// </summary>
            /// <param name="longName">The long name path</param>
            /// <returns>A short name path string</returns>
            public static string ToShortPathName(string longName)
            {
                uint bufferSize = 256;
    
                // don´t allocate stringbuilder here but outside of the function for fast access
                StringBuilder shortNameBuffer = new StringBuilder((int)bufferSize);
    
                uint result = GetShortPathName(longName, shortNameBuffer, bufferSize);
    
                return shortNameBuffer.ToString();
            }
        }
    }
    
        Set fso=CreateObject("Scripting.FileSystemObject")
        ' Is object a file or folder?
    
        If fso.FolderExists(WScript.Arguments(0)) Then
           'The dropped stuff is a folder
           Set objFolder = fso.GetFolder(WScript.Arguments(0))
           rtrn = InputBox("Short path is :", "SHORT PATH", objFolder.ShortPath)
        End If
    
        If fso.FileExists(WScript.Arguments(0)) Then
           'The dropped stuff is a file
           Set objFile = fso.GetFile(WScript.Arguments(0))
           rtrn = InputBox("Short path is :", "SHORT PATH", objFile.ShortPath)
        End If
    
    %~snx
    s ... short 
    n ... name
    x ... extension