/tol/cforge/android/29
Bash
bash
(Bash)
[#29] CFORGE Tool doesn't work with SP16
Last updated: 2020-08-11
/tol/cforge/android/7
Bash
bash
(Bash)
[#7] Avoid warnings from URL handlers
Last updated: 2018-08-09
/tol/cforge/android/2
Bash
bash
(Bash)
[#2] commit: Implement the action 'commit'
Last updated: 2018-08-09
/tol/cforge/android/13
Bash
bash
(Bash)
[#13] automatic build branch
Last updated: 2019-03-10
/tol/cforge/android/13
Bash
bash
(Bash)
[#13] Automatic Build
Last updated: 2019-03-10
cforge: ./branches/13-jobs/cforge/cforge/Package/CFORGE/Scripts/create-package.py
Bash
bash
(Bash)
import sys, os
import zipfile
import cds_script
import uuid
import ui
ManifestSkeleton="""<?xml version="1.0" encoding="ISO-8859-1"?>
<Package>
<Strings>
<String Id="GeneralName">
<Neutral>%s</Neutral>
</String>
<String Id="GeneralVendor">
<Neutral>%s</Neutral>
</String>
<String Id="GeneralCopyright">
<Neutral>%s</Neutral>
</String>
<String Id="GeneralDescription">
<Neutral>%s</Neutral>
</String>
<String Id="license">
<Neutral>%s</Neutral>
</String>
<String Id="TargetDir">
<Neutral>Target directory</Neutral>
</String>
<String Id="TargetDirDescription">
<Neutral>The target directory where the projects are saved.</Neutral>
</String>
</Strings>
<General>
<Id>{%s}</Id>
<Version>1.0.0.0</Version>
<Name>$GeneralName</Name>
<Vendor>$GeneralVendor</Vendor>
<Copyright>$GeneralCopyright</Copyright>
<Description>$GeneralDescription</Description>
<LicenseAgreement>$license</LicenseAgreement>
<RequiredInstallerVersion>3.5.10.0</RequiredInstallerVersion>
</General>
<TargetDirectoryDefinitions>
<TargetDirectoryDefinition>
<Id>1</Id>
<Name>$TargetDir</Name>
<Description>$TargetDirDescription</Description>
<PromptUser>True</PromptUser>
<DefaultValue>%%USERPROFILE%%\CODESYS Projects\</DefaultValue>
</TargetDirectoryDefinition>
</TargetDirectoryDefinitions>
<Components>
<Component>
<General>
<Id>1</Id>
<Name>Default</Name>
<Description>Default Package</Description>
<Selectable>false</Selectable>
<SelectedByDefault>true</SelectedByDefault>
</General>
<Dependencies>
</Dependencies>
<Items>
%s
</Items>
</Component>
</Components>
</Package>
"""
ManifestItemLibrary = """
<Library>
<Path>%s</Path>
</Library>
"""
ManifestItemDevDesc = """
<DeviceDescription>
<Path>%s</Path>
</DeviceDescription>
"""
ManifestItemProject = """
<File>
<Path>%s</Path>
<IgnoreArchiveFolder>True</IgnoreArchiveFolder>
<TargetFolder>$1</TargetFolder>
<Overwrite>
<Option>Yes</Option>
</Overwrite>
</File>
"""
# This is a cforge command (script file)
# this will be run as ironpython script.
# the filename of this script is automatically the corresponding cforge command
# with some magic functions you can easily integrate it nicely into cforge tool
# cforge_usage:
# here you can return an array of all possible arguments and options that can
# be passed to this command script
def cforge_usage():
help = [
["<path to local repository>", "---"]
]
return help
if len(sys.argv) <= 1:
print("Oh, there are no arguments. Perhaps you forgot something?")
sys.exit()
folder = sys.argv[1]
scriptpath = os.path.abspath(os.path.dirname(sys.argv[0]))
def zipdir(path, ziph):
# ziph is zipfile handle
for root, dirs, files in os.walk(path):
for file in files:
filename=os.path.join(root, file)
archname=filename[len(path)+1:]
print("Adding file: %s -> %s" % (filename, archname))
ziph.write(filename, arcname=archname)
# Discover package content
packageItems = ""
license = ""
for root, dirs, files in os.walk(folder):
for file in files:
filename=os.path.join(root, file)
archname=filename[len(folder)+1:]
if file.endswith(".project"):
packageItems += ManifestItemProject % (archname)
if file.endswith(".devdesc.xml"):
packageItems += ManifestItemDevDesc % (archname)
if file.endswith(".library"):
packageItems += ManifestItemLibrary % (archname)
if file == "license.txt":
license = archname;
if license == "":
file = open(os.path.join(folder, "license.txt"), "w")
if file:
file.write("Add license text...")
file.close();
license = "license.txt"
config = ui.Dialog("Create Package", PkgName=True, PkgVendor=True, PkgCopyright=True, PkgDescription=True)
if config != None:
guid = uuid.uuid1();
packageManifest = ManifestSkeleton % (config["PkgName"], config["PkgVendor"], config["PkgCopyright"], config["PkgDescription"], "LICENSE.TXT", guid, packageItems)
file = open(os.path.join(folder, "package.manifest"), "w")
if file:
file.write(packageManifest)
file.close();
print packageManifest
Last updated: 2018-08-29
cforge: ./branches/13-jobs/cforge/cforge/Package/CFORGE/Scripts/build.py
Bash
bash
(Bash)
import sys, os
import re
import zipfile
import cds_script
import ui
scriptpath = os.path.abspath(os.path.dirname(sys.argv[0]))
# This is a cforge command (script file)
# this will be run as ironpython script.
# the filename of this script is automatically the corresponding cforge command
# with some magic functions you can easily integrate it nicely into cforge tool
# cforge_usage:
# here you can return an array of all possible arguments and options that can
# be passed to this command script
def cforge_usage():
help = [
["<path to local repository>", "---"]
]
return help
def zipdir(path, ziph):
# ziph is zipfile handle
for root, dirs, files in os.walk(path):
for file in files:
filename=os.path.join(root, file)
archname=filename[len(path)+1:]
print("Adding file: %s -> %s" % (filename, archname))
ziph.write(filename, arcname=archname)
def do(folder):
#folder = sys.argv[1]
# if folder can't be found, try to interpret it as a repo
# name, relatively to the workspace folder
if not os.path.isdir(folder):
config = ui.GetSettings()
workspace, file = ntpath.split(config['folder'])
folder = os.path.join(workspace, folder)
print("building folder: %s" % folder)
# Build all packages
xFoundProject = False
for root, dirs, files in os.walk(folder):
for file in files:
# btw, check if some libs or projects are to be built
if file.endswith(".library") or file.endswith(".project"):
xFoundProject = True
if file == "package.manifest":
# Increase Package Version
packageManifest = os.path.join(root, file)
f = open(packageManifest, 'r')
if f:
manifest = f.read()
version = re.findall(r'<Version>([^<]*)</Version>', manifest)
if len(version) == 1:
version = version[0]
version_tuple = version.split('.')
version_tuple[-1] = str(int(version_tuple[-1]) + 1)
new_version = ".".join(version_tuple)
print("Increasing package version number from %s to %s\n" % (version, new_version))
manifest = manifest.replace("<Version>%s</Version>" % version, "<Version>%s</Version>" % new_version)
f.close()
f = open(packageManifest, 'w')
if f:
f.write(manifest)
f.close()
# ZIP package
packageDir = root
packageName = root + ".package"
print("Creating package: '%s' -> '%s'" % (packageDir, packageName))
zipf = zipfile.ZipFile(packageName, 'w', zipfile.ZIP_DEFLATED)
zipdir(packageDir, zipf)
zipf.close()
# Export documentation as markdown
if xFoundProject:
scriptname = os.path.join(scriptpath, "action.markdown.py")
scriptargs = folder
cds_script.RunCodesysWithScript(scriptname, scriptargs, False)
# call main
if __name__ == "<module>":
if len(sys.argv) <= 1:
print("Oh, there are no arguments. Perhaps you forgot something?")
sys.exit()
do(sys.argv[1])
Last updated: 2019-05-02
cforge: ./branches/13-jobs/cforge/cforge/Package/CFORGE/Scripts/checkout-prj.py
Bash
bash
(Bash)
import sys, os
import pysvn
import json
hasWebClient = True
try:
from System.Net import WebClient
except:
import requests
hasWebClient = False
hasUI = True
try:
import ui
except:
hasUI = False
base_url = "https://forge.codesys.com/rest"
base_svn = "https://forge.codesys.com/svn/"
# This is a cforge command (script file)
# this will be run as ironpython script.
# the filename of this script is automatically the corresponding cforge command
# with some magic functions you can easily integrate it nicely into cforge tool
# cforge_usage:
# here you can return an array of all possible arguments and options that can
# be passed to this command script
def cforge_usage():
help = [
["<path to CODESYS project>", "---"]
]
return help
def get_json(url):
r = ""
if hasWebClient:
web_client = WebClient()
r = web_client.DownloadData(url)
else:
r = requests.get(url).content
j = json.loads(bytes(r).decode('utf-8'))
return j
if len(sys.argv) <= 1:
print("Oh, there are no arguments. Perhaps you forgot something?")
sys.exit()
args = sys.argv[1].split(" ")
folder = ""
if len(args) == 1:
folder = args[0].strip("/").split("/")[-1]
# username, password and path are specified at the command line
config = dict()
if len(sys.argv)>= 3:
config['user'] = sys.argv[2]
config['pass'] = sys.argv[3]
config['folder'] = sys.argv[4]
elif hasUI:
config = ui.Dialog("Checkout Project", Folder=True, Credentials=True, DefaultFolder=folder)
# iterate over all tools of the project, and checkout all SVN repositories,
# excluding the CODESYS folders
if config != None:
tools = get_json(base_url + '/' + sys.argv[1])
for tool in tools['tools']:
if tool['name'] == 'svn':
repo = tool['url'][1:-1].replace('/', ',')
url = base_svn + repo
print(url)
# checkout
pysvn.svn_checkout_all(config['user'], config['pass'], url, os.path.join(config['folder'], repo))
for root, dirs, files in os.walk(config['folder']):
for file in files:
if file == "meta.profile":
pysvn.svn_remove_local(root)
print('\n')
# store commit count
details = get_json(base_url + tool['url'])
f = open(os.path.join(config['folder'], repo + '.commit_count'), "w")
if f:
f.write(str(details['commit_count']))
f.close()
Last updated: 2018-09-13
cforge: ./branches/13-jobs/cforge/cforge/Package/CFORGE/Scripts/job.py
Bash
bash
(Bash)
import sys, os
import pysvn
import json
import build
import commit
hasWebClient = True
try:
from System.Net import WebClient
except:
import requests
hasWebClient = False
hasUI = True
try:
import ui
except:
hasUI = False
base_url = "https://forge.codesys.com/rest"
base_svn = "https://forge.codesys.com/svn/"
# This is a cforge command (script file)
# this will be run as ironpython script.
# the filename of this script is automatically the corresponding cforge command
# with some magic functions you can easily integrate it nicely into cforge tool
# cforge_usage:
# here you can return an array of all possible arguments and options that can
# be passed to this command script
def cforge_usage():
help = [
["json job string", "---"]
]
return help
def get_json(url):
r = ""
if hasWebClient:
web_client = WebClient()
r = web_client.DownloadData(url)
else:
r = requests.get(url).content
j = json.loads(bytes(r).decode('utf-8'))
return j
if len(sys.argv) <= 1:
print("Oh, there are no arguments. Perhaps you forgot something?")
sys.exit()
# Job is passed as first argument
print("==========")
print(sys.argv[1])
json_file = open(sys.argv[1], "r").read()
job = json.loads(json_file)
print(job)
print("==========")
job["folder"] = '\\temp\\CODESYS'
# iterate over all tools of the project, and checkout all SVN repositories,
# excluding the CODESYS folders
if job != None:
tools = get_json(base_url + '/' + job["project"])
for tool in tools['tools']:
if tool['name'] == 'svn':
repo = tool['url'][1:-1].replace('/', ',')
url = base_svn + repo
print(url)
# checkout
pysvn.svn_checkout_all(job['user'], job['pass'], url, os.path.join(job['folder'], repo))
for root, dirs, files in os.walk(job['folder']):
for file in files:
if file == "meta.profile":
pysvn.svn_remove_local(root)
print('\n')
# store commit count
details = get_json(base_url + tool['url'])
f = open(os.path.join(job['folder'], repo + '.commit_count'), "w")
if f:
f.write(str(details['commit_count']))
f.close()
# Exeucte all actions, passed to the job
for action in job['actions']:
if action['cmd'] == 'build':
build.do(os.path.join(job['folder'], action['repo']))
if action['cmd'] == 'commit':
commit.do(os.path.join(job['folder'], action['repo']), job["user"], job["pass"], action["msg"])
Last updated: 2019-04-20
cforge: ./branches/13-jobs/cforge/cforge/Package/CFORGE/Scripts/import.py
Bash
bash
(Bash)
# Example Batch:
#set WD=%~d0%~p0
#set USER=<username>
#set PASS=<password>
#set PROJECT=C:\Users\<bla>\Projekte\CODESYS\IoDrvSysfsGPIO.library
#set URL=https://forge.codesys.com/svn/,,,,/IoDrvSysfsGPIO/
#set MESSAGE='initial commit'
#"C:\Program Files (x86)\3S CODESYS\CODESYS\Common\CODESYS.exe" --Profile="CODESYS V3.5 SP12" --runscript="C:\Program Files (x86)\3S CODESYS\CODESYS\CFORGE\Scripts\import.py" --scriptargs="%USER% %PASS% %PROJECT% %URL% %WD% %MESSAGE%" --noUI
# if not all parameters are passed, there will be message prompts
# this makes it possible to use it from inside codesys
import sys, os
class ER(ExportReporter):
def error(self, object, message):
system.write_message(Severity.Error, "Error exporting %s: %s" % (object, message))
def warning(self, object, message):
system.write_message(Severity.Warning, "Warning exporting %s: %s" % (object, message))
def nonexportable(self, object):
system.write_message(Severity.Information, "Object not exportable: %s" % object)
@property
def aborting(self):
return False;
if len(sys.argv) > 1:
username=sys.argv[1]
else:
username = system.ui.query_string("Enter the svn username")
if len(sys.argv) > 2:
password=sys.argv[2]
else:
password = system.ui.query_password("Enter the svn password")
if len(sys.argv) > 3:
project=sys.argv[3]
else:
res = system.ui.open_file_dialog("Choose file:", filter="Project files (*.project)|*.project|Library files (*.library)|*.library", filter_index = 0, multiselect=False)
project = res
if len(sys.argv) > 4:
url=sys.argv[4]
else:
url = system.ui.query_string("Enter the svn url:")
if len(sys.argv) > 5:
message=sys.argv[5]
else:
message = system.ui.query_string("Enter the commit message:")
def set_username(req):
print_all(req)
req.username = username
req.password = password
req.save = True # Optional
svn.auth_username_password += set_username
print("open project: " + project)
p = projects.open(project)
reporter = ER()
print("export plcopen xml")
p.export_xml(reporter, p.get_children(False), p.path + ".plcopen.xml", True, True, True)
print("is versioned: " + str(p.svn.is_versioned))
if not p.svn.is_versioned:
print("importing project to svn...")
p.svn.import_project(url,message)
print("import done!")
else:
print("committing project to svn...")
p.svn.commit()
print("commit done!")
p.close()
Last updated: 2018-04-13
cforge: ./branches/13-jobs/cforge/cforge/Package/CFORGE/Scripts/cds_script.py
Bash
bash
(Bash)
# imports
import sys
import os
#
# this is a general helper module providing some basic functions to
# e.g. run CODESYS or another process with certain arguments
#
#
from System.Diagnostics import Process
from System.Net import WebClient
def RunProcess(workdir, process, args):
exitcode = -1
print("run process: " + process + " " + args)
if not os.path.exists(workdir):
print("Path does not exist: " + workdir)
if not os.path.exists(os.path.join(workdir, process)):
print("File does not exist: " + process)
else:
p = Process()
p.StartInfo.WorkingDirectory=workdir
p.StartInfo.FileName = process
p.StartInfo.Arguments = args
p.Start()
p.WaitForExit()
exitcode = p.ExitCode
print("done: " + str(exitcode))
return exitcode
def RunCodesysWithScript(scriptfilename, scriptargs=None, ui=False):
print(scriptfilename)
# common paths
workingdir = os.path.dirname(sys.argv[0])
cdsdir = os.path.abspath(os.path.join(workingdir, os.path.pardir, os.path.pardir))
#print(cdsdir)
# profile stuff
profiledir=os.path.join(cdsdir,"Profiles")
#print(profiledir)
lastprofile=""
for file in os.listdir(profiledir):
if file.endswith(".profile"):
lastprofile = file.replace(".profile","")
#print(lastprofile)
# exe
codesys_exe = os.path.join(cdsdir, "Common", "CODESYS.exe")
packageman_exe = os.path.join(cdsdir, "Common", "PackageManager.exe")
workdir = os.path.join(cdsdir, "Common")
exitcode = -1
if not os.path.exists(os.path.join(workingdir,scriptfilename)):
print("File does not exist: " + scriptfilename)
else:
p = Process()
p.StartInfo.WorkingDirectory=workdir
p.StartInfo.FileName = codesys_exe
processargs = "--profile='" + lastprofile + "' --runscript='" + os.path.join(workingdir,scriptfilename) + "'"
if not ui:
processargs += " --noUI"
if scriptargs != None:
scriptargs = scriptargs.replace("'", "`````")
processargs += " --scriptargs:'" + scriptargs + "'"
print("running codesys with script " + scriptfilename)
p.StartInfo.Arguments = processargs
p.Start()
p.WaitForExit()
exitcode = p.ExitCode
print("done: " + str(exitcode))
return exitcode
def RunPackageManager(args=None):
# common paths
workingdir = os.path.dirname(sys.argv[0])
cdsdir = os.path.abspath(os.path.join(workingdir, os.path.pardir, os.path.pardir))
#print(cdsdir)
# profile stuff
profiledir=os.path.join(cdsdir,"Profiles")
#print(profiledir)
lastprofile=""
for file in os.listdir(profiledir):
if file.endswith(".profile"):
lastprofile = file.replace(".profile","")
#print(lastprofile)
# exe
packageman_exe = os.path.join(cdsdir, "Common", "PackageManager.exe")
workdir = os.path.join(cdsdir, "Common")
exitcode = -1
p = Process()
p.StartInfo.WorkingDirectory=workdir
p.StartInfo.FileName = packageman_exe
processargs = "--profile='" + lastprofile + "' " + args
print("running packman with args " + args)
p.StartInfo.Arguments = processargs
p.Start()
p.WaitForExit()
exitcode = p.ExitCode
print("done: " + str(exitcode))
return exitcode
Last updated: 2018-08-17
cforge: ./branches/13-jobs/cforge/cforge/Package/CFORGE/Scripts/commit.py
Bash
bash
(Bash)
import sys, os
import cds_script
import ui
import pysvn
import ntpath
# This is a cforge command (script file)
# this will be run as ironpython script.
# the filename of this script is automatically the corresponding cforge command
# with some magic functions you can easily integrate it nicely into cforge tool
# cforge_usage:
# here you can return an array of all possible arguments and options that can
# be passed to this command script
def cforge_usage():
help = [
["<path to CODESYS project>", "---"]
]
return help
def do(folder, username, password, message):
scriptpath = os.path.abspath(os.path.dirname(sys.argv[0]))
scriptname = os.path.join(scriptpath, "action.svn.commit.py")
scriptargs = "%s %s %s %s" % (username, password, folder, message)
cds_script.RunCodesysWithScript(scriptname, scriptargs, False)
# call main
if __name__ == "<module>":
if len(sys.argv) <= 1:
print("Oh, there are no arguments. Perhaps you forgot something?")
sys.exit()
folder = sys.argv[1]
# if folder can't be found, try to interpret it as a repo
# name, relatively to the workspace folder
if not os.path.isdir(folder):
config = ui.GetSettings()
workspace, file = ntpath.split(config['folder'])
folder = os.path.join(workspace, folder)
print("commiting folder: %s" % folder)
stat = pysvn.svn_get_stat(folder)
config = ui.Dialog("Commit", Credentials=True, Info=True, InfoText=stat, Message=True)
if config != None:
do(folder, config["user"], config["pass"], config["msg"])
Last updated: 2019-05-02
cforge: ./branches/13-jobs/cforge/cforge/Package/CFORGE/Scripts/install.py
Bash
bash
(Bash)
# imports
import sys
import os
from System.Diagnostics import Process
from System.Net import WebClient
# This is a cforge command (script file)
# pass a "url" or local path to a CODESYS package and this script will install it
# via the CODESYS package manager to your CODESYS installation
#
# cforge_usage:
# here you can return an array of all possible arguments and options that can
# be passed to this command script
def cforge_usage():
help = [
["<url_to_package>", "download and install a codesys package"],
["<local path of package>", "install a local codesys package"]
]
return help
if len(sys.argv) == 1:
print("Oh, there are no arguments. Perhaps you forgot something?")
sys.exit()
# download
workingdir = os.path.dirname(sys.argv[0])
downloaddir = os.path.join(os.environ["USERPROFILE"], "downloads")
if not os.path.exists(downloaddir):
os.makedirs(downloaddir)
url = str(sys.argv[1])
print(url)
localname = os.path.join(downloaddir, url.split("/")[-1].split("?")[0])
print(localname)
if not localname.endswith(".package"):
print("no proper local filename found: " + localname)
sys.exit()
print("downloading file...")
web_client = WebClient()
web_client.DownloadFile(url, localname)
print("downloading done!")
# and install local package now:
sys.path.append(workingdir)
import cds_script
cds_script.RunPackageManager("--install='" + localname + "'")
Last updated: 2018-08-22
cforge: ./branches/13-jobs/cforge/cforge/Package/CFORGE/Scripts/checkout.py
Bash
bash
(Bash)
import sys, os
import cds_script
import ui
# This is a cforge command (script file)
# this will be run as ironpython script.
# the filename of this script is automatically the corresponding cforge command
# with some magic functions you can easily integrate it nicely into cforge tool
# cforge_usage:
# here you can return an array of all possible arguments and options that can
# be passed to this command script
def cforge_usage():
help = [
["<path to CODESYS project>", "---"]
]
return help
if len(sys.argv) <= 1:
print("Oh, there are no arguments. Perhaps you forgot something?")
sys.exit()
args = sys.argv[1].split(" ")
folder = ""
repo = ""
if len(args) == 1:
folder = args[0].strip("/").split("/")[-1]
if not os.path.isdir(args[0]):
repo = args[0]
config = ui.Dialog("Checkout", Folder=True, Credentials=True, Repo=True, DefaultFolder=folder, DefaultRepo=repo)
if config != None:
scriptpath = os.path.abspath(os.path.dirname(sys.argv[0]))
scriptname = os.path.join(scriptpath, "action.svn.checkout.py")
scriptargs = "%s %s %s %s" % (config["repo"], config["user"], config["pass"], config["folder"])
cds_script.RunCodesysWithScript(scriptname, scriptargs, False)
Last updated: 2018-08-22
cforge: ./branches/13-jobs/cforge/cforge/Package/CFORGE/Scripts/ui.py
Bash
bash
(Bash)
#!/usr/bin/ipy
import clr
clr.AddReference("System.Windows.Forms")
clr.AddReference("System.Drawing")
from System.Drawing import Point, Font, FontStyle, Color, Icon
from System.Windows.Forms import Application, Form, TextBox
from System.Windows.Forms import Label, ToolBar, ToolBarButton, OpenFileDialog, Button, ScrollBars
from System.Windows.Forms import DialogResult, ScrollBars, DockStyle
import sys
import os
import json
import ntpath
GlobalResult = False
class IFormSettings(Form):
def __init__(self, Title, Config, Folder=False, Credentials=False, Info=False, InfoText="", Message=False, PkgName=False, PkgVendor=False, PkgCopyright=False, PkgDescription=False, Repo=False):
self.Config = Config
y = 0
self.TitleLable = Label()
self.TitleLable.Text = Title
self.TitleLable.Parent = self
self.TitleLable.Height = 36
self.TitleLable.Font = Font("Arial", 24,FontStyle.Bold)
self.TitleLable.BackColor = Color.FromArgb(80,80,80)
self.TitleLable.ForeColor = Color.FromArgb(255,255,255)
self.TitleLable.Dock = DockStyle.Top
y += 42
if Repo:
# Repository URL
self.RepoLabel = Label()
self.RepoLabel.Text = "Repo. URL:"
self.RepoLabel.Location = Point(0, y)
self.RepoLabel.Width = 60
self.RepoLabel.Parent = self
self.RepoBox = TextBox()
if "Repo" in Config:
self.RepoBox.Text = Config["Repo"]
self.RepoBox.Enabled = True
self.RepoBox.Location = Point(60, y)
self.RepoBox.Parent = self
self.RepoBox.Width = 300
y += 24
if Folder:
# Folder
self.FolderLabel = Label()
self.FolderLabel.Text = "Folder:"
self.FolderLabel.Location = Point(0, y)
self.FolderLabel.Width = 60
self.FolderLabel.Parent = self
self.FolderBox = TextBox()
if "folder" in Config:
self.FolderBox.Text = Config["folder"]
self.FolderBox.Enabled = True
self.FolderBox.Location = Point(60, y)
self.FolderBox.Parent = self
self.FolderBox.Width = 300
self.FolderButton = Button()
self.FolderButton.Click += self.OnClickBrowse
self.FolderButton.Text = "..."
self.FolderButton.Parent = self
self.FolderButton.Location = Point(364, y)
y += 24
if Credentials:
# Credentials
self.UserLabel = Label()
self.UserLabel.Text = "Username:"
self.UserLabel.Location = Point(0, y)
self.UserLabel.Width = 60
self.UserLabel.Parent = self
self.UserBox = TextBox()
if "user" in Config:
self.UserBox.Text = Config["user"]
self.UserBox.Enabled = True
self.UserBox.Location = Point(60, y)
self.UserBox.Parent = self
self.UserBox.Width = 300
y += 24
self.PassLabel = Label()
self.PassLabel.Text = "Password:"
self.PassLabel.Location = Point(0, y)
self.PassLabel.Width = 60
self.PassLabel.Parent = self
self.PassBox = TextBox()
if "pass" in Config:
self.PassBox.Text = Config["pass"]
self.PassBox.Enabled = True
self.PassBox.PasswordChar = "*"
self.PassBox.Location = Point(60, y)
self.PassBox.Parent = self
self.PassBox.Width = 300
y += 24
if Info:
# Info Box
self.InfoLabel = Label()
self.InfoLabel.Text = "Info:"
self.InfoLabel.Location = Point(0, y)
self.InfoLabel.Width = 60
self.InfoLabel.Parent = self
y += 24
self.InfoBox = TextBox()
self.InfoBox.Text = InfoText
self.InfoBox.Enabled = True
self.InfoBox.ReadOnly = True
self.InfoBox.Location = Point(0, y)
self.InfoBox.Parent = self
self.InfoBox.WordWrap = False
self.InfoBox.Multiline = True
self.InfoBox.ScrollBars = ScrollBars.Horizontal | ScrollBars.Vertical
self.InfoBox.Width = 360
self.InfoBox.Height = 260
y += 280
if Message:
# Message
self.MessageLabel = Label()
self.MessageLabel.Text = "Message:"
self.MessageLabel.Location = Point(0, y)
self.MessageLabel.Width = 60
self.MessageLabel.Parent = self
y += 24
self.MessageBox = TextBox()
self.MessageBox.Text = "Enter Message..."
if "msg" in Config and Config["msg"] != "":
self.MessageBox.Text = Config["msg"]
self.MessageBox.Enabled = True
self.MessageBox.Location = Point(0, y)
self.MessageBox.Parent = self
self.MessageBox.WordWrap = False
self.MessageBox.Multiline = True
self.MessageBox.AcceptsReturn = True
self.MessageBox.ScrollBars = ScrollBars.Horizontal | ScrollBars.Vertical
self.MessageBox.Width = 360
self.MessageBox.Height = 160
y += 180
if PkgName:
# Name
self.PkgNameLabel = Label()
self.PkgNameLabel.Text = "Name:"
self.PkgNameLabel.Location = Point(0, y)
self.PkgNameLabel.Width = 60
self.PkgNameLabel.Parent = self
self.PkgNameBox = TextBox()
if "PkgName" in Config:
self.PkgNameBox.Text = Config["PkgName"]
self.PkgNameBox.Enabled = True
self.PkgNameBox.Location = Point(60, y)
self.PkgNameBox.Parent = self
self.PkgNameBox.Width = 300
y += 24
if PkgVendor:
# Name
self.PkgVendorLabel = Label()
self.PkgVendorLabel.Text = "Vendor:"
self.PkgVendorLabel.Location = Point(0, y)
self.PkgVendorLabel.Width = 60
self.PkgVendorLabel.Parent = self
self.PkgVendorBox = TextBox()
self.PkgVendorBox.Text = "Open Source Software"
if "PkgVendor" in Config and Config["PkgVendor"] != "":
self.PkgVendorBox.Text = Config["PkgVendor"]
self.PkgVendorBox.Enabled = True
self.PkgVendorBox.Location = Point(60, y)
self.PkgVendorBox.Parent = self
self.PkgVendorBox.Width = 300
y += 24
if PkgCopyright:
# Name
self.PkgCopyrightLabel = Label()
self.PkgCopyrightLabel.Text = "Copyright:"
self.PkgCopyrightLabel.Location = Point(0, y)
self.PkgCopyrightLabel.Width = 60
self.PkgCopyrightLabel.Parent = self
self.PkgCopyrightBox = TextBox()
self.PkgCopyrightBox.Text = "all rights reserved"
if "PkgCopyright" in Config and Config["PkgCopyright"] != "":
self.PkgCopyrightBox.Text = Config["PkgCopyright"]
self.PkgCopyrightBox.Enabled = True
self.PkgCopyrightBox.Location = Point(60, y)
self.PkgCopyrightBox.Parent = self
self.PkgCopyrightBox.Width = 300
y += 24
if PkgDescription:
# Name
self.PkgDescriptionLabel = Label()
self.PkgDescriptionLabel.Text = "Descr.:"
self.PkgDescriptionLabel.Location = Point(0, y)
self.PkgDescriptionLabel.Width = 60
self.PkgDescriptionLabel.Parent = self
self.PkgDescriptionBox = TextBox()
if "PkgDescription" in Config:
self.PkgDescriptionBox.Text = Config["PkgDescription"]
self.PkgDescriptionBox.Enabled = True
self.PkgDescriptionBox.Location = Point(60, y)
self.PkgDescriptionBox.Parent = self
self.PkgDescriptionBox.Width = 300
y += 24
# OK / Cancel Button
self.AcceptButton = Button()
self.AcceptButton.Click += self.OnClickOK
self.AcceptButton.Text = "OK"
self.AcceptButton.Parent = self
self.AcceptButton.Location = Point(364, y)
self.AcceptButton.Select()
self.CancelButton = Button()
self.CancelButton.Click += self.OnClickCancel
self.CancelButton.Text = "Cancel"
self.CancelButton.Parent = self
self.CancelButton.Location = Point(0, y)
y += 24
# Self (Dialog)
self.Width = 458
self.Height = y + 50
self.Text = "cforge - " + Title
workingdir = os.path.dirname(sys.argv[0])
self.Icon = Icon(os.path.join(workingdir, "icon.ico"))
self.CenterToScreen()
def OnClickBrowse(self, sender, event):
dialog = OpenFileDialog()
dialog.Filter = "all files (*.*) |*.*"
dialog.ShowHelp = True
dialog.ValidateNames = False;
dialog.CheckFileExists = False;
dialog.CheckPathExists = False;
dialog.FileName = "Folder Selection"
if dialog.ShowDialog(self) == DialogResult.OK:
folder, file = ntpath.split(dialog.FileName)
print (self.FolderBox)
self.FolderBox.Text = folder
def OnClickOK(self, sender, event):
global GlobalResult
# Return content of form in config structure
if hasattr(self, 'RepoBox'):
self.Config["repo"] = self.RepoBox.Text
if hasattr(self, 'FolderBox'):
self.Config["folder"] = self.FolderBox.Text
if hasattr(self, 'UserBox'):
self.Config["user"] = self.UserBox.Text
if hasattr(self, 'PassBox'):
self.Config["pass"] = self.PassBox.Text
if hasattr(self, 'MessageBox'):
self.Config["msg"] = self.MessageBox.Text
if hasattr(self, 'PkgNameBox'):
self.Config["PkgName"] = self.PkgNameBox.Text
if hasattr(self, 'PkgVendorBox'):
self.Config["PkgVendor"] = self.PkgVendorBox.Text
if hasattr(self, 'PkgCopyrightBox'):
self.Config["PkgCopyright"] = self.PkgCopyrightBox.Text
if hasattr(self, 'PkgDescriptionBox'):
self.Config["PkgDescription"] = self.PkgDescriptionBox.Text
GlobalResult = True
self.Dispose()
def OnClickCancel(self, sender, event):
global GlobalResult
# Discard form data, don't return it
GlobalResult = False
self.Dispose()
def GetSettings():
dirname = os.path.expanduser("~\\cforge")
filename = dirname + "\\cache.json"
config = { 'folder' : dirname, 'user' : os.environ["USERNAME"], 'pass' : '', 'msg' : ''}
if not os.path.isfile(filename):
if not os.path.isdir(dirname):
os.mkdir(dirname)
with open(filename, "w") as f:
config = json.dump(config, f)
with open(filename) as f:
config = json.load(f)
return config
def SaveSettings(config):
dirname = os.path.expanduser("~\\cforge")
filename = dirname + "\\cache.json"
with open(filename, "w") as f:
config = json.dump(config, f)
def Dialog(Title, Folder=False, Credentials=False, DefaultFolder="", Info=False, InfoText="", Message=False, PkgName=False, PkgVendor=False, PkgCopyright=False, PkgDescription=False, Repo=False, DefaultRepo=""):
config = GetSettings()
if DefaultFolder != "":
folder, file = ntpath.split(config['folder'])
config['folder'] = os.path.join(folder, DefaultFolder)
if DefaultRepo != "":
config['Repo'] = DefaultRepo
Application.Run(IFormSettings(Title, Folder=Folder, Credentials=Credentials, Info=Info, InfoText=InfoText, Message=Message, Config=config, PkgName=PkgName, PkgVendor=PkgVendor, PkgCopyright=PkgCopyright, PkgDescription=PkgDescription, Repo=Repo))
if GlobalResult:
SaveSettings(config)
return config
else:
return None
#Dialog("Checkout", Folder=True, Credentials=True, DefaultFolder="test,y,z")
#Application.Run(IFormSettings("Checkout", Folder=True, Credentials=True))
#Application.Run(IFormSettings("Checkout", Credentials=True))
#Application.Run(IFormSettings("Checkout", Folder=True))
Last updated: 2018-08-29
cforge: ./branches/13-jobs/cforge/cforge/Package/CFORGE/Scripts/pysvn.py
Bash
bash
(Bash)
#!/usr/bin/python
#
# This module is a wrapper for a locally installed SVN command line client.
# It can be used to find URLs of CODESYS projects within a repository, or to
# checkout all files outside of CODESYS projects.
#
# - svn_list:
# a wrapper for the "svn list" command, supporting recursive lists
#
# - svn_get_directories_with_codesys_projects / svn_get_directories_without_codesys_projects:
# return directories with or without CODESYS projects. Can be used to find
# CODESYS library URLs in repositories.
#
# - svn_checkout_non_codesys:
# Checkout top-level directory w/o content.
# Then update all directories, which are not containing any CODESYS projects.
#
import subprocess
def svn_list(username, password, url, recursive=False):
args = ""
if recursive:
args += " -R"
cmd="svn list %s --username=%s --password=%s %s" % (args, username, password, url)
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
(output, err) = p.communicate()
entries = list()
if "\n" in output.decode(encoding='utf-8', errors='ignore'):
entries = output.decode(encoding='utf-8', errors='ignore').strip().replace("\r","").split("\n")
return entries
def svn_get_directories_with_codesys_projects(username, password, url):
allfiles = svn_list(username, password, url, True)
codesys_projects = filter(lambda file: 'meta.profile' in file, allfiles)
alldirs=list()
for cp in codesys_projects:
dirname = cp.replace("/meta.profile", "")
alldirs.append(dirname)
return alldirs
def svn_get_directories_without_codesys_projects(username, password, url):
allfiles = svn_list(username, password, url, True)
codesys_projects = filter(lambda file: 'meta.profile' in file, allfiles)
# filter out all subdirectories of the directory containing 'meta.profile',
# as well as all files (keep only directories)
alldirs=allfiles
for cp in codesys_projects:
dirname = cp.replace("/meta.profile", "")
alldirs = filter(lambda file: not file.startswith(dirname) and file.endswith('/'), alldirs)
return alldirs
def svn_checkout_non_codesys(username, password, url, destination):
dirs = svn_get_directories_without_codesys_projects(username, password, url)
cmd="svn checkout --depth=empty --username=%s --password=%s %s %s" % (username, password, url, destination)
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
(output, err) = p.communicate()
if not err:
for d in dirs:
cmd="svn update --depth=files --username=%s --password=%s %s/%s" % (username, password, destination, d)
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
(output, err) = p.communicate()
def svn_checkout_all(username, password, url, destination):
cmd="svn checkout --username=%s --password=%s %s %s" % (username, password, url, destination)
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
(output, err) = p.communicate()
def svn_remove_local(destination):
cmd="svn update --set-depth exclude %s" % (destination)
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
(output, err) = p.communicate()
def svn_get_stat(folder):
cmd="svn stat %s" % (folder)
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
(stat, err) = p.communicate()
return stat
def svn_get_url(folder):
cmd="svn info --show-item url %s" % (folder)
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
(url, err) = p.communicate()
return url
def svn_update_non_codesys(username, password, folder):
url = svn_get_url(folder)
dirs = svn_get_directories_without_codesys_projects(username, password, url)
for d in dirs:
cmd="svn update --depth=files --username=%s --password=%s %s/%s" % (username, password, folder, d)
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
(output, err) = p.communicate()
def svn_commit_non_codesys(username, password, folder, message):
cmd="svn commit -m \"%s\" --username=%s --password=%s" % (message, username, password)
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True, cwd=folder)
(output, err) = p.communicate()
Last updated: 2018-09-10
cforge: ./branches/13-jobs/cforge/cforge/Package/CFORGE/Scripts/plcopenxml.xslt
Bash
bash
(Bash)
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:po="http://www.plcopen.org/xml/tc6_0200">
<!--
| Parse POU start tags
-->
<xsl:template match="po:pou[@pouType='functionBlock']">
<xsl:text>---
</xsl:text>
<!-- <xsl:value-of select="po:interface/po:documentation"/>-->
<xsl:call-template name="trim">
<xsl:with-param name="input" select="po:interface/po:documentation"/>
</xsl:call-template>
<xsl:text>
~~~ST
</xsl:text>
<xsl:text>FUNCTION_BLOCK </xsl:text><xsl:value-of select="@name" />
<xsl:apply-templates select="po:interface"/>
<xsl:text>
~~~
</xsl:text>
<xsl:apply-templates select="po:body"/>
<xsl:apply-templates select="po:addData/po:data/po:Method"/>
</xsl:template>
<xsl:template match="po:pou[@pouType='program']">
<xsl:text>---
~~~ST
</xsl:text>
<xsl:text>PROGRAM </xsl:text><xsl:value-of select="@name" />
<xsl:apply-templates select="po:interface"/>
<xsl:text>
~~~
</xsl:text>
<xsl:apply-templates select="po:body"/>
</xsl:template>
<xsl:template match="po:Method">
<xsl:text>---
~~~ST
</xsl:text>
<xsl:text>METHOD </xsl:text><xsl:value-of select="@name" />
<xsl:text>: </xsl:text>
<xsl:apply-templates select="*/po:returnType"/>
<xsl:apply-templates select="po:interface"/>
<xsl:text>
~~~
</xsl:text>
<xsl:apply-templates select="po:body"/>
</xsl:template>
<!--
| Parse POU body
-->
<xsl:template match="po:body">
<xsl:apply-templates select="*|@*"/>
</xsl:template>
<!--
| Parse Interface (also finish the start tag, to be able to set "EXTENDS" or "IMPLEMENTS".
-->
<xsl:template match="po:interface">
<xsl:if test="po:addData/po:data/po:Inheritance/po:Extends">
<xsl:text> EXTENDS </xsl:text>
<xsl:value-of select="po:addData/po:data/po:Inheritance/po:Extends"/>
</xsl:if>
<xsl:text>
</xsl:text>
<xsl:apply-templates select="po:localVars|po:tempVars|po:inputVars|po:outputVars|po:inOutVars|po:externalVars|po:globalVars"/>
</xsl:template>
<!--
| Variables (Part of the interface)
-->
<xsl:template match="po:localVars">
<xsl:text>VAR
</xsl:text>
<xsl:apply-templates select="po:variable"/>
<xsl:text>END_VAR
</xsl:text>
</xsl:template>
<xsl:template match="po:tempVars">
<xsl:text>VAR_TEMP
</xsl:text>
<xsl:apply-templates select="po:variable"/>
<xsl:text>END_VAR
</xsl:text>
</xsl:template>
<xsl:template match="po:inputVars">
<xsl:text>VAR_INPUT
</xsl:text>
<xsl:apply-templates select="po:variable"/>
<xsl:text>END_VAR
</xsl:text>
</xsl:template>
<xsl:template match="po:outputVars">
<xsl:text>VAR_OUTPUT
</xsl:text>
<xsl:apply-templates select="po:variable"/>
<xsl:text>END_VAR
</xsl:text>
</xsl:template>
<xsl:template match="po:inOutVars">
<xsl:text>VAR_INOUT
</xsl:text>
<xsl:apply-templates select="po:variable"/>
<xsl:text>END_VAR
</xsl:text>
</xsl:template>
<xsl:template match="po:externalVars">
<xsl:text>VAR_EXTERNAL
</xsl:text>
<xsl:apply-templates select="po:variable"/>
<xsl:text>END_VAR
</xsl:text>
</xsl:template>
<xsl:template match="po:globalVars">
<xsl:text>VAR_GLOBAL
</xsl:text>
<xsl:apply-templates select="po:variable"/>
<xsl:text>END_VAR
</xsl:text>
</xsl:template>
<xsl:template match="po:variable">
<xsl:text> </xsl:text>
<xsl:if test="@name">
<xsl:value-of select="@name"/>
<xsl:text>: </xsl:text>
<xsl:apply-templates select="po:type"/>
<xsl:text>;
</xsl:text>
</xsl:if>
</xsl:template>
<xsl:template match="po:type|po:baseType|po:returnType">
<xsl:if test="po:derived">
<xsl:value-of select="po:derived/@name"/>
</xsl:if>
<xsl:if test="po:array">
<xsl:text>ARRAY [</xsl:text>
<xsl:value-of select="po:array/dimension/@lower"/>
<xsl:text>..</xsl:text>
<xsl:value-of select="po:array/dimension/@upper"/>
<xsl:text>] OF </xsl:text>
<xsl:apply-templates select="po:baseType"/>
</xsl:if>
<xsl:if test="not(po:derived) and not(po:array) and not(po:struct)">
<xsl:value-of select="name(*[1])"/>
</xsl:if>
</xsl:template>
<!--
| Implement the presentation of the different languages
-->
<xsl:template match="po:ST">
<xsl:text>~~~ST
</xsl:text>
<xsl:value-of select="*[1]"/>
<xsl:text>
~~~
</xsl:text>
</xsl:template>
<xsl:template name="trim">
<xsl:param name="input"/>
<xsl:choose>
<xsl:when test="starts-with($input,' ')">
<xsl:call-template name="trim">
<xsl:with-param name="input" select="substring-after($input,' ')"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="substring($input, string-length($input) ) = ' ' ">
<xsl:call-template name="trim">
<xsl:with-param name="input" select="substring($input, 1,
string-length($input)-1)"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$input"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!--
| Fetch and ignore rest
-->
<xsl:template match="*|@*">
<xsl:apply-templates select="*|@*"/>
</xsl:template>
</xsl:stylesheet>
Last updated: 2018-06-04
cforge: ./branches/13-jobs/cforge/cforge/Properties/AssemblyInfo.cs
Bash
bash
(Bash)
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// Allgemeine Informationen über eine Assembly werden über die folgenden
// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
// die einer Assembly zugeordnet sind.
[assembly: AssemblyTitle("cforge")]
[assembly: AssemblyDescription("The cforge tool for CODESYS Forge")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("cforge")]
[assembly: AssemblyCopyright("Copyright © 2018")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly
// für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von
// COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen.
[assembly: ComVisible(false)]
// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
[assembly: Guid("4fea909f-b6ab-49ef-9eea-9aed5c2e7792")]
// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
//
// Hauptversion
// Nebenversion
// Buildnummer
// Revision
//
// Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden,
// übernehmen, indem Sie "*" eingeben:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
Last updated: 2018-03-17
cforge: ./branches/13-jobs/cforge/cforge/Package/CFORGE/Scripts/update.py
Bash
bash
(Bash)
import sys, os
import cds_script
import ui
import ntpath
# This is a cforge command (script file)
# this will be run as ironpython script.
# the filename of this script is automatically the corresponding cforge command
# with some magic functions you can easily integrate it nicely into cforge tool
# cforge_usage:
# here you can return an array of all possible arguments and options that can
# be passed to this command script
def cforge_usage():
help = [
["<path to CODESYS project>", "---"]
]
return help
if len(sys.argv) <= 1:
print("Oh, there are no arguments. Perhaps you forgot something?")
sys.exit()
folder = sys.argv[1]
# if folder can't be found, try to interpret it as a repo
# name, relatively to the workspace folder
if not os.path.isdir(folder):
config = ui.GetSettings()
workspace, file = ntpath.split(config['folder'])
folder = os.path.join(workspace, folder)
print("updating folder: %s" % folder)
config = ui.Dialog("Update", Credentials=True)
if config != None:
scriptpath = os.path.abspath(os.path.dirname(sys.argv[0]))
scriptname = os.path.join(scriptpath, "action.svn.update.py")
scriptargs = "%s %s %s" % (config["user"], config["pass"], folder)
cds_script.RunCodesysWithScript(scriptname, scriptargs, False)
Last updated: 2019-01-25
cforge: ./branches/13-jobs/cforge/cforge/Package/CFORGE/Scripts/list-all.py
Bash
bash
(Bash)
# imports
import sys
import os
from System.Diagnostics import Process
from System.Net import WebClient
# This is a cforge command (script file)
# this will open the CODESYS PackageManager to list all installed packages
# cforge_usage:
# here you can return an array of all possible arguments and options that can
# be passed to this command script
def cforge_usage():
help = [
["", "no parameters required"]
]
return help
if len(sys.argv) > 1:
print("Oh, there are arguments... didnt expect them")
# common paths
workingdir = os.path.dirname(sys.argv[0])
cdsdir = os.path.abspath(os.path.join(workingdir, os.path.pardir, os.path.pardir))
print(cdsdir)
# profile stuff
profiledir=os.path.join(cdsdir,"Profiles")
print(profiledir)
lastprofile=""
for file in os.listdir(profiledir):
if file.endswith(".profile"):
lastprofile = file.replace(".profile","")
print(lastprofile)
# exe
codesys_exe = os.path.join(cdsdir, "Common", "CODESYS.exe")
packageman_exe = os.path.join(cdsdir, "Common", "PackageManager.exe")
workdir = os.path.join(cdsdir, "Common")
#Process.Start(localname)
p = Process()
p.StartInfo.WorkingDirectory=workdir
p.StartInfo.FileName = packageman_exe
p.StartInfo.Arguments = "--profile='" + lastprofile + "'"
p.Start()
p.WaitForExit()
Last updated: 2018-04-12
cforge: ./branches/13-jobs/cforge/cforge/bin/Debug/cforge.exe.config
Bash
bash
(Bash)
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
</configuration>
Last updated: 2018-07-13
cforge: ./branches/13-jobs/cforge/cforge/Package/CFORGE/Setup.bat
Bash
bash
(Bash)
@ECHO OFF
REM
REM Install cforge URL Handler in windows registry
REM
ECHO "Setup cforge"
start "" /wait /b cforge.exe --setup
PAUSE
Last updated: 2018-03-20
cforge: ./branches/13-jobs/cforge/cforge/Package/CFORGE/Setup.reg
Bash
bash
(Bash)
Binary file ./branches/13-jobs/cforge/cforge/Package/CFORGE/Setup.reg matches
Last updated: 2018-08-22
cforge: ./branches/13-jobs/cforge/cforge/Helper.cs
Bash
bash
(Bash)
using IronPython.Hosting;
using Microsoft.CSharp.RuntimeBinder;
using Microsoft.Scripting.Hosting;
using Microsoft.Scripting.Runtime;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Dynamic;
using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Security.Principal;
using System.Text;
using System.Threading.Tasks;
namespace cforge
{
/// <summary>
/// Misc helper classes for all kinds of stuff
/// </summary>
class Helper
{
#region Registry
/// <summary>
/// Function to check if URL Handler for cforge tool is installed
/// </summary>
/// <returns>true, if yes. false, if not</returns>
public static bool CheckRegistryProtocol()
{
RegistryKey cforge = Registry.ClassesRoot.OpenSubKey("cforge");
if (cforge == null)
{
return false;
}
return true;
}
public static void RegisterProtocol(bool bVerbose)
{
try
{
String fullpath = GetCFORGEAssemblyPath();
RegistryKey cforgekey = Registry.ClassesRoot.OpenSubKey("cforge");
cforgekey = Registry.ClassesRoot.CreateSubKey("cforge", true);
cforgekey.SetValue("", "URL:cforge Protocol");
cforgekey.SetValue("URL Protocol", "");
RegistryKey cforgeshell = cforgekey.CreateSubKey("shell");
RegistryKey shellopen = cforgeshell.CreateSubKey("open");
RegistryKey opencommand = shellopen.CreateSubKey("command");
opencommand.SetValue("", "\"" + fullpath + "\" \"%1\"");
Console.WriteLine("[INFO] Installed URL Handler for cforge tool. \r\n\tPath is: " + fullpath);
}
catch (Exception ex)
{
Console.WriteLine("Exception while adding the registry key. Perhaps you are not admin?");
Console.WriteLine(ex.ToString());
}
}
internal static void ShowLicenseInfo()
{
Console.WriteLine("License information ");
Console.WriteLine("");
Console.Write(Resources.license);
Console.WriteLine("");
}
#endregion
#region SystemPath
public static void AddToSystemPath(bool bVerbose)
{
string strPath = System.Environment.GetEnvironmentVariable("Path", EnvironmentVariableTarget.Machine);
string[] split = strPath.Split(new Char[] { ';' });
String path = Path.GetDirectoryName(GetCFORGEAssemblyPath());
String strNewSystemPath = strPath + ";" + path;
if (!split.Contains(path))
{
System.Environment.SetEnvironmentVariable("Path", strNewSystemPath, EnvironmentVariableTarget.Machine);
}
}
#endregion
public static bool EasyAttachEnabled()
{
try
{
String path = GetCFORGEAssemblyPath();
String Debugfile = Path.Combine(Path.GetDirectoryName(path), "debug");
if (File.Exists(Debugfile))
return true;
}
catch
{
}
return false;
}
/// <summary>
/// Function to retrieve the location of the currenty assembly (cforge.exe).
/// This should be located in the CODESYS installation subfolder "CFORGE"
/// </summary>
/// <returns>full path to cforge.exe</returns>
private static String GetCFORGEAssemblyPath()
{
String path = System.Reflection.Assembly.GetExecutingAssembly().Location;
return path;
}
private static bool IsCODESYSPathInstallation()
{
String path = GetCFORGEAssemblyPath();
if (path.Contains("bin") && (path.Contains("Debug") || path.Contains("Release")))
return false;
return true;
}
/// <summary>
/// Function to retrieve the CODESYS AP_ROOT (this is where "Common" etc. folders are)
/// </summary>
/// <returns>full path to AP ROOT</returns>
private static String GetCODESYSRoot()
{
if (IsCODESYSPathInstallation())
{
// twice up from cforge.exe (if installed in CODESYS)
String path = GetCFORGEAssemblyPath();
path = Directory.GetParent(path).FullName;
return Directory.GetParent(path).FullName;
}
// for now return a normal installation path for CODESYS
return @"C:\Program Files (x86)\3S CODESYS\CODESYS\";
}
/// <summary>
/// Function to retrieve the "ScriptLib" Path inside CODESYS. We just take the last one, probably this is the newest one
/// </summary>
/// <returns>full path to ScriptLib version folder</returns>
private static String GetCODESYSScriptingLibPath()
{
String path = Path.Combine(GetCODESYSRoot(), "ScriptLib");
String version = Directory.EnumerateDirectories(path).Last();
path = Path.Combine(path, version);
return path;
}
/// <summary>
/// Function to retrieve the CFORGE Script path (this is where the IronPython scripts should reside)
/// </summary>
/// <returns>full path to CFORGE Scripts</returns>
private static String GetCFORGEScriptPath()
{
if (IsCODESYSPathInstallation())
{
// <AP_ROOT>\CFORGE\Scripts
String path = GetCODESYSRoot();
return Path.Combine(path, "CFORGE", "Scripts");
}
String localscriptpath = System.AppDomain.CurrentDomain.BaseDirectory;
localscriptpath = Directory.GetParent(localscriptpath).FullName;
localscriptpath = Directory.GetParent(localscriptpath).FullName;
localscriptpath = Directory.GetParent(localscriptpath).FullName;
return Path.Combine(localscriptpath,"Package", "CFORGE", "Scripts");
}
/// <summary>
/// Function to enumerate all IronPython scripts to exend cforge.exe inside Scripts folder
/// </summary>
/// <returns>List of IPY scripts</returns>
public static List<String> GetAllScripts()
{
List<string> liScripts = new List<string>();
try
{
String path = GetCFORGEScriptPath();
foreach (String file in Directory.EnumerateFiles(path))
{
if (Path.GetExtension(file).ToLowerInvariant() == ".py")
{
String shortfilename = Path.GetFileNameWithoutExtension(file);
liScripts.Add(shortfilename);
}
}
}
catch(Exception e)
{
Console.WriteLine("[EXCEPTION] GetAllScripts: " + e.Message);
}
return liScripts;
}
public static bool IsUserElevated()
{
using (var curIdent = WindowsIdentity.GetCurrent())
{
var principal = new WindowsPrincipal(curIdent);
return principal.IsInRole(WindowsBuiltInRole.Administrator);
}
}
public static void RunElevated(String args)
{
String strAssemblyPath = GetCFORGEAssemblyPath();
try
{
Process p = new Process();
p.StartInfo.FileName = strAssemblyPath;
p.StartInfo.Arguments = args;
p.StartInfo.Verb = "runas";
p.Start();
p.WaitForExit();
}
catch(Exception ex)
{
Console.WriteLine("[EXCEPTION] RunElevated: " + ex.Message);
}
}
#region Scripting
public static void ExecuteIPyScript(String command, String[] args, bool bVerbose)
{
String scriptfile = Path.Combine(GetCFORGEScriptPath(), command + ".py");
Console.WriteLine();
Console.WriteLine("[INFO] Executing: " + scriptfile);
Console.WriteLine();
if (!File.Exists(scriptfile))
{
Console.WriteLine();
Console.WriteLine("[ERROR] Cannot execute command: no such file or directory: " + scriptfile);
Console.WriteLine();
return;
}
//ScriptEngine engine = Python.CreateEngine();
ScriptEngine engine = IronPython.Hosting.Python.CreateEngine(new Dictionary<string, object> { { "Debug", ScriptingRuntimeHelpers.True } });
Debug.Assert(engine.Runtime.Setup.DebugMode);
String strScriptingPath = GetCODESYSScriptingLibPath();
try
{
dynamic sys = Python.GetSysModule(engine);
sys.argv[0] = scriptfile;
foreach (string arg in args)
{
sys.argv.Add(arg);
}
sys.path.Add(GetCFORGEScriptPath());
sys.path.Add(strScriptingPath);
var source = engine.CreateScriptSourceFromFile(scriptfile);
source.Execute();
//Console.WriteLine("Script finished");
}
catch (IronPython.Runtime.Exceptions.SystemExitException ex)
{
Console.WriteLine();
Console.WriteLine("[INFO] command " + command + ".py exited: ");
ExceptionOperations eo = engine.GetService<ExceptionOperations>();
string error = "[INFO] " + eo.FormatException(ex);
Console.WriteLine(error);
}
catch (Exception ex)
{
Console.WriteLine();
Console.WriteLine("[Exception] command " + command + ".py caused an exception: " );
ExceptionOperations eo = engine.GetService<ExceptionOperations>();
string error = eo.FormatException(ex);
Console.WriteLine(error);
}
}
public static void ShowUsageIPyScript(string command, bool v)
{
String scriptfile = Path.Combine(GetCFORGEScriptPath(), command + ".py");
if (!File.Exists(scriptfile))
{
Console.WriteLine("[ERROR] Cannot execute command: no such file or directory: " + scriptfile);
return;
}
ScriptRuntime runtime;
runtime = Python.CreateRuntime();
Python.GetEngine(runtime);
try
{
dynamic script = runtime.UseFile(scriptfile);
var help = script.cforge_usage();
foreach (var item in help)
{
String cmd = "--" + command + " " + item[0].ToString();
cmd = cmd.PadRight(32) + item[1];
Console.WriteLine(cmd);
}
}
catch
{
// we silently ignore errors in this script, as we only want to show the usage!
//Console.WriteLine(("--" + command).PadRight(32) + "");
}
}
#endregion
}
}
Last updated: 2018-08-09
cforge: ./branches/13-jobs/cforge/cforge/Resources.Designer.cs
Bash
bash
(Bash)
//------------------------------------------------------------------------------
// <auto-generated>
// Dieser Code wurde von einem Tool generiert.
// Laufzeitversion:4.0.30319.42000
//
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
// der Code erneut generiert wird.
// </auto-generated>
//------------------------------------------------------------------------------
namespace cforge {
using System;
/// <summary>
/// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
/// </summary>
// Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
// -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
// Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
// mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("cforge.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
/// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die $WCNOW$ ähnelt.
/// </summary>
internal static string BuildTime {
get {
return ResourceManager.GetString("BuildTime", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die $WCREV$ ähnelt.
/// </summary>
internal static string CurrentSVNRevision {
get {
return ResourceManager.GetString("CurrentSVNRevision", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die $WCMODS?(local modifications detected): $ ähnelt.
/// </summary>
internal static string HasLocalModifications {
get {
return ResourceManager.GetString("HasLocalModifications", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Apache License
///Version 2.0, January 2004
///http://www.apache.org/licenses/
///
///TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
///
///1. Definitions.
///
///"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
///
///"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
///
///"Legal Entity" shall mean the union of the acting entity and all other entities that c [Rest der Zeichenfolge wurde abgeschnitten]"; ähnelt.
/// </summary>
internal static string license {
get {
return ResourceManager.GetString("license", resourceCulture);
}
}
}
}
Last updated: 2018-04-23