Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Externe EXE aus C# ausführen mit Parametern

523 views
Skip to first unread message

Torben Schulz

unread,
Apr 2, 2003, 10:14:00 AM4/2/03
to
Hallo Forum,

dieses Posting landet nur einmal hier, versprochen :-))

Jetzt habe ich folgendes Problem:

Ich möchte im Laufe einer Installation die
Konsolenanwendung isqlw.exe auf dem Zielrechner ausführen,
also sowas:

System.Diagnostics.Process.Start(@"isqlw.exe -localhost -
E -i meinScript.sql -o XX:\res.sql");

So findet er die isql.exe-Datei allerdings nicht, und den
Pfad fest einzuprogrammierung wäre nicht gut.
Ich würde gerne die Datei isqlw.exe im Filesystem des
Zielrechners suchen und mir den Pfad merken, dann die
Datei aufrufen.

Die Datei meinScript.sql ist als embedded Resource in
meinem Tool mit drin, der Output res.sql soll dort
abgelegt werden, wo das Programm hininstalliert wird.
(also Pfad XX)
Wie kann ich das derart flexibel gestalten, dass es etwa
so läuft:

String myPath //Pfad zur isqlw.exe

System.Diagnostics.Process.Start(@"myPath:\isqlw.exe -
localhost -E -i meinScript.sql -o myPath\res.sql");

Geht das überhaupt, dass diesem externen Tool isqlw eine
embedded resource zugewiesen wird, oder sollte ich die
myScript vorher auf die HD speichern, um sie isqlw
übergeben zu können?


Viele Grüße und vielen Dank,
Torben

Herfried K. Wagner

unread,
Apr 2, 2003, 1:32:06 PM4/2/03
to
Hallo Torben!

"Torben Schulz" <grim...@gmx.net> schrieb:


>Ich möchte im Laufe einer Installation die
>Konsolenanwendung isqlw.exe auf dem Zielrechner ausführen,
>also sowas:
>
>System.Diagnostics.Process.Start(@"isqlw.exe -localhost -
>E -i meinScript.sql -o XX:\res.sql");

Schau dir mal die Klasse ProcessStartInfo an:

\\\
Dim psi As New ProcessStartInfo()
psi.FileName = "Bla.exe"
psi.Arguments = "-Bla -Na"
Process.Start(psi)
///

Grüsse,
Herfried K. Wagner


Elmar Boye

unread,
Apr 2, 2003, 1:53:23 PM4/2/03
to
Hallo Torben,

Torben Schulz <grim...@gmx.net> schrieb ...


> Ich möchte im Laufe einer Installation die
> Konsolenanwendung isqlw.exe auf dem Zielrechner ausführen,

Also Du suchst Dir das raus, was am ehesten schief
gehen kann ;-)

isqlw ist zum einen keine Konsolen, sondern eine
Windows-Anwendung und kennt nur zusätzlich einen
Kommandozeilenmodus. Dies mehr als Hinweis, damit
Du Dich nicht wunderst, wenn bei falschen Parametern
evtl. ein Dialog auftaucht...

> also sowas:
> System.Diagnostics.Process.Start(@"isqlw.exe -localhost -
> E -i meinScript.sql -o XX:\res.sql");
>
> So findet er die isql.exe-Datei allerdings nicht, und den
> Pfad fest einzuprogrammierung wäre nicht gut.

Zudem ist isqlw.exe ist nur verfügbar wenn die Client-Tools
bzw. eine SQL Server Vollversion installiert ist - weil
lizenzpflichtig. Bei der MSDE ist das Programm nicht dabei.

Aus obigen Gründen ist es eher sinnvoll osql.exe zu verwenden,
denn dass ist ein reines Kommandozeilenprogramm (und wird
von Microsoft selbst beim Setup verwendet) und immer auch
bei der MSDE dabei.
(Dafür gilt insbesondere der bereits gegebene Hinweis
auf OEM/Unicode!)

> Ich würde gerne die Datei isqlw.exe im Filesystem des
> Zielrechners suchen und mir den Pfad merken, dann die
> Datei aufrufen.

In beiden Fällen sollte auf einem Rechner der Client-Tools
oder MSDE installiert hat, das Programm im Suchpfad zu finden
sein, denn der SQL Server Setup erweitert die PATH Angabe.
Wenn Du Dich darauf nicht verlassen willst, musst Du die
Registry konsultieren. Geeignet wären:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\Setup
oder
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\80\Tools\ClientSetup

und dort "SQLPath" ergänzt um ein \BINN, was definitiv bei
MS an der Stelle hardcodiert ist (weil in den Setup-Packages
eingebaut).

>
> Die Datei meinScript.sql ist als embedded Resource in
> meinem Tool mit drin, der Output res.sql soll dort
> abgelegt werden, wo das Programm hininstalliert wird.

Nein, das klappt mit den Programmen selbst nicht.
Bei isqlw gar nicht, da es nur im Kommandozeilen-Modus läuft,
wenn man den -i und -o Parameter übergibt (siehe Warnung oben).
osql.exe kann prinzipiell auch von der Standard-Eingabe lesen
(wenn -i fehlt) und schreibt auch auf die Standardausgabe
(wenn -o fehlt)...

, oder sollte ich die
> myScript vorher auf die HD speichern, um sie isqlw
> übergeben zu können?

... aber ob das über ProcessStartInfo.RedirectXXX
sauber klappt, habe ich nie probiert (nicht zuletzt
weil ich seit Jahr und Tag meine Datenbanken sowieso
in SQL-Skripten auf Platte habe).

Und Platte hat den Vorteil, dass man schnell noch
mal was ändern kann.

Gruss
Elmar

P.S.: Für das Ausführen via Stream, was Du wohl erst
ad acta gelegt hast, noch mal was schnell Gestricktes -
da kommt der Stream allerdings noch aus einer Datei:

private static void SqlExecuteScript(
SqlConnection Connection,
string ScriptFilename)
{
// Optimist: Unicode oder ANSI (Windows) Codierung
System.IO.StreamReader srScript = new System.IO.StreamReader(ScriptFilename);
System.Text.StringBuilder sb = new System.Text.StringBuilder(2048);
string line;

try
{
while(srScript.Peek() > -1)
{
line = srScript.ReadLine();
if (String.Compare(line.TrimStart(), 0, "GO", 0, 2, true) == 0)
{
if (sb.Length > 0)
{
SqlExecuteBatch (sb.ToString(), Connection);
sb.Length = 0;
}
}
else
{
sb.Append(line);
sb.Append("\r\n");
}
}
if (sb.Length > 0)
SqlExecuteBatch (sb.ToString(), Connection);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
finally
{
srScript.Close();
}
}

private static void SqlExecuteBatch(string CommandText, SqlConnection Connection)
{
if (CommandText == null || CommandText.Length == 0) return;

ConnectionState IsClosed = Connection.State;
try
{
if (IsClosed == ConnectionState.Closed)
Connection.Open();

SqlCommand cmd = new SqlCommand(CommandText, Connection);
cmd.CommandTimeout = 0;

cmd.ExecuteNonQuery ();
}
catch(SqlException e)
{
foreach (SqlError err in e.Errors)
Console.WriteLine ("Zeile {0}, Fehler {1}: {2}", err.LineNumber, err.Number, err.Message);
}
finally
{
if (IsClosed == ConnectionState.Closed && Connection.State == ConnectionState.Open)
Connection.Close ();
}
}

Torben Schulz

unread,
Apr 3, 2003, 1:59:44 AM4/3/03
to
Hallo Elmar,

vielen Dank für die ausführliche Antwort.

>-----Originalnachricht-----


>Hallo Torben,
>
>Torben Schulz <grim...@gmx.net> schrieb ...
>> Ich möchte im Laufe einer Installation die
>> Konsolenanwendung isqlw.exe auf dem Zielrechner
ausführen,
>
>Also Du suchst Dir das raus, was am ehesten schief
>gehen kann ;-)

>
>isqlw ist zum einen keine Konsolen, sondern eine
>Windows-Anwendung und kennt nur zusätzlich einen
>Kommandozeilenmodus. Dies mehr als Hinweis, damit
>Du Dich nicht wunderst, wenn bei falschen Parametern
>evtl. ein Dialog auftaucht...
>
>> also sowas:
>> System.Diagnostics.Process.Start(@"isqlw.exe -
localhost -
>> E -i meinScript.sql -o XX:\res.sql");
>>
>> So findet er die isql.exe-Datei allerdings nicht, und
den
>> Pfad fest einzuprogrammierung wäre nicht gut.


>
>Zudem ist isqlw.exe ist nur verfügbar wenn die Client-
Tools
>bzw. eine SQL Server Vollversion installiert ist - weil
>lizenzpflichtig. Bei der MSDE ist das Programm nicht
dabei.
<<<<<<<<<<<<<<<<<<

Ja, das wird vorausgesetzt, dass diese Tools installiert
sind. Die Vollversion ist drauf und isqlw ebenso.
In der Konsole klappt der Befehl

isqlw.exe -localhost -E -i d:\meinScript.sql -o :\res.sql

auch prima, aber sobald das von C# aufgerufen wird, kann
er 'die angegebene Datei' (damit kann er ja nur isqlw
meinen) nicht finden.
<<<<<<<<<<<<<<<<<<<<


>
>Aus obigen Gründen ist es eher sinnvoll osql.exe zu
verwenden,
>denn dass ist ein reines Kommandozeilenprogramm (und wird
>von Microsoft selbst beim Setup verwendet) und immer auch
>bei der MSDE dabei.
>(Dafür gilt insbesondere der bereits gegebene Hinweis
>auf OEM/Unicode!)

<<<<<<<<<<<<<<<<<<<<<

Prima Tipp, ich probier es gleich mal aus.

<<<<<<<<<<<<<<<<<<<<<<

>
>> Ich würde gerne die Datei isqlw.exe im Filesystem des
>> Zielrechners suchen und mir den Pfad merken, dann die
>> Datei aufrufen.
>
>In beiden Fällen sollte auf einem Rechner der Client-Tools
>oder MSDE installiert hat, das Programm im Suchpfad zu
finden
>sein, denn der SQL Server Setup erweitert die PATH Angabe.
>Wenn Du Dich darauf nicht verlassen willst, musst Du die
>Registry konsultieren. Geeignet wären:
>HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\Setup
>oder
>HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL
Server\80\Tools\ClientSetup
>
>und dort "SQLPath" ergänzt um ein \BINN, was definitiv bei
>MS an der Stelle hardcodiert ist (weil in den Setup-
Packages
>eingebaut).


<<<<<<<<<<<<<<<<<<<<<<<<<
Das wird ja bereits erledigt sein, da die Konsole selber
ja isqlw auch findet. Nur aus C# eben nicht...


<<<<<<<<<<<<<<<<<<<<<<<<<<
>
>>
>> Die Datei meinScript.sql ist als embedded Resource in
>> meinem Tool mit drin, der Output res.sql soll dort
>> abgelegt werden, wo das Programm hininstalliert wird.
>
>Nein, das klappt mit den Programmen selbst nicht.
>Bei isqlw gar nicht, da es nur im Kommandozeilen-Modus
läuft,
>wenn man den -i und -o Parameter übergibt (siehe Warnung
oben).
>osql.exe kann prinzipiell auch von der Standard-Eingabe
lesen
>(wenn -i fehlt) und schreibt auch auf die Standardausgabe
>(wenn -o fehlt)...
>
>, oder sollte ich die
>> myScript vorher auf die HD speichern, um sie isqlw
>> übergeben zu können?
>


<<<<<<<<<<<<<<<<<<<<<<<<<<<

Ich probiere osql mal aus.
Ja, ich werde das *.sql auf die Ziel-HD kopieren, und nach
der Ausführung wieder entfernen.
Da wäre fast ein normales Batch-Programm geeigneter :-)


>.... aber ob das über ProcessStartInfo.RedirectXXX


>sauber klappt, habe ich nie probiert (nicht zuletzt
>weil ich seit Jahr und Tag meine Datenbanken sowieso
>in SQL-Skripten auf Platte habe).
>
>Und Platte hat den Vorteil, dass man schnell noch
>mal was ändern kann.
>
>Gruss
>Elmar
>
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

Tja, ich fand das mit dem Stream auch schöner, 'echter'.
Aber es klappte nicht richtig, auch ohne GO hat er
zumindest die Views übersprungen, die StoredProcedures
waren auch unauffindbar.

Ich probiere gerade Deinen Code (herzlichen Dank dafür),
habe aber wieder ein Problem:
Er mault hier:

ConnectionState IsClosed = Connection.State;


Ich habe mit using eingebunden:
using System;
using System.Collections;
using System.ComponentModel;
using System.Configuration.Install;
using System.Windows.Forms;
using System.IO ;
using System.Reflection ;
using System.Data .SqlClient ;

Nochmals vielen Dank für Deine Hilfe,

Torben

>.
>

Torben Schulz

unread,
Apr 3, 2003, 2:01:55 AM4/3/03
to
Hallo Herfried,

vielen Dank für Deinen Tipp, ich schaue mir die Klasse mal
an.

Viele Grüße,

Torben


>-----Originalnachricht-----

>.
>

Elmar Boye

unread,
Apr 3, 2003, 3:26:54 AM4/3/03
to
Hallo Torben,

Torben Schulz <grim...@gmx.net> schrieb ...
>> Torben Schulz <grim...@gmx.net> schrieb ...
>>> Ich möchte im Laufe einer Installation die
>>> Konsolenanwendung isqlw.exe auf dem Zielrechner ausführen,
>>
>

> Ja, das wird vorausgesetzt, dass diese Tools installiert
> sind. Die Vollversion ist drauf und isqlw ebenso.
> In der Konsole klappt der Befehl
>
> isqlw.exe -localhost -E -i d:\meinScript.sql -o :\res.sql


also der Befehl sah mir gestern schon etwas zerstückelt
aus und ich habs aufs Vertippen geschoben...

Eine korrekte Zeile sähe in etwa aus
isqlw.exe -E -S localhost -d master -i D:\meinScript.sql -o D:\res.out


> auch prima, aber sobald das von C# aufgerufen wird, kann
> er 'die angegebene Datei' (damit kann er ja nur isqlw
> meinen) nicht finden.

Also mal gerade etwas probiert wie:

static void IsqlwExecuteScript(
string ServerName,
string DatabaseName,
string ScriptFileName)
{
if (System.IO.File.Exists(ScriptFileName) == false) return;

System.Diagnostics.Process p = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo();

psi.FileName = "isqlw.exe";
psi.Arguments = String.Format("-E -S {0} -d {1} -i {2} -o {3}",
ServerName,
DatabaseName,
ScriptFileName,
System.IO.Path.ChangeExtension(ScriptFileName, ".out"));
psi.WorkingDirectory = Environment.CurrentDirectory;
psi.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;

p.StartInfo = psi;
p.Start();

}

funktionierte ohne Probleme...

>
> <<<<<<<<<<<<<<<<<<<<<<<<<
> Das wird ja bereits erledigt sein, da die Konsole selber
> ja isqlw auch findet. Nur aus C# eben nicht...
> <<<<<<<<<<<<<<<<<<<<<<<<<<

... in ECHO %PATH%, kommt allerdings auch die diskutierte Pfadangabe
vor. zwar habe ich die Process-Klassen unter .NET bisher nicht
grossartig verwendet, aber die Regeln sollten dem Win32-API
für CreateProcess - siehe Platform SDK - entsprechen und danach
werden u. a. die Pfade laut PATH durchlaufen.


> Ich probiere osql mal aus.

... da gilt insofern gleiches.

>
> Ich probiere gerade Deinen Code (herzlichen Dank dafür),
> habe aber wieder ein Problem:
> Er mault hier:
>
> ConnectionState IsClosed = Connection.State;
>

vollqualifziert wäre das
System.Data.ConnectionState IsClosed = Connection.State;
(Tja, das "wo isser denn" beginnt bereits wieder... ;-)

Gruss
Elmar

Torben Schulz

unread,
Apr 3, 2003, 3:54:32 AM4/3/03
to
Hallo Elmar,

vielen Dank für den Hinweis System.Data. *g*

Nun kompiliert er wunderbar, ich mache mich ans
ausprobieren.

Die isqlw-Version ist endlich fertig und läuft- puh!

Viele Grüße,

Torben

>-----Originalnachricht-----

>.... in ECHO %PATH%, kommt allerdings auch die

diskutierte Pfadangabe
>vor. zwar habe ich die Process-Klassen unter .NET bisher
nicht
>grossartig verwendet, aber die Regeln sollten dem Win32-
API
>für CreateProcess - siehe Platform SDK - entsprechen und
danach
>werden u. a. die Pfade laut PATH durchlaufen.
>
>
>> Ich probiere osql mal aus.
>

>.... da gilt insofern gleiches.


>
>>
>> Ich probiere gerade Deinen Code (herzlichen Dank dafür),
>> habe aber wieder ein Problem:
>> Er mault hier:
>>
>> ConnectionState IsClosed = Connection.State;
>>
>
>vollqualifziert wäre das
>System.Data.ConnectionState IsClosed = Connection.State;
>(Tja, das "wo isser denn" beginnt bereits wieder... ;-)
>
>Gruss
>Elmar
>

>.
>

0 new messages