4

I have the misfortune of working with a program which requires all filenames passed into it to be valid URLs. (No, I don't know why.) Rather than having to drop to the command line and hand-craft file: URLs each time, I'm throwing together a batch file onto which I can simply drop files dragged from the Windows GUI.

A full, proper URL encoder is beyond my needs or interest (most of the characters the app chokes on aren't valid in Windows filenames, anyway), but the two cases I do need to solve are backslashes and spaces. Backslashes are easily handled by variable replacement syntax (SET URL=%URL:\=/%), but spaces are tricky — % is special for both URLs and batch files.

Neither type of batch escaping I'm familiar with (^%, %%) allows the variable replacement to behave as desired and I haven't had any success Googling a solution. Can any batch gurus help me out?

Here's what I have so far:

@ECHO OFF

SETLOCAL

SET URLPATH=file:/%~dp1
SET URLPATH=%URLPATH:\=/%

REM none of these work
REM SET URLPATH=%URLPATH: =%20%
REM SET URLPATH=%URLPATH: =%%20%
REM SET URLPATH=%URLPATH: =^%20%

REM works; I just need to figure out how to generate it
SET URLPATH=file:/C:/Documents%%20and%%20Settings/bblank/example.dat

stupidapp.exe %URLPATH%

ENDLOCAL
Ben Blank
  • 54,908
  • 28
  • 127
  • 156
  • Dude - why torture yourself trying to do this in .bat file syntax? Why not write a simple .exe (that you can call from your .bat file). Or write a .wsh script? Or Powershell or Perl? *ANYTHING* but .bat syntax! – paulsm4 Apr 18 '12 at 21:43
  • @paulsm4 — It's ubiquitous. I need to be able to distribute this script without worrying about dependencies. – Ben Blank Apr 18 '12 at 21:47
  • first off when you set a value you do not need a % in front. second your URL has the incorrect space encoding the space value is %20 not %%20. also your URL directing should use a "\" until the file name I.E File://C:\...\...\.../example.dat. also = should be == stupid batch idea but it is what it is. and last but not least URLPATH=="File://....." with this you will not need %20 at all. – CMS_95 Nov 18 '13 at 02:09

2 Answers2

3

Side note - I believe you want %~f1 instead of %~dp1

You need to switch over to delayed expansion.

@echo off
setlocal enableDelayedExpansion

set "URLPATH=file:/%~f1"
set "URLPATH=!URLPATH:\=/!"
set "URLPATH=!URLPATH: =%%20!"
stupidapp.exe !URLPATH!

endlocal

A bit more work is required if any of your file names happen to contain the ! character because it will be corrupted when %1 is expanded if delayed expansion is enabled.

@echo off
setlocal disableDelayedExpansion
set "URLPATH=file:/%~f1"
setlocal enableDelayedExpansion
set "URLPATH=!URLPATH:\=/!"
set "URLPATH=!URLPATH: =%%20!"
stupidapp.exe !URLPATH!

endlocal
endlocal
Ben Blank
  • 54,908
  • 28
  • 127
  • 156
dbenham
  • 127,446
  • 28
  • 251
  • 390
  • Works perfectly! I didn't think to mention, but the app requires a working directory to be passed in as well as a filename and that's the part of the code I copied here; hence the `%~dp1`. :-) – Ben Blank Apr 18 '12 at 23:51
  • I am using this code to pass a filename (%~1) to the default browser as a query argument. It works great on windows 7! – Sébastien Sep 27 '13 at 14:15
2

dbenham's solution is almost certainly preferable (being rather easier to read), but for the sake of completeness, here is an alternative solution:

SET URLPATH=file:/%~dp1
SET URLPATH=%URLPATH:\=/%

REM for each space in the path, split the path into the portions before and after
REM that space, then join them with an escaped space
:ESCAPE_SPACE
SET TRAILING=%URLPATH:* =%
CALL SET URLPATH=%%URLPATH: %TRAILING%=%%
SET URLPATH=%URLPATH%%%20%TRAILING%
IF NOT "%URLPATH%"=="%URLPATH: =%" GOTO ESCAPE_SPACE

stupidapp.exe %URLPATH%
Ben Blank
  • 54,908
  • 28
  • 127
  • 156