Entwickler-Ecke

IO, XML und Registry - Delphi-Compiler in C#


Necaremus - Mi 17.11.10 17:19
Titel: Delphi-Compiler in C#
hi,
hoffe, dass ich im richtigen Unterforum poste. Falls nicht, bitte einfach verschieben.


ich versuche dateien via C# über die dcc32.exe von Delphi zu kompelieren, jedoch schaff ich es leider nicht.
hier der code:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
/* this is code */
        public int Execute(System.IO.FileInfo file)
        {
            string args = GetArgs(file.FullName);
            Process proc = new Process();
            proc.StartInfo.FileName = config.Dcc32Path;
            proc.StartInfo.Arguments = args;
            proc.StartInfo.RedirectStandardOutput = true;
            proc.StartInfo.RedirectStandardError = true;
            proc.StartInfo.CreateNoWindow = true;
            proc.StartInfo.UseShellExecute = false;
            proc.Start();
            proc.WaitForExit();
            string outPut = proc.StandardOutput.ReadToEnd();
            if (!String.IsNullOrEmpty(outPut))
                wixInstaller.WriteMessage(outPut, true);
            string error = proc.StandardError.ReadToEnd();
            if (!String.IsNullOrEmpty(error))
                wixInstaller.WriteMessage(error, true);
            int exitCode = proc.ExitCode;
            proc.Close();
            return exitCode;
        }

        private string GetArgs(string dprFile)
        {
            string u = @"E:\Development\___\src\Common;E:\Development\___\Packages\Bin;E:\Development\___\Packages\Lib;E:\Development\___\Packages\src;E:\Development\___\Packages\Tnt;E:\Development\___\Packages\greatis\ObjInsp\Source;E:\Development\___\Packages\greatis\FormDes\Source;E:\Development\___\Packages\GR32";
            u = u.Replace(";""\";\"");
            string r = String.Format(" -CC -B -Q -W- -H+ -U \"{0}\" \"{1}\"",
                /*0*/ u,//@"E:\Development\___\src\Common;E:\Development\___\Packages\Bin;E:\Development\___\Packages\Lib;E:\Development\___\Packages\src;E:\Development\___\Packages\Tnt;E:\Development\___\Packages\greatis\ObjInsp\Source;E:\Development\___\Packages\greatis\FormDes\Source;E:\Development\___\Packages\GR32";
                /*1*/ dprFile);
            return r;
        }


das prob, welches ich habe ist, dass der dcc32.exe bei mir immer ohne wirkliche fehlermeldung abstürzt.
ich habe es vorher schon anders probiert etc. pp...
ich bekomm es einfach nicht hin, dass das ding meine Datei richtig kompeliert.

"Normale" Dateien, d.h. ohne "-U"-Parameter, schaff ich zu kompelieren, weshalb irgendwo ein fehler beim "-U"-Parameter sein müsste.
jedoch wo?
ich komm nicht mehr weiter, need help.


so far


Greenberet - Mi 17.11.10 18:16

Ich kenn mich mit delphi zu wenig aus um dir da was genaues sagen zu können. Aber ein Fehler ist mir aufgefallen:

du ersetzt alle ; durch ";"

jetzt schauen wir uns mal den String nach dem Replace bis zum ersten ; an.


C#-Quelltext
1:
E:\Development\___\src\Common\";\"E                    


Hier fehlt das \" ganz am Anfang, sprich das Semikolon ist im String entkapselt(überall) und nicht der Trenner wie es sein sollte.


Eventuell kannst du auch nur ein zusätzliches am Ende und am Anfang setzen, dann brauchst du sie bei den Einzelnen nicht ersetzen.


Necaremus - Do 18.11.10 12:01

ich habe es gelöst, editier ich später für leute die es wissen wollen - ist bissel sehr tricky^^

zu deiner anmerkung: nein, da ist kein fehler drin, denn:

C#-Quelltext
1:
2:
3:
 string u = @"langer string mit vielen ; zwischen den pfaden"// der string wird als "normaler" string gespeichert, d.h.: "E:\\Bla\\Blubb\\PIPAPO\\"
u = u.Replace(";""\";\""); // nun sind alle Pfade gequoted, es fehlt lediglich ein quote am anfang und ende;
string s = String.Format("Blabla \"{0}\"", u); // nun auch am anfang und ende




===Edit===
so hier die "Lösung":
dcc32.exe sucht im directory nach einer dcc32.cfg und nimmt die daten daraus. Dies ermöglicht uns die parameter in die Datei zu packen und nicht per args zu übergeben. Wir müssen also in jeder directpry eine passende dcc32.cfg erstellen und die workingDirectory vom dcc32.exe auf file.Directory setzen.

erstmal meine funktion für das anpassen der dcc32.cfg datei:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
private void Init()
        {//*
            /* TODO:
             * Init the -u and -r etc 4 delphi compiler... */

            string u1 = "-u\"" + Config.DelphiDir + "\\lib\";\"" + Config.DelphiDir + "\\lib\\Obj\"\r\n";
            string u2 = "";
            string r  = "-r\"" + Config.DelphiDir + "\\lib\"";
            switch (Config.Project.Name)
            {
                case "____1":
                    u2 = "-u\"path\";\"path[...]\"\r\n";
                    break;
                case "____2":
                    u2 = "-u\"path\";\"path[...]\"\r\n";
                    break;
                case "____3":
                    u2 = @"path;path;path;path;path;path;"
                    u2 = String.Format("-u\"{0}\"\r\n", u2.Replace(";""\";\""));
                    // ... should have started doing it like this earlier, much less work :/
                    break;
                case /*[...]*/:
                     // [...]
                default:
                    break;
            }
            if (Config.ForCruiseControl)
                u2 = u2.Replace("E:\\""C:\\");
            Config.Dcc32Content = "-aWinTypes=Windows;WinProcs=Windows;DbiProcs=BDE;DbiTypes=BDE;DbiErrs=BDE\r\n" + u1 + u2 + r;
        }


nachdem ich also den content hab, kommt der eigentliche compiler:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
public class DelphiCompiler
    {
        private Config config;
        private WixInstaller wixInstaller;
        public DelphiCompiler(Config config, WixInstaller wixInstaller)
        {
            this.config = config;
            this.wixInstaller = wixInstaller;            
        }
        public int Execute()
        {
            wixInstaller.WriteMessage("DelphiCompiler gestartet..."true);
            int error = 0;
            FileInfo[] files = GetFiles();
            DirectoryInfo tmpDir = new DirectoryInfo(config.BufferPath);
            string filePath = "";
            foreach (FileInfo file in files)
            {
                if (config.Cancel)
                    return -1;
                if (file.Extension != ".dpr"
                    continue;
                if (file.Directory != tmpDir)
                {
                    DeleteCfg(filePath);
                    filePath = file.Directory + "\\dcc32.cfg";
                    tmpDir = file.Directory;
                    CreateCfg(filePath);
                }
                wixInstaller.WriteMessage(String.Format("Kompeliere die Datei: \"{0}\"...", file.FullName), true);
                error = Execute(file);
                if (error != 0)
                {
                    wixInstaller.WriteMessage(String.Format("Konnte die Datei \"{0}\" nicht kompelieren.\r\nExitCode: {1}", file, error), true);
                    //* break;
                    error = 0;
                }
            }
            wixInstaller.WriteMessage("DelphiCompiler abgeschlossen."true);
            return error;
        }

        private int Execute(FileInfo file)
        {
            Process proc = new Process();
            proc.StartInfo.FileName = config.Dcc32Path;
            proc.StartInfo.WorkingDirectory = file.Directory.ToString();
            proc.StartInfo.Arguments = "-B \"" + file.FullName + '"';
            proc.StartInfo.RedirectStandardOutput = true;
            proc.StartInfo.RedirectStandardError = true;
            proc.StartInfo.CreateNoWindow = true;
            proc.StartInfo.UseShellExecute = false;
            proc.Start();
            string outPut = proc.StandardOutput.ReadToEnd();
            if (!String.IsNullOrEmpty(outPut))
                wixInstaller.WriteMessage(outPut, true);
            string error = proc.StandardError.ReadToEnd();
            if (!String.IsNullOrEmpty(error))
                wixInstaller.WriteMessage(error, true);
            proc.WaitForExit();
            int exitCode = proc.ExitCode;
            proc.Close();
            return exitCode;
        }

        private FileInfo[] GetFiles()
        {
            DirectoryInfo dir = new DirectoryInfo(config.BufferPath + "\\" + config.ProjectRep);
            return dir.GetFiles("*.dpr", SearchOption.AllDirectories);
        }

        private void CreateCfg(string filePath)
        {
            using (StreamWriter writer = new StreamWriter(filePath, false, Encoding.GetEncoding(1252)))
            {
                writer.Write(config.Dcc32Content);
            }
        }

        private void DeleteCfg(string filePath)
        {
            if (File.Exists(filePath))
                File.Delete(filePath);
        }
    }


blubb und ja, der gibt grad zwingend 0 zurück^^ das muss i noch anpassen