2

La commande suivante dans un fichier de commandes ne fonctionne pas comme prévu/espéré:Obtenir court Nom du fichier des arguments de ligne de commande par lots fichier

echo %~nxs1


Voici un exemple d'affichage de ce que je suis en train de faire:

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) 

au lieu de cela ce que je reçois quelque chose comme ce qui suit (en fonction de court-noms attribués):

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

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

C:\>test "C:\Documents and Settings\All Users\ntuser.data" 
ntuser.data 
s\ntuser.data 

C:\>test "C:\Documents and Settings\All Users\ntuser.dat.baz" 
ntuser.dat.baz 
z 

C:\>test "C:\Documents and Settings\All Users\foo.bar.baz" 
File Not Found 
s\foo.bar.baz 



Fondamentalement, je dois passer un nom de fichier dans un fichier BAT et ont le get script (par exemple l'affichage) comme un court nom de fichier, mais seul le nom de fichier et l'extension, pas de lecteur ou chemin.

Les informations d'aide pour POUR donne % ~ Fsi comme exemple, mais qui a tout le chemin comme un court nom de fichier, pas seulement le fichier. Est-ce que quelqu'un sait comment combiner le paramètre S de % ~ sans obtenir le chemin entier?


Merci beaucoup.



Mises à jour

  1. Je ne cherche pas une solution dans une autre langue, je besoin de la commande BAT pour travailler.

  2. Il semble que cela fonctionne pour les autres, donc je vérifie pour voir si c'est une sorte de problème de configuration alternative. Je suis en train de tester pour voir si les extensions de processeur de commande pourraient être la cause. Cela ne fonctionnera pas du tout si les extensions sont désactivées (évidemment), donc je pars de l'hypothèse que c'est un bug qui a été corrigé dans un service pack suivant (le système sur lequel j'ai testé est XP SP1). Je suis en train de tester SP2 et SP3 aujourd'hui ...

+2

Je n'ai aucun problème à exécuter votre exemple de script. – ghostdog74

+2

Votre script fonctionne pour moi tel quel sur WinXP –

Répondre

2

Eh bien, je viens de le confirmer. J'ai testé le script avec CMD.EXE de XP SP1, SP2 et SP3 ainsi qu'une installation de VM SP2. Il a donné les résultats erronés susmentionnés avec la version SP1, mais a fonctionné correctement dans les versions SP2 et SP3. Donc c'est en effet un bug qui a été corrigé. Pour toute personne qui se lance dans cela, le fichier CMD.EXE de SP2 + peut être déposé dans une installation SP1 sans problème (en supposant qu'une mise à jour n'est pas possible).

+0

Wow! Les votes négatifs sans explications étaient super utiles! Vous les gars (qui que ce soit l'a fait) rock! – Synetech

+1

Oh, et voter vers le bas une réponse correcte est tout simplement studpid. La réponse que j'ai trouvée est correcte, et tous ceux qui rencontrent le même problème pourraient obtenir la réponse qu'ils recherchent, mais certains d-bag ont voté (sans même laisser un commentaire pour s'expliquer!) , les passants peuvent penser que c'est incorrect. : roll: – Synetech

0

Je n'ai aucun problème pour l'exécution de votre lot. J'espère que quelqu'un pourra bientôt vous aider. Mais pendant que vous y êtes, voici une alternative faite avec Vbscript, que je pense que vous devriez connaître.

Set objArgs = WScript.Arguments 
strFile = objArgs(0) 
WScript.Echo CreateObject("Scripting.FileSystemObject").GetFile(strFile).ShortName 

sur la ligne de commande (ou votre lot), appelez comme ça

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

Il y a une autre façon de le faire, compiler ce code dans 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(); 
     } 
    } 
} 

Ajouter ceci dans le projet Console C# appelé ConvFN et le construit. Appelez ensuite ConvFN -s% 1 à partir du fichier de commandes où le paramètre% 1 est un nom de fichier long et il affichera le nom de fichier court équivalent ... comme sage l'inverse, ConvFN -l% 1 où% 1 est le nom de fichier court et il produira le nom de fichier long équivalent.

Ce code a été tiré de pinvoke.net.

0

1- Enregistrez le code dans ShortFileName.Vbs

2- Faites glisser n importe quel dossier ou Drop fichier à ce script

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 
+0

Vous * réalisez * que ce n'est pas un * fichier batch * non? – Synetech

2

Regardez this forum post. Le code ressemble à:

%~snx 
s ... short 
n ... name 
x ... extension 
+0

Oui, je le sais. J'ai dit que cela ne fonctionnait pas comme prévu et confirmé que c'était un bug dans XP SP1. – Synetech

Questions connexes