簡體   English   中英

從 C# 控制台應用程序靜默讀/寫到 a.cmd 腳本

[英]Silently Read/Write to a .cmd script from a C# console application

我正在嘗試從 C# 控制台應用程序靜默讀寫 a.cmd 文件。 .cmd 文件如下所示:

ECHO OFF
set Input=""
set /p IsCustom="Do you want to create a custom deploy package ? (Y/N)"
set /p Input="Enter product name (press enter for none):"
ECHO ON
cd .\DeployScript

IF /I "%IsCustom%" == "Y" (
    nant -buildfile:Deploy.build -D:environment=Disk Deploy.LocalRelease -D:productname=%Input%
    cd ..
    GOTO END
)

nant -buildfile:Deploy.build -D:environment=Disk Deploy.NewLocalRelease -D:productname=%Input%
cd ..

:END

這是我要插入值的地方:

set /p IsCustom="Do you want to create a custom deploy package ? (Y/N)"
set /p Input="Enter product name (press enter for none):"

這是我在 C# 控制台應用程序中嘗試的內容,但我無法閱讀上述兩個問題並寫信給他們:

private static void ExecuteCmdFile()
{
    Process process = new Process();
    process.EnableRaisingEvents = true;
    process.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(process_OutputDataReceived);
    process.ErrorDataReceived += new System.Diagnostics.DataReceivedEventHandler(process_ErrorDataReceived);
    process.Exited += new System.EventHandler(process_Exited);

    process.StartInfo.FileName = Path + @"\createPackage.cmd";
    process.StartInfo.UseShellExecute = false;           
    process.StartInfo.RedirectStandardOutput = true;

    process.Start();          
    process.BeginOutputReadLine();
    process.WaitForExit();
}

static void process_Exited(object sender, EventArgs e)
{
    Console.WriteLine(string.Format("process exited with code {0}\n", ""));
}

static void process_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
    //Console.WriteLine(e.Data + "\n");
}

我無法閱讀 process_OutputDataReceived() 中的問題,也沒有關於插入值的線索。 只是想知道我是否正確地從 C# 應用程序讀取/寫入 .cmd 文件? 我在這里遺漏了什么還是有其他方法?

處理批處理文件的 Windows 命令處理器cmd.exe不是為與其他進程通信而設計的。 它被設計用於一個接一個地執行命令和可執行文件,並支持簡單的IF條件和GOTO來控制命令/程序執行的順序和FOR在循環中重復執行某些操作。 而已。

我建議將批處理文件修改為以下代碼:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "IsCustom=%~1"
if defined IsCustom goto CheckInput
%SystemRoot%\System32\choice.exe /C NY /N /M "Do you want to create a custom deploy package (Y/N)?"
if errorlevel 2 (set "IsCustom=Y") else set "IsCustom=N"

:CheckInput
set "Input=%~2"
if not defined Input goto InputPrompt
if /I "%Input%" == "/N" set "Input="
goto ProcessData

:InputPrompt
set /P "Input=Enter product name (press enter for none): "
if not defined Input goto ProcessData
set "Input=%Input:"=%"

:ProcessData
cd /D "%~dp0DeployScript"
if /I "%IsCustom%" == "Y" (
    nant -buildfile:Deploy.build -D:environment=Disk Deploy.LocalRelease -D:productname="%Input%"
    goto END
)

nant -buildfile:Deploy.build -D:environment=Disk Deploy.NewLocalRelease -D:productname="%Input%"

:END
endlocal

現在批處理文件可以在沒有任何參數的情況下執行,在這種情況下,用戶會被提示兩次,以安全可靠的方式評估輸入。

但也可以從另一個可執行文件(例如在 C# 中編碼的程序或從命令提示符 window 或由另一個批處理文件調用的程序)中運行帶有一個或兩個 arguments 的批處理文件。

第一個參數分配給環境變量IsCustom ,該變量在沒有任何參數或以""作為第一個參數的情況下執行的批處理文件上未明確定義。 稍后用於引用環境變量IsCustom的字符串值的IF條件僅檢查字符串值是Y還是y以執行自定義操作。 作為第一個參數傳遞給批處理文件的任何其他參數字符串都會導致運行標准操作。

第二個參數分配給環境變量Input ,在沒有任何參數或以""作為第二個參數的情況下執行的批處理文件上也明確未定義。 如果第二個參數不區分大小寫,等於/N ,則批處理文件將此解釋為不使用產品名稱的顯式請求。

是/否提示是使用命令CHOICE完成的,如果調用批處理文件時不帶任何參數或使用""作為第一個參數,則強烈建議將其用於此類選擇提示。

如果在沒有第二個參數的情況下調用批處理文件或僅使用""作為第二個參數,則使用set /P完成第二個提示。 如果用戶完全輸入一個字符串,則從輸入字符串中刪除雙引號,以便其余行對輸入字符串進行安全可靠的處理。

目錄DeployScript很可能是包含批處理文件的目錄的子目錄,因此命令CD與選項/D一起使用,以便在需要時更改當前驅動器並明確地將子目錄DeployScript當前目錄,而與哪個目錄無關開始執行批處理文件時的當前目錄。

nant應使用文件擴展名引用,如果完整路徑由於相對於批處理文件路徑而眾所周知,或者已修復,則應使用完整路徑引用,這樣就可以在批處理文件中使用完全限定的文件名,因為它已完成外部命令CHOICE

命令ENDLOCAL導致初始當前目錄再次成為當前目錄SETLOCAL將當前目錄路徑推入堆棧。 ENDLOCAL從堆棧中彈出該路徑並使該目錄再次成為當前目錄(如果同時未刪除,這在此處是不可能的)。 因此,根本不需要執行cd..

現在 C# 編碼的應用程序可以運行cmd.exe選項/D/C以及帶有兩個 arguments YN和產品名稱或/N的完整路徑的批處理文件名。 There is no need anymore to communicate with cmd.exe processing the batch file or passing the arguments via standard input stream to the internal command SET of cmd.exe .

筆記:

I do not really understand why the C# Process class is used being a C# wrapper class for the Windows kernel function CreateProcess called with using the STARTUPINFO structure because it would be also possible to use the Process class to run nant directly by the C# coded program and當然還有批處理文件可能額外運行的任何其他可執行文件。 C# 編碼的應用程序可以直接訪問cmd.exe在處理批處理文件時使用的所有 Windows 庫函數。 因此,根據提供的有關任務的信息,我認為根本不需要為任務使用批處理文件。

要了解批處理文件中使用的命令及其工作原理,請打開命令提示符window,在其中執行以下命令,並仔細閱讀每個命令顯示的所有幫助頁面。

  • call /? ...解釋批處理文件參數引用
  • choice /?
  • cmd /?
  • echo /?
  • endlocal /?
  • goto /?
  • if /?
  • set /?
  • setlocal /?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM