Entwickler-Ecke

Sonstiges (.NET) - Batch über C# ausführen


Delete - Do 25.02.10 16:51
Titel: Batch über C# ausführen
Hallo zusammen,

bin noch ein ziemlicher Noob in C# und wende mich deshalb mit einem kleinen Anliegen an euch.

Ich habe schon sehr viel mit Batch programmiert und möchte deshalb Teile meiner Programme über Batch ausführen lassen.
Ich kommen aber einfach nicht weiter und hab schon überall im Internet gesucht.


Was ich bisher weis
Das ganze müsste ungefähr so aussehen:
System.Diagnistics.Process.Start ("cmd" "/k oder /c" "befehl")

Was ich nicht weis
Was muss ich bei using hinschreiben?
Wie gebe ich das ganze in CMD aus?
Wie baue ich Schleifen mit Calls ein?

Zitat:
for /f "delims=" %%g in ('.......befehl.......') do for /f "tokens=3*" %%i in ("%%g") do set "var=%%i" & call :procedure

:procedure
echo %var%
if /i "%var%"=="1" (mk dir1) else (mk dir2)


Ich komme damit überhaupt nicht weiter. Ich hoffe mal einer von euch kann mir helfen!


JüTho - Do 25.02.10 18:23

Hallo und :welcome:

Ohne Argumente geht es einfacher:

C#-Quelltext
1:
System.Diagnostics.Process.Start("befehl");                    

Mit Argumenten musst du über eine Process-Instanz gehen sowie zwischen Befehl und Argumenten trennen.

Vor etwa zwei Tagen hatten wir schon einmal eine Diskussion zu bat-Dateien. Die ging zwar ziemlich durcheinander, aber die ersten Antworten von danielf sollten zu deiner Frage passen.

Zitat:
Was muss ich bei using hinschreiben?

Wenn du (wie oben) den vollständigen Namen der Klasse benutzt: gar nichts. using ist insofern nur eine Erleichterung für Schreibfaule (also für alle Programmierer), die den Namespace nur einmal schreiben wollen und nicht in jeder Zeile:

C#-Quelltext
1:
2:
using System.Diagnostics;
Process.Start("befehl");


Zitat:
Wie gebe ich das ganze in CMD aus?

Das sollte durch Process.Start automatisch gehen.

Zitat:
Wie baue ich Schleifen mit Calls ein?

So komplex habe ich niemals mit call gearbeitet; und batch-Dateien habe ich etwa vor zehn Jahren zur Seite gelegt. Dafür haben wir doch "Hochsprachen".

Gruß Jürgen


Delete - Do 25.02.10 18:57

Schonmal Danke für die Antwort :-) Ich lerne grade noch die Hochsprache ;-)

Obwohl wenn ich z.B.


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Process.Start("echo off");
            Process.Start("echo TEST");
            Process.Start("pause>nul");
        }
    }
}


im Debug Modus starte sagt VStudio "Das System kann die angegebene Datei nicht finden".
Habe das einfach als Standart Konsolenanwendung genommen. Bin ja noch ziehmlich neu^^


danielf - Do 25.02.10 21:57

Hallo,

wie Jürgen gesagt hat, musst du eine Prozess-Instanz erzeugen und dort den Befehl und die Argumente getrennt zuweisen.

Schau dir am Besten MSDN [http://msdn.microsoft.com/de-de/library/system.diagnostics.process.aspx] dazu an. Da findest du zu allen Klassen immer Beispiele.

Gruß Daniel


Kha - Fr 26.02.10 00:36

user profile iconaraBong hat folgendes geschrieben Zum zitierten Posting springen:
System.Diagnistics.Process.Start ("cmd" "/k oder /c" "befehl")
Das ist schon der richtige Weg, um wirkliche CMD-Befehle ausführen zu können, aber afaik kannst du mit /K und /C immer nur einen einzelnen Befehl absetzen. Für mehrere musst du anscheinend eine temporäre Batch-Datei erstellen, oder du integrierst CMD über ProcessStartInfo.UseShellExecute = false direkt in dein Programm.

F#-Code
1:
2:
3:
4:
5:
open System.Diagnostics

let proc = Process.Start(ProcessStartInfo("cmd", RedirectStandardInput = true, UseShellExecute = false))
proc.StandardInput.WriteLine "echo off"
proc.StandardInput.WriteLine "echo test"


Delete - So 28.02.10 18:23

Klappt irgendwie alles nicht. Ich hab das schon alles ausprobiert aber bei jedem gabs errors oder es hat sich nichts getan.


norman2306 - So 28.02.10 20:22

Was willst du denn mit der batch datei machen, was du nicht mit c# machen kannst?


Delete - So 28.02.10 22:26

Zum Beispiel sowas:


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
set "all="
for /f "delims=" %%g in ('reg query "HKLM\software\abc...."') do for /f "tokens=3*" %%i in ("%%g") do set "var=%%i" & call :procedure
:procedure
echo %var%
echo.
set "all=%all% %var%
goto :eof
echo %all%
pause>nul


übersetzt:
Variable all = leer
für jeden Schlüssel aus HKLM\software\abc wird der Wert rausgesucht und in die Variable var gesetzt. Dann wird die Prozedur ":procedure" aufgerufen.
--------Beginn der Prozedure
Gibt den Wert der Variable var aus.
Gibt eine leere Zeile aus
Setzt die Variable all auf "all Leerzeichen var"
Beendet den Durchlauf und beginnt wieder von vorne bis alle Schlüssel durch sind
--------Ende der Prozedur und for-Schleife
Gibt alle gesammelten Werte von den Variablen var wieder.
Pausiert das Programm ohne Eingabeaufforderung.

Moderiert von user profile iconChristian S.: Code-Tags hinzugefügt


Kha - So 28.02.10 22:42

Und was ist nun die Antwort auf
user profile iconnorman2306 hat folgendes geschrieben Zum zitierten Posting springen:
[...] was du nicht mit c# machen kannst?

;) ?

Wenn du das Problem aber weiter verfolgen willst, bräuchten wir zum Helfen etwas mehr Input als "Klappt irgendwie alles nicht".


Delete - Mo 01.03.10 00:43

Wie schon gesagt bin ich noch ein ziemlicher Noob und hab derzeit relativ wenig Zeit so richtig mit C# anzufangen.

Also kann ich eigentlich nur die ganz grundlegenden Dinge.

Also fürs erste bräuchte ich naturlich ziemlich viel Hilfe was C# angeht, weil Batch über C# laufen lassen ist ja nicht so der Burner^^

Also was ich bräuchte:

Zum Thema Registry:
Registry-Ordner auslesen mit foreach-Schleife
Name des Wertes in Variablesetzen
Inhalt eines Wertes (z.B. text,zahl,adresse in Variablen textinhalt=text zahlinhalt=zahl adressinhalt=adresse)

Und wie ich dann damit eine Prozedur aufrufen kann...

Ach ja.... so nebenbei^^ kann man über C# auch Sachen downloaden? Bei Batch braucht man für HTTP-Downloads ein Addon.


norman2306 - Mo 01.03.10 01:46

Die Registry auslesen ist Relativ einfach:

Erstmal brauchst du das:

C#-Quelltext
1:
using Microsoft.Win32;                    


Um an einen bestimmten Key zu kommen:


C#-Quelltext
1:
RegistryKey key = Registry.CurrentUser.OpenSubKey(path, true);                    


und um an den Value zu kommen

C#-Quelltext
1:
object value = key.GetValue(name);                    


um den Value zu setzen:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
if (key == null)
{
    key = Registry.CurrentUser.CreateSubKey(path, RegistryKeyPermissionCheck.ReadWriteSubTree);
    key.CreateSubKey(name, RegistryKeyPermissionCheck.ReadWriteSubTree);
    key.SetValue(name, value);
}
if (key.GetValue(name) != null)
{
    key.SetValue(name, value);
}
else
{
    key.CreateSubKey(name, RegistryKeyPermissionCheck.ReadWriteSubTree);
    key.SetValue(name, value);
}


und um die Namen aller Subs zu bekommen:


C#-Quelltext
1:
key.GetSubKeyNames();                    


Also kleines Beispiel:


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
RegistryKey key = Registry.CurrentUser.OpenSubKey("Software//MyApps//abc"true);
if (key != null)
{
    string[] subs = key.GetSubKeyNames();

    foreach (string subkey in subs)
    {
        key.SetValue(1);
    }
}


Hoffe, dass hilft dir weiter.


danielf - Mo 01.03.10 08:42

Hallo,

darüber hinaus ist es möglich, Dateien aus dem Internet mit .NET herunterzuladen. Dafür gibt es die Klasse WebClient. Ein sehr einfaches Tutorial findest du hier [http://www.geekpedia.com/tutorial66_Using-WebClient-to-download-a-file.html].


C#-Quelltext
1:
2:
WebClient wc = new WebClient();
wc.DownloadFile("internetpfad","localpfad");


Noch eine Anmerkung zu dem Thread. Wenn du dir unsicher bist, ob es in C# geht oder nicht, kannst du dies auch hier Äußern und wir können es Diskutieren. Uns Erstmal die erklären lassen, wie du einen Prozess startest und dann sagen bätsch, dass brauch ich eigentlich gar nicht, ist ziemlich umständlich und unnötig.


C#-Quelltext
1:
2:
[DllImport("KERNEL32.DLL")]
public static extern bool SetEnvironmentVariable(string VariableName, string VariableValue);


Also am Besten nochmal überlegen was du machen willst und diese Überlegungen vorschlagen, bevor du in die "falsche" Richtung rennst.

Gruß Daniel