从Java使用时Windows 2008 Server上%dp0的行为

从Java使用时Windows 2008 Server上%dp0的行为,java,batch-file,windows-server-2008,Java,Batch File,Windows Server 2008,问题环境:Windows Server 2008 R2版本7601 我有一个批处理文件SomeBatchFile.bat,它使用%~dp0获取脚本位置。但是当它从java程序在Windows Server 2008 R2 Build 7601上执行时,它显示出一种错误行为 这就是行为 1) 像这样执行的时候 Process proc=Runtime.getRuntime().exec(“c:\\full\\path\\SomeBatchFile.bat”) 将SomeBatchFile.bat文

问题环境:Windows Server 2008 R2版本7601

我有一个批处理文件
SomeBatchFile.bat
,它使用
%~dp0
获取脚本位置。但是当它从java程序在Windows Server 2008 R2 Build 7601上执行时,它显示出一种错误行为

这就是行为

1) 像这样执行的时候

Process proc=Runtime.getRuntime().exec(“c:\\full\\path\\SomeBatchFile.bat”)

SomeBatchFile.bat
文件保存在
C:\full\path
中(基本上给出了实际的完整路径),它将返回预期的结果
C:\full\path\

2) 但是像这样执行的时候

processproc=Runtime.getRuntime().exec(“SomeBatchFile.bat”)

SomeBatchFile.bat
文件保存在
C:\Windows
(本质上是环境变量
PATH
的一部分)中。这会返回错误的值,而不是
bat脚本位置
,返回调用此脚本的
java程序位置

这是我正在使用的脚本文件,

REM Just prints the script location to a file

set MY_HOME=%~dp0
echo %MY_HOME% >> test_out.txt

REM And some other business logic here ...
在WindowsServer2003上,这是绝对正常的


知道为什么会这样吗?这是Java/Windows错误吗?如何解决这个问题?

如果您试图以相对路径启动脚本,还应该尝试使用以下语法:

Process proc=Runtime.getRuntime().exec(“.\\SomeBatchFile.bat”)

processproc=Runtime.getRuntime().exec(“.\SomeBatchFile.bat”)

processproc=Runtime.getRuntime().exec(“./SomeBatchFile.bat”)


这三种方法中的一种应该有效。

如果您试图以相对路径启动脚本,还应该尝试使用以下语法:

Process proc=Runtime.getRuntime().exec(“.\\SomeBatchFile.bat”)

processproc=Runtime.getRuntime().exec(“.\SomeBatchFile.bat”)

processproc=Runtime.getRuntime().exec(“./SomeBatchFile.bat”)


这三种方法中的一种应该可以工作。

我已经尝试复制您的问题,唯一的方法是引用批处理文件执行,也就是说,如果java程序调用
cmd
实例来处理批处理文件执行,批处理文件名是
“SomeBatchFile.bat”
。您可以尝试从命令行执行批处理文件,并使用引号调用它以查看问题

也就是说,一个简单的批处理文件

@echo %~dp0
放置在路径的某个位置(例如,
c:\windows\test.bat
),当从命令行、任何文件夹调用时,您将检索到正确的文件夹,但不包括指向该文件夹的路径,也不带引号(只需键入
test.bat
)。但是,如果完成了相同的测试,调用文件作为
“test.bat”
,您将检索当前文件夹

D:\>type c:\windows\test.bat
@echo %~dp0
D:\>
D:\>test.bat
C:\Windows\

D:\>"test.bat"
D:\

D:\>cd temp

D:\temp>test.bat
C:\Windows\

D:\temp>"test.bat"
D:\temp\
我没有访问2003和2008的权限进行检查,但“可能”批处理文件调用的配置已更改

(在本例中,问题来自c#,引用的是完整的批处理文件名,但这是同一个问题)您将发现发生这种情况的原因

如果批处理文件名不包含空格或特殊字符,只需使用

Runtime.getRuntime().exec("cmd.exe /c SomeBatchFile.bat")
或者,如果无法避免文件名中的引号,可以更改批处理文件以使用子例程获取所需信息

@echo关闭
setlocal enableextensions disabledelayedexpansion
呼叫:getBatchFolder MY_HOME
回显%MY_HOME%
后藤:eof
:getBatchFolder returnVar
设置“%~1=%~dp0”
后藤:eof

我试图复制您的问题,唯一的方法是引用批处理文件,也就是说,当java程序调用
cmd
实例来处理批处理文件执行时,批处理文件名是
“SomeBatchFile.bat”
。您可以尝试从命令行执行批处理文件,并使用引号调用它以查看问题

也就是说,一个简单的批处理文件

@echo %~dp0
放置在路径的某个位置(例如,
c:\windows\test.bat
),当从命令行、任何文件夹调用时,您将检索到正确的文件夹,但不包括指向该文件夹的路径,也不带引号(只需键入
test.bat
)。但是,如果完成了相同的测试,调用文件作为
“test.bat”
,您将检索当前文件夹

D:\>type c:\windows\test.bat
@echo %~dp0
D:\>
D:\>test.bat
C:\Windows\

D:\>"test.bat"
D:\

D:\>cd temp

D:\temp>test.bat
C:\Windows\

D:\temp>"test.bat"
D:\temp\
我没有访问2003和2008的权限进行检查,但“可能”批处理文件调用的配置已更改

(在本例中,问题来自c#,引用的是完整的批处理文件名,但这是同一个问题)您将发现发生这种情况的原因

如果批处理文件名不包含空格或特殊字符,只需使用

Runtime.getRuntime().exec("cmd.exe /c SomeBatchFile.bat")
或者,如果无法避免文件名中的引号,可以更改批处理文件以使用子例程获取所需信息

@echo关闭
setlocal enableextensions disabledelayedexpansion
呼叫:getBatchFolder MY_HOME
回显%MY_HOME%
后藤:eof
:getBatchFolder returnVar
设置“%~1=%~dp0”
后藤:eof

将正确的路径作为第一个参数传递?文件的位置事先未知,用户将脚本保存在作为path变量一部分的任何位置,并执行java程序。此脚本选择脚本的位置并执行一些活动。因此,我想使用%dp0获取脚本的位置,这在Windows 2008 Server上失败。能否包含检索路径的批处理代码?@MC ND-脚本文件内容已添加到问题中。愚蠢的问题,但是我必须问:您确定在包含java程序位置的文件夹中没有
SomeBatchFile.bat
的副本吗?请将正确的路径作为第一个路径传递