The windows bat files e.g. ps2pdf.bat call other .bat files using paths relative to the current script. This doesn't resolve correctly if e.g. ps2pdf.bat is used in the windows explorer context menu (Right Click->open with->ps2pdf.bat). To fix this, all calls from a bat file to other bat files or executables should prepend the current scripts path to the call e.g. in ps2pdf14.bat, instead of: call ps2pdfxx %1 %2 it should be call "%~dp0ps2pdfxx" %1 %2 Secondly, when using the context menu, the working dir is set to the windows system directory e.g. c:\windows\system. This is usually read only, so temporary files that are created by GS fails (e.g. _.at and _.at2). To fix this, I suggest prepending the windows temp dir in front of these files e.g. instead of echo -dCompatibilityLevel#1.4 >_.at it would be echo -dCompatibilityLevel#1.4 >"%TEMP%\_.at" I would be happy to submit a patch, but couldn't find the right CVS repository. I've fixed this and tested it on my own machine. Thanks for a great program. Bjorn
(In reply to comment #0) > I would be happy to submit a patch, but couldn't find the right CVS repository. http://git.ghostscript.com and http://svn.ghostscript.com both should work. git is a mirror and svn is authoritative .
I was finally able to find a reference which stated that the %~d batch parameter was added to Windows in NT 4. That's sufficiently long ago that I fell comfortable with using it in the batch scripts. As noted in the submission log this does mean that Windows 3.x, 95 and 98 may not work with these scripts (I can't find any definitive statements about those versions of Windows), however those are sufficiently old that I don't think we need to worry about them. The files have been updated in revision 11498, patch available here: http://ghostscript.com/pipermail/gs-cvs/2010-July/011373.html I have tested a number, but haven't been able to be completely exhaustive about it, more testing would be welcome. Thanks very much for your contribution, if you feel you would like to submit a patch in future, then simply add it as an attachment to the bug report.
My worry with this would also have been the lacking support for older Windows systems. Personally, I'm using this trick in my batch files since a few years. To check, if cmd.exe on your version of Window actually supports it, just run "for /?" and scroll down towards the end. Here is a list of all posible loop variable (%a, %b, %c,...) or positional parameter (%0, %1, %2,...) replacements (using "I" for letter or number): %~I : expand %I and remove all enclosing quotes ("). %~fI : expand %I to the full file name. %~dI : show the drive name where %I is located. %~pI : show the path for %I. %~nI : show the name of %I without file suffix. %~xI : show the suffix of %I. %~sI : show the 'short' path for %I. %~aI : show the file attributes of %I. %~tI : show date+time of %I. %~zI : show filesize of %I. One can combine these like for example here: %dpI : show drive letter with path for %I. %nxI : show 'filename.suffix' for %I. %fsI : show path with filename of %I, but completely the short version. If you use these wisely, you can make .bat files work even using relative paths.
Sorry for the "noise" in comment #3. (I had this bug open in a browser tab since a few days, with the comment written, but for some reason not committed yet. When realizing that a click on the "Commit" was still missing, I just did it. Only after the fact I realized that comment #2 had appeared in the meanwhile confirming Bjorn's patch had been accepted).
There are a few problems with the adopted solution, and I will suggest 2 patches for fixing them. Patch order: the 2 patches are ‘successive’, in comment order. Please apply them in this order, otherwise patch won’t find the context it needs. There are hunks in the 1st patch that apply with a fuzz factor, that’s OK; the reasons are the ‘$Id$’s, patch does not know to un-expand them. (A) %~dp0 does not work on Win95/98/ME, only on the NT-based versions This is already mentioned in comments above. Fortunately there is an easy way to rectify the situation, so no need to cut off old Windows versions. The technique used: ‘%0\..’ is the absolute/relative directory of the batch file, as specified by the user on the command line. The ‘..\’ removes the path component that precedes it, in this case the bat filename itself; it is not necessary for the respective component to represent an actual directory, it can be a file or not exist at all. There is only one case when this does not work directly and has to be handled specially: if the user started the bat by typing its filename without any path AND the *.bat is not in the current directory. In this case (and only in this case) the command interpreter searches the %PATH%. The case is detected by ‘if not exist %0\..\self.bat’, and no path will be specified for subordinate batch files, so the command interpreter will be able to search them in the %PATH% the same as it did for the main bat. (B) Temp files are (usually) written near, not inside, %TEMP% With a default Windows installation, %TEMP% is set but without a trailing backslash. So ‘%TEMP%_at’ can be, for example, placed in the directory ‘C:\Document and Settings\user\Local Settings’ and named ‘TEMP_at’. The solution: use ‘%TEMP%.\_at’ instead. Here is how this works: - case 1: %TEMP% not set ‘%TEMP%.\_at’ becomes ‘.\_at’. Temp files are created in the current directory as before. - case 2: %TEMP% set without a trailing ‘\’, for example ‘C:\TEMP’ ‘%TEMP%.\_at’ becomes, for example, ‘C:\TEMP.\_at’. This is the same as ‘C:\TEMP\_at’, because Windows IGNORES trailing periods. - case 3: %TEMP% set with a trailing ‘\’, for example ‘C:\TEMP\’ ‘%TEMP%.\_at’ becomes, for example, ‘C:\TEMP\.\_at’, OK. (C) A typo: a ‘>>’ was suppressed from ps2pdf.bat Modified: trunk/gs/lib/ps2pdf.bat =================================================================== --- trunk/gs/lib/ps2pdf.bat 2010-07-08 20:01:59 UTC (rev 11497) +++ trunk/gs/lib/ps2pdf.bat 2010-07-09 09:40:17 UTC (rev 11498) @@ -6,13 +6,13 @@ ... :top -echo %1 >>_.at +echo %1 %TEMP%_.at <== HERE shift ... (D) It’s not impossible (but a bad idea) for %TEMP% to contain spaces I noticed Windows to define %TEMP% using DOS 8.3 names by default. However, it is possible the user does differently, and also it’s possible to completely disable the creation of DOS 8.3 aliases on disk.
Created attachment 6565 [details] Suggested patch: use a Win9X-compatible construct instead of ‘%~dp0’ Follow-up #1 to rev 11498: replace the use of ‘%~dp0’, available only on NT-based Windows, with ‘%0\..’ which is compatible with all Windows versions. A special test is also done to detect the situation when the bat was found by searching the %PATH%, in which case no path is specified for subordinate bat files to allow the command interpreter to look for them on the %PATH% as it did for the master bat.
Created attachment 6566 [details] Suggested patch: %TEMP%-related fixes Follow-up #2 to rev 11498: (i) By using the construct ‘%TEMP%_at’, temp files may (and often they do, because by default %TEMP% does not have a trailing ‘\’) go in the %TEMP%’s parent, not inside %TEMP%. Use ‘%TEMP%.\_at’ instead. (ii) Fix a typo in ps2pdf.bat, the removal of a ‘>>’. (iii) Enclose temp filenames in quotes, just in case %TEMP% contains spaces or other separators.
(In reply to comment #5) Thanks for spotting the typo in ps2pdf.bat, I've committed the fix for that as revision 11545. As for the remaining issues; as we keep on saying, batch programming in Windows is a difficult area, its not possible to do a really good job. The batch files are provided as a convenience, if they don't work you can still run Ghostscript from the command line. Or, of course, write your own batch files. The main aim here is to provide something which works reasonably well for most users, and which we're comfortable in supporting. I don't want to take on the job of endlessly patching a rickety structure to try and retain compatibility with old versions of Windows. Microsoft hasn't supported Windows 98 or ME since July 2006, four years bow, so I don't particularly feel we need to worry about it. I'd rather move on and use the new capabilities. If I hear howls of complaint from the user community I'll have to rethink that position of course.
The temp-files-miss-the-%TEMP%-folder issue (comment #5 point (B)) affects by default all Windows versions, old and new, because the %TEMP% environment variable does not normally include a trailing backslash. The %TEMP%-containing-spaces (comment #5 point (D)) affects equally well all versions, maybe with an extra for the NT-based ones including those current. The cause of this extra is that it’s possible to completely suppress, for performance reasons, the creation of DOS 8.3 filenames on NTFS volumes (‘fsutil behavior set disable8dot3 1’); then spaces become almost unavoidable (‘...\Local Setting\...’ and such). Now, my opinion about comment #5 point (A) may be biased, as I still use sometimes those old Windows versions (Win98 often enough, Win95 rarely). Of course, the decision is yours. You may decide to do nothing. But if you decide to fix at least comment #5 point (B) (and eventually (D)), what is easier and takes less time: (i) apply the 2 patches as they are; or (ii) redo and retest something similar to attachment #6566 [details]? (Okay, okay, I confess: I’m evil.)
Unfortunately there’s a 5th problem coming from the committed patch, bigger than all the others together. (E) Once Ghostscript installed with default options, most (all?) batch files dont’t work at all even with current versions of Windows. Tested for now on WinXP-SP3 which is supported by Microsoft. Examples: ================================================================== C:\Program Files\gs\gs8.71\lib>ps2pdf input.ps output.pdf 'C:\Program' is not recognized as an internal or external command, operable program or batch file. C:\Program Files\gs\gs8.71\lib> ================================================================== C:\Program Files\gs\gs8.71\lib>ps2ascii file.ps file.txt 'C:\Program' is not recognized as an internal or external command, operable program or batch file. '-q' is not recognized as an internal or external command, operable program or batch file. C:\Program Files\gs\gs8.71\lib> ================================================================== No output file created in either of these cases. (Note: I’m using the current revision of GS; the ‘8.71’ appears there because I installed 8.71 from code.google.com, then replaced all files with ones resulting from a default build of TRUNK revision 11680 and modified the registry appropriately.) Cause: the ‘%~dp0’ expands to the drive+path, including any spaces or command line separators that happen to be there, without quotes around the whole thing. So any ‘call %~dp0file.bat’ line in the *.BAT results in ‘call C:\Program Files\C:\Program Files\gs\gs8.71\lib\file.bat’, and the command interpreter looks for C:\Program.(bat|com|exe) which (hopefully! - security risk) does not exist. Batch files that call others for something essential (like ‘ps2pdf.bat’) don’t work because the subordinate BAT files are not found. Those that don’t rely on others (like ‘ps2ascii.bat’) don’t work in general because they don’t manage to execute ‘gssetgs.bat’ and %GSC% remains undefined. My patch from comment #6 does not have this problem, because if quotes are needed they are already present in ‘%0’ and are preserved. Of course I would prefer committing it. Failing that, all instances of ‘%dp0’ need to be quoted. Failing this also, and to really stick with comment #8, please revert the committed patch. The OP can solve the problem with the directory by defining the PATH environment variable; the trouble with temp files cannot be solved so easily (but Windows Script Host or Windows PowerShell should come to the rescue...). I’m reopening this bug so this new issue does not get forgotten. It’s not the same as the original one, but all discussion and patches are here.
revision 11684 should solve this. Path expansion (whether from environment variables or magic %~d) are guarded with quotes. The %TEMP% use gets a trailing path separator. Doubled separators don't seem to cause a problem so this seems safe.