2

I am trying to make a batch script for converting .m3u files to .lst and .cfg.

So, i made already a vbscript to treat a single file by drag and drop and it works fine. Now my worries in this batch: How to detect if the parameter to go through drag and drop is a folder or not ?

Batch File :

@ECHO OFF
Title Conversion des fichiers de type .m3u en .lst et en .cfg by HACKOO
Mode con cols=70 lines=5
color 0A 
echo.
IF [%1] EQU [] Goto:Error
CD /D "%~1"
FOR %%f IN (*.m3u) DO (echo. & echo Conversion du fichier "%%f" ... & Cscript /NoLogo %~dp0Convert_m3u-lst-cfg.vbs "%%f" & Cls & echo.)
Start "" explorer "%~1"
Exit

:Error
Color 0c
echo.
ECHO    Il faut glisser et deposer un dossier sur ce programme batch 
Timeout /T 6 /NoBreak >nul
Exit

The Vbscript : Convert_m3u-lst-cfg.vbs

Option Explicit
Const Titre = "Conversion des fichiers de type .m3u en .lst et en.cfg by © HACKOO"
Const ForReading = 1
Const ForWriting = 2
Const TriStateUseDefault = -2
Const StartTagName = "<servername=>"
Const EndTagName = "</servername>"
Const StartserveurURL = "<serverurl=>"
Const EndserveurURL = "</serverurl>"
Const category = "<servercategory=>movies</servercategory>"
Dim sInfile,sOutfile,oFSO,oInfile,oOutfile,Texte,Folder,Ws,MyDirectory,FileM3UConverted
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set Ws = CreateObject("Wscript.Shell")
MyDirectory = oFSO.GetParentFolderName(WScript.ScriptFullName)
'****************************1ère étape : Formater le fichier.m3u déposé, càd enlever toutes les lignes vides***********************************
' Obtenir le nom du fichier d'entrée de ligne de commande , si le 2ème paramètre est entré
' utiliser le deuxième paramètre en tant que nouveau fichier de sortie, sinon réécriture du fichier d'entrée
If (WScript.Arguments.Count > 0) Then
    sInfile = WScript.Arguments(0)
        If LCase(oFSO.GetExtensionName(sInfile)) <> "m3u" Then 
            MsgBox "Faites glisser et déposer le fichier.m3u à convertir sur ce script",vbExclamation,Titre
            Wscript.Quit()
        End If  
Else
    MsgBox "Faites glisser et déposer le fichier.m3u à convertir sur ce script",vbExclamation,Titre
    WScript.Quit
End If
If (WScript.Arguments.Count > 1) Then
    sOutfile = WScript.Arguments(1)
Else
    sOutfile = sInfile
End If
' Lire le fichier en entré dans une variable puis fermetrure de ce dernier
Folder = GetFilenameWithoutExtension(sInfile) & "_Hackoo-Conversion"

If Not oFSO.FolderExists(Folder) Then
    oFSO.CreateFolder(Folder)
End If  
FileM3UConverted = Folder & "\" & GetName(Folder) &".m3u"
'wscript.echo sInfile
Set oInfile = oFSO.OpenTextFile(sInfile, ForReading, False, TriStateUseDefault)
Set oOutfile = oFSO.OpenTextFile(FileM3UConverted, ForWriting, True) 

While Not oInfile.AtEndOfStream
    Texte = oInfile.ReadLine
    Texte = Trim(Texte)
    If ( Len(Texte) > 0 ) Then
        oOutfile.Writeline Texte
    End If
Wend
oOutfile.Close
Set oOutfile = Nothing
'*****************************2ème étape : Extraire les lignes depuis le fichier formaté .m3u vers un fichier.lst******************************
Dim strLine,Tab,strNewcontents,i,k,Count,Name,URL,Ligne,sOutfileCfg
sInfile = FileM3UConverted
sOutfile = GetFilenameWithoutExtension(sInfile) & ".lst" 
sOutfileCfg = GetFilenameWithoutExtension(sInfile) & ".cfg"
If oFSO.FileExists(sOutfile) Then
    oFSO.DeleteFile(sOutfile)
End If
Set oInfile = oFSO.OpenTextFile(sInfile, ForReading, False, TriStateUseDefault)
oInfile.SkipLine()
Do Until oInfile.AtEndOfStream
    strLine = oInfile.Readline
    strLine = Trim(strLine)
    If Len(strLine) > 0 Then
        strNewcontents = Replace(strNewcontents,"#EXTINF:-1,","")
        strNewcontents = Replace(strNewcontents,"#EXTINF:0,","")
        strNewcontents = Replace(strNewcontents,"#EXTINF:0 ","")
        strNewcontents = Replace(strNewcontents,"#EXTINF:-1 ","")
        strNewContents = strNewContents & strLine & vbCrLf
    End If
Loop
oInfile.Close
Count = 0
Tab = split(strNewcontents,vbcrlf)
For i = lbound(Tab) to ubound(Tab) Step 2
    If i Mod 2 = 0 then
        Count = Count + 1
        Name = Trim(Tab(i))
        k = i+1
        If k > UBound(tab) Then Exit For
        URL = Tab(k)
    End If  
    Ligne = StartTagName & Name & EndTagName & StartserveurURL & URL & EndserveurURL & category
    Call WriteLog(Ligne,sOutfile)
    Call WriteLog("I: " & URL & " " & Name,sOutfileCfg)
Next
Ws.Popup "La conversion du fichier  "& vbCrLf &  DblQuote(sInfile) & vbCrLf & " est terminé avec succès !","2",Titre,64
'MsgBox "La conversion du fichier " & vbCrLf &  DblQuote(sInfile) & vbCrLf & " est terminé avec succès !",vbInformation,Titre
'**********************************************************************************************
'Fonction pour écrire le résultat dans un fichier texte
Sub WriteLog(strText,LogFile)
    Dim fs,ts 
    Const ForAppending = 8
    Set fs = CreateObject("Scripting.FileSystemObject")
    Set ts = fs.OpenTextFile(LogFile,ForAppending,True)
    ts.WriteLine strText
    ts.Close
End Sub
'**********************************************************************************************
Function DblQuote(Str)
    DblQuote = Chr(34) & Str & Chr(34)
End Function
'**********************************************************************************************
Function GetFilenameWithoutExtension(ByVal FileName)
  Dim Result, i
  Result = FileName
  i = InStrRev(FileName, ".")
  If ( i > 0 ) Then
    Result = Mid(FileName, 1, i - 1)
  End If
  GetFilenameWithoutExtension = Result
End Function
'**********************************************************************************************
Function GetName(Path)
Dim fso
Set fso = CreateObject("Scripting.FileSystemObject")
GetName = fso.GetBaseName(path)
End Function
'**********************************************************************************************
Hackoo
  • 18,337
  • 3
  • 40
  • 70

5 Answers5

3

A way to test if an element is a folder, a file or nothing. Adapted from : How to test if a path is a file or directory in Windows batch file?

@echo off

set /p var=Name of the element to test :

call:test %var%
goto end

:test
if exist "%~1" (2>nul pushd "%~1" && (popd&set "type=FOLDER") || set "type=FILE" ) else set "type=UNKNKOWN"
echo "%~1" = %type%

:end
Community
  • 1
  • 1
SachaDee
  • 9,245
  • 3
  • 23
  • 33
2

You can use only cd on folders so, you can check if the cd command work on the parameter.

In batch, that look like to

set olddir=%CD%
2>nul cd %parametre%&&echo the parameter is not a folder||echo the parameter is a folder
REM Restore old dir after cd.
cd %olddir%
TSnake41
  • 405
  • 3
  • 8
1

You can also try something like this, in addition to the way @TSnake41 did it:

@echo off

::without pushd, fails on extensionless files
set "folder=false"
for /F "delims=" %%A in ("%~1") do if "%%~xA"=="" set "folder=true"
echo folder: %folder%

::with pushd
set "folder=true"
2>nul pushd "%~1"
if %errorlevel% neq 0 set "folder=false"
popd
echo folder: %folder%
pause
Dennis van Gils
  • 3,487
  • 2
  • 14
  • 35
1

You can simply append a \ to the item %~1 and check the item for existence:

if exist "%~1\" (
    echo Item is a folder.
) else (
    echo Item is a file.
)

Since you are talking about drag and drop, the item %~1 always exists, because you cannot drag nothing. But with a \ appended, the check will fail for files but not for folders. It will also fail if you drag a folder which you do not have sufficient access privileges for.

Note, that there is always %~1 stated rather than %1, which removes potential surrounded quotes. So "%~1\" explicitly encloses the item within a pair of quotes and includes the \ also within it.

aschipfl
  • 33,626
  • 12
  • 54
  • 99
1

There are several answers here using exist and pushd/popd, but you can also use file attributes. And I believe the attribute techinique is more robust. I wrote this subroutine based on the answer linked here in How to test if a file is a directory in a batch script?.

::
:$is_dir ( ref_RETURN PATH )
:: RETURN == (BOOLEAN as undef/1) whether PATH is a directory
:: NOTE: URLref: https://stackoverflow.com/questions/138981/how-do-i-test-if-a-file-is-a-directory-in-a-batch-script/3728742#3728742
setlocal ENABLEEXTENSIONS
set "_RETval="
set "_RETvar=%~1"
if NOT EXIST "%~2" ( goto :_is_dir_RETURN )
set "attr=%~a2"
set "attr_bit=%attr:~0,1%"
if /i "%attr_bit%"=="d" (set "_RETval=1")
:_is_dir_RETURN
endlocal & set %_RETvar%^=%_RETval%
goto :EOF
::

Here is a test batch file...

@echo off
if "%~1" == "" (echo usage: %~nx0 PATH & goto :EOF)
call :$is_dir is_a_dir "%~1"
set /p _OUTPUT="'%1' "<nul &:: aka, echo-noLF
if not exist "%~1" ( set /p _OUTPUT=does not exist;<nul )
if defined is_a_dir ( echo IS a directory ) else ( echo is NOT a directory)
goto :EOF

:: ** SUBs
goto :EOF
::
:$is_dir ( ref_RETURN PATH )
:: RETURN == (BOOLEAN as undef/1) whether PATH is a directory
:: NOTE: URLref: https://stackoverflow.com/questions/138981/how-do-i-test-if-a-file-is-a-directory-in-a-batch-script/3728742#3728742
setlocal ENABLEEXTENSIONS
set "_RETval="
set "_RETvar=%~1"
if NOT EXIST "%~2" ( goto :_is_dir_RETURN )
set "attr=%~a2"
set "attr_bit=%attr:~0,1%"
if /i "%attr_bit%"=="d" (set "_RETval=1")
:_is_dir_RETURN
endlocal & set %_RETvar%^=%_RETval%
goto :EOF
::
Community
  • 1
  • 1
rivy
  • 1,570
  • 1
  • 15
  • 30