CoDeSys in Python

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
zedream
User
Beiträge: 11
Registriert: Donnerstag 12. Januar 2012, 14:36

Hallo,

ich schreibe ein Python-Skript, das CoDeSys (CoDeSys.exe) öffnet. CoDeSys ist eine eine Entwicklungsumgebung für Speicherprogrammierbare Steuerungen.
Das würde so gehen:

Code: Alles auswählen

import os
os.system(r'"C:\Program Files (x86)\3S CoDeSys\CoDeSys\Common\CoDeSys.exe"')
Allerdings mein Skript soll auf alle Rechner laufen, auf den CoDeSys installiert ist ohne etwas im Skript zu ändern. Deshalb darf der Speicherort der exe-Datei (CoDeSys.exe) nicht fest im Skript sein.

Ist mein Problem verständlich? Wenn Ja, hat jemand eine Idee, wie das geht?

Danke :)
sroken
User
Beiträge: 11
Registriert: Donnerstag 12. Januar 2012, 14:30

wäre es möglich auf den Rechnern die umgebungsvariablen zu ändern ... woebi, dann könntest du es auch im Skript ändern, wa :(
zedream
User
Beiträge: 11
Registriert: Donnerstag 12. Januar 2012, 14:36

was meinst du mit
umgebungsvariablen auf den rechnern ändern
?
sroken
User
Beiträge: 11
Registriert: Donnerstag 12. Januar 2012, 14:30

Der Begriff Umgebungsvariable ist ein Begriff aus dem Bereich der Betriebssysteme von Computern. Eine Umgebungsvariable enthält beliebige Zeichenketten, die in den meisten Fällen Pfade zu bestimmten Programmen oder Daten enthalten, sowie bestimmte Daten, die von mehreren Programmen verwendet werden können.
damit könntest du den kompletten Pfad weglassen und nur deine *.exe eintragen, müsstest aber an jeden Client gehen und die Umgebungsvariablen ändern.

und zwar so:

Code: Alles auswählen

Um Umgebungsvariablen anzuzeigen oder zu ändern:

    Klicken Sie mit der rechten Maustaste auf Arbeitsplatz und klicken Sie anschließend auf Eigenschaften.
    Klicken Sie auf die Registerkarte Erweitert.
    Klicken Sie auf Umgebungsvariablen. 
Ein von der Logik müsste das funktionieren, nur dann kannste eben auchd as Skript auf jedem Rechner anpassen ;)
zedream
User
Beiträge: 11
Registriert: Donnerstag 12. Januar 2012, 14:36

Das wäre eine Lösung aber ich habe auf die andere Rechner keine Zugriffrechte.
sroken
User
Beiträge: 11
Registriert: Donnerstag 12. Januar 2012, 14:30

hab ich mir fast gedacht :(
Dann muss ich leider erstmal passen :(
Benutzeravatar
sparrow
User
Beiträge: 4600
Registriert: Freitag 17. April 2009, 10:28

Statt os.system solltest du das subprocess-Modul verwenden.

Um die Datei zu finden könntest du das Dateisystem durchsuchen.

Gruß
Sparrow
zedream
User
Beiträge: 11
Registriert: Donnerstag 12. Januar 2012, 14:36

@sroke: danke dir für die Mühe :)

@sparrow: ich versuche mit dem folgenden Skript das Dateisystem zu finden:

Code: Alles auswählen

import configparser
import os 
text = "file.txt"
for root, dirs, files in os.walk('\\'):
    for name in files:
        if name == text:
            print(os.path.abspath(os.path.join(root, name)))
Das geht einwandfrei. Aber wenn ich nach einer exe-Datei suchen will (bsp. notepad.exe), das Skript findet sie nicht. Hast du vllt. eine Erklärung dafür?
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

zedream hat geschrieben: Das geht einwandfrei. Aber wenn ich nach einer exe-Datei suchen will (bsp. notepad.exe), das Skript findet sie nicht. Hast du vllt. eine Erklärung dafür?
Du musst dann "notepad.exe" an `text` binden und nicht "file.txt" :twisted:

Im Ernst: k.A. wieso er Dateien nicht finden sollte, die auf `.exe` enden. Das kann eigentlich nur daran liegen, dass er diese gar nicht erst druchläuft. Was ist denn `\\` für eine Pfadangabe? (Man könnte wohl auch einen RawString nehmen, dann wäre es nur ein Backslash) Ist das ein allgemeingültiger, OS unabhängiger Wurzelknoten? Ich kenne von Unix her nur "/"; und unter Windows gibt es doch gar keinen, oder?

Im übrigen kannst Du Dir die innere `for`-Schleife auch sparen:

Code: Alles auswählen

for root, dirs, files in os.walk('\\'):
    if text in files:
        print(os.path.abspath(os.path.join(root, name)))
Das sollte es auch tun.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
zedream
User
Beiträge: 11
Registriert: Donnerstag 12. Januar 2012, 14:36

Du musst dann "notepad.exe" an `text` binden und nicht "file.txt" :twisted:
natürlich binde ich "notepad.exe und nicht files.txt", wenn ich nach notepad.exe suche :wink:
Was ist denn `\\` für eine Pfadangabe?
Das ist, wenn ich die Festplatte nicht bestimmen will. Das heisst mein Skript soll alle Festplatten dursuchen. Es geht bei Dateien wie ".txt", ".cbl", ".ini".... aber nicht bei ".exe" (was ist rausgefunden habe!)
Im übrigen kannst Du Dir die innere `for`-Schleife auch sparen
Danke für den Vorschlag, du hast Recht.
Benutzeravatar
/me
User
Beiträge: 3561
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

zedream hat geschrieben:natürlich binde ich "notepad.exe und nicht files.txt", wenn ich nach notepad.exe suche :wink:
Hier geht es (Windows 7 64bit; Python 2.7.2 32bit).

Code: Alles auswählen

import os
filename = 'notepad.exe'
for root, dirs, files in os.walk('\\'):
    if filename in files:
        print(os.path.abspath(os.path.join(root, filename)))
liefert mir

Code: Alles auswählen

C:\Windows\notepad.exe
C:\Windows\System32\notepad.exe
C:\Windows\SysWOW64\notepad.exe
C:\Windows\winsxs\amd64_microsoft-windows-notepadwin_31bf3856ad364e35_6.1.7600.16385_none_9ebebe8614be1470\notepad.exe
C:\Windows\winsxs\amd64_microsoft-windows-notepad_31bf3856ad364e35_6.1.7600.16385_none_cb0f7f2289b0c21a\notepad.exe
C:\Windows\winsxs\wow64_microsoft-windows-notepad_31bf3856ad364e35_6.1.7600.16385_none_d5642974be118415\notepad.exe
zedream
User
Beiträge: 11
Registriert: Donnerstag 12. Januar 2012, 14:36

@/me: ja das habe in der Zwischenzeit schon hingekriegt trotzdem danke :)

Ein anderes Problem habe ich jetzt :D
mit

Code: Alles auswählen

os.system(r"C:\Windows\notepad.exe")
wird "notepad" ausgeführt. Wenn das Pfad Leerzeichen enthält, muss die Pfadangabe wie folgt angepasst werden:

Code: Alles auswählen

os.system(r'"C:\Program Files (x86)\Windows\notepad.exe"')
Wie mache ich diese Anpassung in meinem Skript??
Mein Skript sieht folgendermaßen aus:

Code: Alles auswählen

import os
text = "notepad.exe"
for root, dirs, files in os.walk('C:\\'):
    if text in files:
        pfad = os.path.abspath(os.path.join(root, text))
        print(pfad)
        os.system(pfad)
        break
wir gehen davon aus dass das Pfad Leerzeichen enthält !!
BlackJack

@zedream: Das ist einer der Gründe warum man den Umweg über eine Shell vermeiden sollte, also `os.system()`, und stattdessen die externen Programme mit dem `subprocess`-Modul *direkt* aufrufen sollte.
zedream
User
Beiträge: 11
Registriert: Donnerstag 12. Januar 2012, 14:36

Ich habe es doch hingekriegt :D

Code: Alles auswählen

import os 
text = "notepad.exe"
for root, dirs, files in os.walk('C:\\'):
    if text in files:
        pfad = os.path.abspath(os.path.join(root, text))
        print(pfad)
        os.system(r'"%s"' % pfad)
        break
Ich muss aber das Laufwerk bestimmen. Weisst jemand, ob es gehen würde ohne das Laufwerk zu bestimmen?

@BlackJack: Wenn du meinst , dass es mit `subprocess`-Modul besser wäre, würdest du bitte anhand eines Beispiels zeigen, wie sich "notepad" mit `subprocess`-Modul aufrufen lässt?
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

zedream hat geschrieben: @BlackJack: Wenn du meinst , dass es mit `subprocess`-Modul besser wäre, würdest du bitte anhand eines Beispiels zeigen, wie sich "notepad" mit `subprocess`-Modul aufrufen lässt?
Schau Dir doch mal die Doku dazu an. Dort gibt es auch viele Beispiele, die zeigen, wie man Anwendungsfälle anderer Module auf `subprocess` umstellt.

Ich kenne Deine Intention zwar nicht, aber mir gefällt Dein Code nicht so wirklich. Ich würde eine Funktion schreiben (`locate` ?), die das Dateisystem nach einer Datei durchsucht und diese bei Erfolg zurückliefert.

Das Ausführen dieser Datei würde ich damit auf jeden Fall von der Suche trennen. Das macht es übersichtlicher und vor allem auch schneller - denn auf Dauer könnte man sich überlegen, den Pfad persistent in einem ConfigFile abzulegen und nur bei Bedarf danach zu suchen.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
nomnom
User
Beiträge: 487
Registriert: Mittwoch 19. Mai 2010, 16:25

Der Ordner „\“ bei Windows ist doch das oberste Verzeichnis der Partition, auf der man sich gerade befindet?
JonasR
User
Beiträge: 251
Registriert: Mittwoch 12. Mai 2010, 13:59

Bin auch der Meinung dass \ das Rootverzeichniss der Systempartition ist, wenn man nicht explizit gewechselt hat.
zedream
User
Beiträge: 11
Registriert: Donnerstag 12. Januar 2012, 14:36

@Hyperion: danke für dein Tipp.

Jetzt habe ich 2 Funktionen; die erste sucht nach CoDeSys.exe und die zweite sucht nach einem anderen Python-Skript. Die zwei Funktionen:

Code: Alles auswählen

def runProcess(CoDeSys):
    for root, dirs, files in os.walk('C:\\'):
        if CoDeSys in files:
            return (os.path.abspath(os.path.join(root, CoDeSys)))

def PythonScript(ExportScript):
    for root, dirs, files in os.walk('D:\\'):
        if ExportScript in files:
            return ((os.path.abspath(os.path.join(root, ExportScript))))
Das zweite Skript hat die Aufgabe, ein CoDeSys-Projekt zu öffnen und dies als XML-Datei zu exportieren aber erst wenn CoDeSys schon offen ist (Das Projekt kann von außen nicht exportiert werden). Bisher habe ich das mit dem folgenden Skript gemacht

Code: Alles auswählen

subprocess.call(r'"C:\Program Files (x86)\3S CoDeSys\CoDeSys\Common\CoDeSys.exe" --Profile="CoDeSys V3.4 SP4 Patch 1" --runscript="D:\------\Python32\Export.py"')
CoDeSys wird aufgerufen und CoDeSys ruft das andere Skript Export.py innerhalb der CoDeSys-Umgebung. Nun versuche ich das mit den Funktionen zu machen, da ich den Pfad nicht so eingeben darf. Ich habe versucht die Funktionen nacheinander aufzurufen aber das geht logischerweise nicht :D

Hat jemand eine Idee?
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

zedream hat geschrieben:@Hyperion: danke für dein Tipp.
Na, also so solltest Du das nicht umsetzen...
zedream hat geschrieben: Jetzt habe ich 2 Funktionen; die erste sucht nach CoDeSys.exe und die zweite sucht nach einem anderen Python-Skript.

Code: Alles auswählen

def runProcess(CoDeSys):
    for root, dirs, files in os.walk('C:\\'):
        if CoDeSys in files:
            return (os.path.abspath(os.path.join(root, CoDeSys)))

def PythonScript(ExportScript):
    for root, dirs, files in os.walk('D:\\'):
        if ExportScript in files:
            return ((os.path.abspath(os.path.join(root, ExportScript))))
Ähem... schau Dir doch mal bitte die beiden Funktionen an, und dann beschreibe mit mal den Unterschied. (und nein, ich meine nicht das überflüssige Klammerpaar in der zweiten Funktion!)
zedream hat geschrieben: Das zweite Skript hat die Aufgabe, ein CoDeSys-Projekt zu öffnen
Was für ein zweites Script? Was ist denn das erste?

Den ganzen Rest habe ich nicht verstanden ehrlich gesagt. Ich habe keine Ahnung, wie dieses CoDeSys funzt, was es macht und wie da Deine Scripte reinspielen. Vielleicht haben ja andere mehr kapiert ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
zedream
User
Beiträge: 11
Registriert: Donnerstag 12. Januar 2012, 14:36

Also ich habe es schon hingekriegt. Ich danke euch allen :D Wenn ihr interesse habt, kann ich mal mein Skript posten.

Gruß
zedream
Antworten