关于更改目录中的批处理文件〜DP0变化 [英] In Batch file ~dp0 changes on changing directory

查看:171
本文介绍了关于更改目录中的批处理文件〜DP0变化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下内容的批处理文件

I have a batch file with following content

echo %~dp0
CD Arvind
echo %~dp0

即使在更改目录值如果〜DP0一样了。
但是,如果我运行CSHARP方案,CD后〜DP0的值更改此批处理文件。它现在指向新的目录。以下是我使用code:

Even after changing directory value if ~dp0 is same. However if I run this batch file from CSharp program, the value of ~dp0 changes after CD. It now points to new directory. Following is the code that I use:

Directory.SetCurrentDirectory(//Dir where batch file resides);
ProcessStartInfo ProcessInfo;
Process process = new Process();
ProcessInfo = new ProcessStartInfo("mybatfile.bat");
ProcessInfo.UseShellExecute = false;
ProcessInfo.RedirectStandardOutput = true;
process = Process.Start(ProcessInfo);
process.WaitForExit();
ExitCode = process.ExitCode;
process.Close();

为什么会出现通过不同的方式执行相同的脚本输出有区别吗?
我在这里缺少一些东西吗?

Why is there a difference in output on executing same script by different ways? Am I missing some thing here?

推荐答案

这个问题开始在这一点上的讨论,和一些测试是为了确定原因。因此,在的cmd.exe ...一些调试(后这是一个的 32位Windows XP的cmd.exe 的但作为的行为是一致的在较新的系统的版本,可能使用相同或类似的code)

This question started the discussion on this point, and some testing was done to determine why. So, after some debugging inside cmd.exe ... (this is for a 32 bit Windows XP cmd.exe but as the behaviour is consistent on newer system versions, probably the same or similar code is used)

在杰布的回答中指出

It's a problem with the quotes and %~0.
cmd.exe handles %~0 in a special way

和这里杰布是正确的。

运行批处理文件的当前上下文里面有到当前的批处理文件,一个变量,包含正在运行的批处理文件的完整路径和文件名的引用。

Inside the current context of the running batch file there is a reference to the current batch file, a "variable" containing the full path and file name of the running batch file.

当一个变量被访问,它的价值是由现有变量列表检索但如果请求的变量%0 ,有的改良剂已要求(使用),那么在运行批处理参考变量的数据被使用。

When a variable is accessed, its value is retrieved from a list of available variables but if the variable requested is %0, and some modifier has been requested (~ is used) then the data in the running batch reference "variable" is used.

的使用已经在变量另一种效果。如果该值是引用,报价将被删除。这里有一个在code的错误。这是codeD类似(这里简化汇编伪code)

But the usage of ~ has another effect in the variables. If the value is quoted, quotes are removed. And here there is a bug in the code. It is coded something like (here simplified assembler to pseudocode)

value = varList[varName]
if (value && value[0] == quote ){
    value = unquote(value)
} else if (varName == '0') {
    value = batchFullName
}

是的,这意味着,当该批处理文件是引用,第一部分的如果被执行,充分借鉴到批处理文件中不使用,而是检索的值是用来调用它时引用该批处理文件中的字符串。

And yes, this means that when the batch file is quoted, the first part of the if is executed and the full reference to the batch file is not used, instead the value retrieved is the string used to reference the batch file when calling it.

然后会发生什么事?如果当批量文件名为使用的全路径,那么就没有问题。但是,如果在呼叫不使用完整的路径,在该路径的任何元素不需要被检索在间歇呼叫present。这检索假定相对路径。

What happens then? If when the batch file was called the full path was used, then there will be no problem. But if the full path is not used in the call, any element in the path not present in the batch call needs to be retrieved. This retrieval assumes relative paths.

一个简单的批处理文件( TEST.CMD

A simple batch file (test.cmd)

@echo off
echo %~f0

在使用测试(不扩展,不包括引号),我们得到Ç叫:\\地方\\ TEST.CMD

When called using test (no extension, no quotes), we obtain c:\somewhere\test.cmd

在使用名为测试(没有扩展名,行情),我们得到 C:\\地方\\测试

When called using "test" (no extension, quotes), we obtain c:\somewhere\test

在第一种情况下,不带引号,使用正确的内在价值。在第二种情况下,作为呼叫被引用,该字符串用来调用批处理文件(测试)是不带引号的使用。当我们要求一个完整的路径,它被认为是一个相对引用一些所谓的测试

In the first case, without quotes, the correct internal value is used. In the second case, as the call is quoted, the string used to call the batch file ("test") is unquoted and used. As we are requesting a full path, it is considered a relative reference to something called test.

这是为什么。如何解决?

This is the why. How to solve?

从C#code


  • 不要使用引号: CMD / C batchfile.cmd

如果需要报价,使用完整路径在调用批处理文件。这样 0%包含了所有必要的信息。

If quotes are needed, use the full path in the call to the batch file. That way %0 contains all the needed information.

从批处理文件

批处理文件可以从任何地方任何方式被调用。检索当前批处理文件的信息的唯一可靠的方法是使用一个子程序。如果任何修饰符()时,在%0 将使用内部变量来获取数据。

Batch file can be invoked in any way from any place. The only reliable way to retrieve the information of the current batch file is to use a subroutine. If any modifier (~) is used, the %0 will use the internal "variable" to obtain the data.

@echo off
    setlocal enableextensions disabledelayedexpansion

    call :getCurrentBatch batch
    echo %batch%

    exit /b

:getCurrentBatch variableName
    set "%~1=%~f0"
    goto :eof

这将回显到控制台,以目前的批处理文件independtly你如何调用该文件,带或不带引号的完整路径。

This will echo to console the full path to the current batch file independtly of how you call the file, with or without quotes.

注意:为什么工作?为什么%〜子程序里面F0 引用返回不同的值?从子程序内部访问的数据是不一样的。当呼叫执行,新的批处理文件上下文在内存中创建,并且内部变量是用来初始化此背景下。

note: Why does it work? Why the %~f0 reference inside a subroutine return a different value? The data accessed from inside the subroutine is not the same. When the call is executed, a new batch file context is created in memory, and the internal "variable" is used to initialize this context.

这篇关于关于更改目录中的批处理文件〜DP0变化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆