22. Januar 2018 01:58
<#
.SYNOPSIS
Object Package Viewer and Configurator
.DESCRIPTION
This script opens a NAV Object Package, displays it in a treeview and offers multiple selection of single objects
to create a new object package
.NOTES
File Name : NAVObjectPackageConfigurator.ps1
Author : Kai Kowalewski
Requires : PowerShell V3
.LINK
.EXAMPLE
#>
function NAVObjectPackageConfigurator
{
# Install .Net Assemblies
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
$ErrorActionPreference = "Stop"
$PSDefaultParameterValues['*:ErrorAction']='Stop'
$initialDirectory = 'C:\temp'
[Windows.Forms.Application]::EnableVisualStyles()
[reflection.assembly]::loadwithpartialname("System.Windows.Forms") | Out-Null
[reflection.assembly]::loadwithpartialname("System.Drawing") | Out-Null
[reflection.assembly]::loadwithpartialname("System.Windows.Forms.SaveFileDialog") | Out-Null
$sourceEncoding = [System.Text.Encoding]::GetEncoding(850)
$dt = New-Object System.Data.Datatable
[void]$dt.Columns.Add("ObjectIndex")
[void]$dt.Columns.Add("ObjectFileName")
$dt.Columns["ObjectIndex"].Datatype = [string]
$dt.Columns["ObjectFileName"].DataType = [string]
[void]$dt.clear
function Read-SingleObjectFile
{
param (
$SingleObjectFilename
)
$richTextBox1.text = [System.IO.File]::ReadAllText("$WorkingFolder\SPLITNAVOBJ\$SingleObjectFileName", $sourceencoding)
$form1.refresh()
}
function Clear-ObjectContent
{
$richTextBox1.text = ""
$form1.refresh()
}
function Concat-SelectedObjectFiles
{
Add-Type -AssemblyName System.Windows.Forms
$SelectedTabCnt = 0
$SelectedPagCnt = 0
$SelectedRepCnt = 0
$SelectedCodCnt = 0
$SelectedXmlCnt = 0
$SelectedForCnt = 0
$SelectedDatCnt = 0
$SelectedQueCnt = 0
$SelectedMenCnt = 0
$outputfile = Get-SaveFile "$Workingfolder"
if ($outputfile -eq "") {throw 'Please select a file name for new object package'}
[int]$SelObjCnt = 0
if (test-path $outputfile) {Remove-Item $outputfile -force}
$dw = New-Object System.Data.DataView($dt)
$dw.Sort="ObjectIndex"
ForEach ($DataRowView in $dw)
{
$CurrIndex = $($DataRowView[0])
$CurrFile = $($DataRowView[1])
[String]$SelectedObjectChar = $DataRowView[1].Substring(0,1)
Switch ($SelectedObjectChar)
{
'T' {$SelectedTabCnt++}
'P' {$SelectedPagCnt++}
'R' {$SelectedRepCnt++}
'C' {$SelectedCodCnt++}
'X' {$SelectedXmlCnt++}
'F' {$SelectedForCnt++}
'D' {$SelectedDatCnt++}
'Q' {$SelectedQueCnt++}
'M' {$SelectedMenCnt++}
}
#Write-Host "$CurrIndex $CurrFile"
$SelObjCnt++
Add-Content -path $outputfile -value(Get-Content $WorkingFolder\SPLITNAVOBJ\$CurrFile)
}
[string]$SelectedObjectList = ""
if ($SelectedTABCnt -gt 0) {$SelectedObjectList += "TAB:$SelectedTABCnt "}
if ($SelectedFORCnt -gt 0) {$SelectedObjectList += "FOR:$SelectedFORCnt "}
if ($SelectedPAGCnt -gt 0) {$SelectedObjectList += "PAG:$SelectedPAGCnt "}
if ($SelectedREPCnt -gt 0) {$SelectedObjectList += "REP:$SelectedREPCnt "}
if ($SelectedDATCnt -gt 0) {$SelectedObjectList += "DAT:$SelectedDATCnt "}
if ($SelectedCODCnt -gt 0) {$SelectedObjectList += "COD:$SelectedCODCnt "}
if ($SelectedQUECnt -gt 0) {$SelectedObjectList += "QUE:$SelectedQUECnt "}
if ($SelectedXMLCnt -gt 0) {$SelectedObjectList += "XML:$SelectedXMLCnt "}
if ($SelectedMENCnt -gt 0) {$SelectedObjectList += "MEN:$SelectedMENCnt "}
[System.Windows.Forms.MessageBox]::Show("File $outputfile with $SelObjCnt objects ($SelectedObjectList) created.")
}
$button1_OnClick=
{
Concat-SelectedObjectFiles
}
$form1 = New-Object System.Windows.Forms.Form
$linkLabel1 = New-Object System.Windows.Forms.LinkLabel
$label4 = New-Object System.Windows.Forms.Label
$label3 = New-Object System.Windows.Forms.Label
$label2 = New-Object System.Windows.Forms.Label
$button1 = New-Object System.Windows.Forms.Button
$richTextBox1 = New-Object System.Windows.Forms.RichTextBox
$linkLabel1_OpenLink=
{
[system.Diagnostics.Process]::start($linkLabel1.text)
}
Function Get-SaveFile($initialDirectory)
{
[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") |
Out-Null
$SaveFileDialog = New-Object System.Windows.Forms.SaveFileDialog
$SaveFileDialog.Title = 'Save new NAV object package'
$SaveFileDialog.initialDirectory = $initialDirectory
#$SaveFileDialog.filename = 'SelectedObjects.txt'
$SaveFileDialog.filter = "NAV Object Files (*.txt)|*.txt"
$SaveFileDialog.ShowDialog() | Out-Null
$SaveFileDialog.filename
}
Function Get-FileName($initialDirectory)
{
[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null
$OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog
$OpenFileDialog.initialDirectory = $initialDirectory
$OpenFileDialog.filter = "NAV Object Files (*.txt)|*.txt"
$OpenFileDialog.ShowDialog() | Out-Null
$OpenFileDialog.filename
}
$inputfile = Get-FileName -initialDirectory "$env:HOMEDRIVE\temp" # This is the default path in OpenFile window.
if ($inputfile -eq "") {throw 'Please select a file'}
[decimal]$filesize = ((Get-Item $inputfile).length/1MB)
$filesize =[math]::round($filesize,2)
$inputfile = resolve-path $inputfile
$WorkingFolder = Split-Path -Parent $inputfile
#$form = New-Object System.Windows.Forms.Form
$treeView1 = New-Object System.Windows.Forms.TreeView
$newNode = new-object System.Windows.Forms.TreeNode
$treeView1.Dock = 'Left'
$treeView1.CheckBoxes = $true
if (Test-path "$WorkingFolder\SPLITNAVOBJ\")
{Remove-Item -path "$WorkingFolder\SPLITNAVOBJ\" -Recurse -Force}
Write-Host "Splitting NAV objects from $inputfile (Size: $filesize MB) to $WorkingFolder\SPLITNAVOBJ\, this may take a while..." -ForegroundColor Yellow
$startime = Get-Date
$Sr = new-object System.IO.StreamReader($inputfile,[system.text.encoding]::GetEncoding(850))
$ObjectLine = @{}
$ObjectType = @{}
$ObjectID = @{}
$ObjectName = @{}
[int]$ObjCnt = 0
[int]$TabCnt = 0
[int]$PagCnt = 0
[int]$RepCnt = 0
[int]$CodCnt = 0
[int]$XmlCnt = 0
[int]$ForCnt = 0
[int]$DatCnt = 0
[int]$QueCnt = 0
[int]$MenCnt = 0
while (-not $Sr.EndOfStream)
{
$Currline = $sr.ReadLine()
if ($Currline.StartsWith('OBJECT'))
{
$TotalLineCnt++
[String]$ObjectChar = $Currline.Substring(7,1)
$ObjectLine = $currline.Split(' ')
$ObjCnt++
Switch ($ObjectChar)
{
'T' {$TabCnt++}
'P' {$PagCnt++}
'R' {$RepCnt++}
'C' {$CodCnt++}
'X' {$XmlCnt++}
'F' {$ForCnt++}
'D' {$DatCnt++}
'Q' {$QueCnt++}
'M' {$MenCnt++}
}
$ObjectFileName = $ObjectLine[1].Substring(0,3).ToUpper() + $ObjectLine[2] + ".TXT"
$ObjectFullName = $CurrLine.Substring(7)
#$ObjectLine.Add($TotalLineCnt,$TotalLineCnt)
$ObjectType.Add($ObjCnt,$ObjectLine[1])
$ObjectID.Add($ObjCnt,$ObjectLine[2])
$ObjectName.Add($ObjCnt,$ObjectFullName)
$newNode = new-object System.Windows.Forms.TreeNode
$newNode.Name = $ObjectFileName
$newNode.Text = $ObjectFullName
$newNode.Tag = $ObjCnt
$treeView1.Nodes.Add($newNode) | Out-Null
$Objectfile = New-Item -path "$WorkingFolder\SPLITNAVOBJ\$ObjectFileName" -type file -force
IF (Test-Path $ObjectFile) {Remove-Item $ObjectFile}
$sw = new-object System.IO.Streamwriter($Objectfile,$false,[system.text.encoding]::GetEncoding(850))
}
if (-not $Currline.StartsWith('}'))
{$sw.writeline($Currline)}
else
{
$sw.writeline($Currline)
$sw.writeline()
$sw.Flush()
}
}
$endtime = Get-Date
$time = $endtime - $startime
Write-Host "$ObjCnt NAV objects splitted to $WorkingFolder\SPLITNAVOBJ\ in $($time.Minutes)m:$($time.Seconds)s:$($time.Milliseconds)ms" -ForegroundColor Yellow
Write-Host "Tables: $TabCnt" -ForegroundColor Yellow
Write-Host "Pages: $PagCnt" -ForegroundColor Yellow
Write-Host "Reports: $RepCnt" -ForegroundColor Yellow
Write-Host "Codeunits: $CodCnt" -ForegroundColor Yellow
Write-Host "XMLPorts: $XMLCnt" -ForegroundColor Yellow
Write-Host "Queries: $QueCnt" -ForegroundColor Yellow
Write-Host "MenuSuites: $MenCnt" -ForegroundColor Yellow
if ($ForCnt -gt 0)
{Write-Host "Forms: $ForCnt" -ForegroundColor Yellow}
if ($DatCnt -gt 0)
{Write-Host "Dataports: $DatCnt" -ForegroundColor Yellow}
[string]$ObjectList = ''
if ($TABCnt -gt 0) {$ObjectList += "TAB:$TABCnt "}
if ($FORCnt -gt 0) {$ObjectList += "FOR:$FORCnt "}
if ($PAGCnt -gt 0) {$ObjectList += "PAG:$PAGCnt "}
if ($REPCnt -gt 0) {$ObjectList += "REP:$REPCnt "}
if ($DATCnt -gt 0) {$ObjectList += "DAT:$DATCnt "}
if ($CODCnt -gt 0) {$ObjectList += "COD:$CODCnt "}
if ($QUECnt -gt 0) {$ObjectList += "QUE:$QUECnt "}
if ($XMLCnt -gt 0) {$ObjectList += "XML:$XMLCnt "}
if ($MENCnt -gt 0) {$ObjectList += "MEN:$MENCnt "}
$sr.Close()
$sr.Dispose()
$sw.close()
$sw.Dispose()
$TV_AfterCheck =
{
if($_.Node.Checked)
{
$_.Node.Setfocus
#$_.Node.SetFont = New-Object System.Drawing.Font("Microsoft Sans Serif",9,1,3,0)
$row = $dt.NewRow()
[String]$TempIndex = $_.Node.Tag.ToString("0000000000")
$row["ObjectIndex"] = $TempIndex
$row["ObjectFileName"] = $_.Node.Name
$dt.Rows.Add($row)
$dt.AcceptChanges()
#[void]$dt.Rows.Add("$_.Node.Tag","$_.Node.Name")
Read-SingleObjectFile($_.Node.Name)
#[System.Windows.Forms.MessageBox]::Show('Node ' + $_.Node.Text + ' checked')
}
else
{
[String]$TempIndex = $_.Node.Tag.ToString("0000000000")
#[System.Windows.Forms.MessageBox]::Show('Node ' + $TempIndex + ' uncheckêd')
$rows = $dt.Select("ObjectIndex = '$TempIndex'").Delete()
foreach($row2 in $rows)
{
$row2.Delete()
}
$dt.AcceptChanges
Clear-ObjectContent
#[System.Windows.Forms.MessageBox]::Show('Node ' + $_.Node.Text + ' unchecked')
}
}
$treeView1.Add_AfterCheck($TV_AfterCheck)
$form1.text = 'NAV Object Package Configurator ' + [System.IO.Path]::GetFileName($inputfile) + ' ' + 'Objects:' + $ObjCnt + ' ' + $ObjectList
$form1.Name = "form1"
$form1.DataBindings.DefaultDataSourceUpdateMode = 0
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Width = 838
$System_Drawing_Size.Height = 612
$form1.ClientSize = $System_Drawing_Size
$linkLabel1.Font = New-Object System.Drawing.Font("Microsoft Sans Serif",9,0,3,0)
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Width = 155
$System_Drawing_Size.Height = 23
$linkLabel1.Size = $System_Drawing_Size
$linkLabel1.TabIndex = 10
$linkLabel1.Text = "http://www.msdynamics.de"
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 180
$System_Drawing_Point.Y = 0
$linkLabel1.Location = $System_Drawing_Point
$linkLabel1.TabStop = $True
$linkLabel1.DataBindings.DefaultDataSourceUpdateMode = 0
$linkLabel1.Name = "linkLabel1"
$linkLabel1.add_click($linkLabel1_OpenLink)
$form1.Controls.Add($linkLabel1)
$button1.TabIndex = 4
$button1.Name = "button1"
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Width = 150
$System_Drawing_Size.Height = 23
$button1.Size = $System_Drawing_Size
$button1.UseVisualStyleBackColor = $True
$button1.Text = "Create Object Package"
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 0
$System_Drawing_Point.Y = 0
$button1.Location = $System_Drawing_Point
$button1.DataBindings.DefaultDataSourceUpdateMode = 0
$button1.add_Click($button1_OnClick)
$form1.Controls.Add($button1)
<#
$label3.TabIndex = 6
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Width = 100
$System_Drawing_Size.Height = 23
$label3.Size = $System_Drawing_Size
$label3.Text = "Object Content"
$label3.Font = New-Object System.Drawing.Font("Microsoft Sans Serif",9,0,3,0)
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 255
$System_Drawing_Point.Y = 3
$label3.Location = $System_Drawing_Point
$label3.DataBindings.DefaultDataSourceUpdateMode = 0
$label3.Name = "label3"
$form1.Controls.Add($label3)
#>
<#
$label2.TabIndex = 5
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Width = 100
$System_Drawing_Size.Height = 12
$label2.Size = $System_Drawing_Size
$label2.Text = "Object List"
$label2.Font = New-Object System.Drawing.Font("Microsoft Sans Serif",8,0,3,0)
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 8
$System_Drawing_Point.Y = 8
$label2.Location = $System_Drawing_Point
$label2.DataBindings.DefaultDataSourceUpdateMode = 0
$label2.Name = "label2"
$form1.Controls.Add($label2)
#>
$richTextBox1.Name = "richTextBox1"
$richTextBox1.Text = ""
$richTextBox1.DataBindings.DefaultDataSourceUpdateMode = 0
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 255
$System_Drawing_Point.Y = 30
$richTextBox1.Location = $System_Drawing_Point
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Width = 800
$System_Drawing_Size.Height = 454
$richTextBox1.Size = $System_Drawing_Size
$richTextBox1.Font = New-Object System.Drawing.Font("Courier New",11,0,3,0)
$richTextBox1.WordWrap = $false
$richtextbox1.ScrollBars = 'ForcedBoth'
$richtextbox1.Dock = 'Fill'
$richtextbox1.ReadOnly = $true
$RichTextBox1.BackColor = [Drawing.Color]::White
$RichTextBox1.ForeColor = [Drawing.Color]::Black
$richTextBox1.TabIndex = 1
$form1.Controls.Add($richTextBox1)
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Width = 300
$System_Drawing_Size.Height = 563
$treeView1.Size = $System_Drawing_Size
$treeView1.Name = "treeView1"
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 100
$System_Drawing_Point.Y = 100
$treeView1.Location = $System_Drawing_Point
$treeView1.DataBindings.DefaultDataSourceUpdateMode = 0
$treeView1.TabIndex = 0
$treeView1.Font = New-Object System.Drawing.Font("Microsoft Sans Serif",10,0,3,0)
$form1.Controls.Add($treeView1)
#Save the initial state of the form
#$InitialFormWindowState = $form1.WindowState
# Menu Options - File / Exit
$menuExit = New-Object System.Windows.Forms.ToolStripMenuItem
$menuFile = New-Object System.Windows.Forms.ToolStripMenuItem
#$menuExit.Image = [System.IconExtractor]::Extract("shell32.dll", 10, $true)
$menuExit.ShortcutKeys = "Control, X"
$menuExit.Text = "Exit"
$menuExit.Add_Click({$form1.Close()})
[void]$menuFile.DropDownItems.Add($menuExit)
$menuMain = New-Object System.Windows.Forms.MenuStrip
$mainToolStrip = New-Object System.Windows.Forms.ToolStrip
# Main ToolStrip
[void]$form1.Controls.Add($mainToolStrip)
# Main Menu Bar
[void]$form1.Controls.Add($menuMain)
$form1.ShowDialog() | Out-Null
#Invoke-item "$WorkingFolder\SPLITNAVOBJ\"
}
NAVObjectPackageConfigurator