Related
I am new to this forum and hoping to get some help.
I have a an HTML string having text and several base64 images.
I need to loop through all image tags adding a slash / before
the closing tag > so that each image ends with /> and return
a new html string with the changes.
so each
<IMG src="data:image/png;base64,iVBORw0KG....">
should then be
<IMG src="data:image/png;base64,iVBORw0KG...."/>
I am not versed with html and I am wondering how to do it
(using regex?).
Here is some pseudo code:
Function GetSourceImges(Sourcehtml As String) As List(Of String)
Dim listOfImgs As New List(Of String)()
'use regex to find image tags
'Return list of base64 image tags
End Function
For each image in list
insert a slash appropriately
next
Reconstitute a new html string with edited images
Thanks
Map all "IMG" tags using LINQ and use their indexes as an anchor to fix the missing "/" characters. please see my comments inside the code.
Sub Main()
Dim htmlstring As String = "<IMG src=""data:image/png;base64,iVBORw0KG....""> " & vbCrLf _
& "<img src=""data:image/png;base64,iVBORw0KG...."">" & vbCrLf _
& "<p>blahblah</p>" & vbCrLf _
& "<IMG src=""data:image/png;base64,iVBORw0KG...."">" & vbCrLf _
& "<p>blahblah</p>"
' find all indxes of img using regex and lambda exprations '
Dim indexofIMG() As Integer = Regex.Matches(htmlstring, "IMG", RegexOptions.IgnoreCase) _
.Cast(Of Match)().Select(Function(x) x.Index).ToArray()
' check from each index of "IMG" if "/" is missing '
For Each itm As Integer In indexofIMG
Dim counter As Integer = itm
While counter < htmlstring.Length - 1
If htmlstring(counter) = ">" Then
If htmlstring(counter - 1) <> "/" Then
' fix the missing "/" using Insert() method '
htmlstring = htmlstring.Insert(counter, "/")
End If
Exit While
End If
counter += 1
End While
Next
Console.WriteLine(htmlstring)
Console.ReadLine()
End Sub
Surprisingly it works with the console app but doesn't when I view it on a richtextbox as in btnEditHTML method below. The generated pdf has only one red dot and not two.
Can't say why.
I must say you have been very helpfull.
'SetTable and customimagetagprocessor borrowed from [here] iTextsharp base64 embedded image in header not parsing/showing
Imports System.IO
Imports iTextSharp.text
Imports iTextSharp.tool.xml
Imports iTextSharp.text.pdf
Imports iTextSharp.tool.xml.parser
Imports iTextSharp.tool.xml.pipeline.css
Imports iTextSharp.tool.xml.pipeline.html
Imports iTextSharp.tool.xml.pipeline.end
Imports iTextSharp.tool.xml.html
Imports System.Text.RegularExpressions
Public Class Form1
Dim dsktop As String = My.Computer.FileSystem.SpecialDirectories.Desktop
Public Function GetFormattedHTML(str As String) As String
'format images by changing > to />
' find all indxes of img using regex and lambda exprations '
Dim indexofIMG() As Integer = Regex.Matches(str.ToString, "IMG", RegexOptions.IgnoreCase) _
.Cast(Of Match)().Select(Function(x) x.Index).ToArray()
' check from each index of "IMG" if "/" is missing '
For Each itm As Integer In indexofIMG
Dim counter As Integer = itm
While counter < str.ToString.Length - 1
If str(counter) = ">" Then
If str(counter - 1) <> "/" Then
' fix the missing "/" using Insert() method '
str = str.ToString.Insert(counter, " /")
End If
Exit While
End If
counter += 1
End While
Next
Return str.ToString
End Function
Private Sub btnEditHTML_Click(sender As Object, e As EventArgs) Handles btnEditHTML.Click
Rtb.Text = String.Empty
'the 2 base64 images in the html below are actually just small red dots
Dim RawHTML As String = "<P>John Doe</P><IMG " &
"src=""data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg==""> Jackson5<IMG " &
"src=""data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg=="">"
Rtb.Text = GetFormattedHTML(RawHTML)
'notice that the 2nd base64 string is not edited as required.
End Sub
Private Sub btnGenerate_Click(sender As Object, e As EventArgs) Handles btnGenerate.Click
'here I create a 2 column itextsharp table to parse my html into the cells
Dim doc As New iTextSharp.text.Document(iTextSharp.text.PageSize.A4, 25, 25, 25, 30)
Dim wri As PdfWriter = PdfWriter.GetInstance(doc, New System.IO.FileStream(dsktop & "\testtable.pdf", System.IO.FileMode.Create))
doc.Open()
'set table columnwidths -------------------------------------------------------------
Dim MainTable As New PdfPTable(2) '2 column table
MainTable.WidthPercentage = 100
Dim Wth(1) As Single
Dim u As Integer = 2
For i As Integer = 0 To 1
Wth(i) = CInt(Math.Floor(2 * 500 / u))
Next
MainTable.SetWidths(Wth)
Dim htmlstr As String = GetFormattedHTML("<P>John Doe</P><IMG " &
"src=""data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg==""> Jackson5<IMG " &
"src=""data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg=="">")
Dim Elmts = New ElementList()
Elmts = XMLWorkerHelper.ParseToElementList(htmlstr, Nothing)
Dim MinorTable As New PdfPTable(1)
MinorTable = SetTable(Elmts, htmlstr)
For i = 1 To 2
Dim Cell As New PdfPCell
Cell.AddElement(MinorTable)
MainTable.AddCell(Cell)
Next
doc.Add(MainTable)
doc.Close()
Process.Start(dsktop & "\testtable.pdf")
End Sub
Public Function SetTable(ByVal elements As ElementList, ByVal htmlcode As String) As PdfPTable
Dim tagProcessors As DefaultTagProcessorFactory = CType(Tags.GetHtmlTagProcessorFactory(), DefaultTagProcessorFactory)
tagProcessors.RemoveProcessor(HTML.Tag.IMG) ' remove the default processor
tagProcessors.AddProcessor(HTML.Tag.IMG, New CustomImageTagProcessor()) ' use our new processor
Dim cssResolver As ICSSResolver = XMLWorkerHelper.GetInstance().GetDefaultCssResolver(True)
cssResolver.AddCssFile(Application.StartupPath & "\pdf.css", True)
'see sample css file at https://learnwebcode.com/how-to-create-your-first-css-file/
'Setup Fonts
Dim xmlFontProvider As XMLWorkerFontProvider = New XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS)
xmlFontProvider.RegisterDirectory(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "assets/fonts/"))
Dim cssAppliers As CssAppliers = New CssAppliersImpl(xmlFontProvider)
Dim htmlContext As HtmlPipelineContext = New HtmlPipelineContext(cssAppliers)
htmlContext.SetAcceptUnknown(True)
htmlContext.SetTagFactory(tagProcessors)
Dim pdf As ElementHandlerPipeline = New ElementHandlerPipeline(elements, Nothing)
Dim htmlp As HtmlPipeline = New HtmlPipeline(htmlContext, pdf)
Dim css As CssResolverPipeline = New CssResolverPipeline(cssResolver, htmlp)
Dim worker As XMLWorker = New XMLWorker(css, True)
Dim p As XMLParser = New XMLParser(worker)
'Dim holderTable As New PdfPTable({1})
Dim holderTable As PdfPTable = New PdfPTable({1})
holderTable.WidthPercentage = 100
holderTable.HorizontalAlignment = Element.ALIGN_LEFT
Dim holderCell As New PdfPCell()
holderCell.Padding = 0
holderCell.UseBorderPadding = False
holderCell.Border = 0
p.Parse(New MemoryStream(System.Text.Encoding.ASCII.GetBytes(htmlcode)))
For Each el As IElement In elements
holderCell.AddElement(el)
Next
holderTable.AddCell(holderCell)
'Dim holderRow As New PdfPRow({holderCell})
'holderTable.Rows.Add(holderRow)
Return holderTable
End Function
End Class
Public Class CustomImageTagProcessor
Inherits iTextSharp.tool.xml.html.Image
Public Overrides Function [End](ctx As IWorkerContext, tag As Tag, currentContent As IList(Of IElement)) As IList(Of IElement)
Dim attributes As IDictionary(Of String, String) = tag.Attributes
Dim src As String = String.Empty
If Not attributes.TryGetValue(iTextSharp.tool.xml.html.HTML.Attribute.SRC, src) Then
Return New List(Of IElement)(1)
End If
If String.IsNullOrEmpty(src) Then
Return New List(Of IElement)(1)
End If
If src.StartsWith("data:image/", StringComparison.InvariantCultureIgnoreCase) Then
' data:[<MIME-type>][;charset=<encoding>][;base64],<data>
Dim base64Data As String = src.Substring(src.IndexOf(",") + 1)
Dim imagedata As Byte() = Convert.FromBase64String(base64Data)
Dim image As iTextSharp.text.Image = iTextSharp.text.Image.GetInstance(imagedata)
Dim list As List(Of IElement) = New List(Of IElement)()
Dim htmlPipelineContext As pipeline.html.HtmlPipelineContext = GetHtmlPipelineContext(ctx)
list.Add(GetCssAppliers().Apply(New Chunk(DirectCast(GetCssAppliers().Apply(image, tag, htmlPipelineContext), iTextSharp.text.Image), 0, 0, True), tag, htmlPipelineContext))
Return list
Else
If File.Exists(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, src)) Then
Dim imagedata As Byte() = File.ReadAllBytes(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, src))
Dim image As iTextSharp.text.Image = iTextSharp.text.Image.GetInstance(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, src))
Dim list As List(Of IElement) = New List(Of IElement)()
Dim htmlPipelineContext As pipeline.html.HtmlPipelineContext = GetHtmlPipelineContext(ctx)
list.Add(GetCssAppliers().Apply(New Chunk(DirectCast(GetCssAppliers().Apply(image, tag, htmlPipelineContext), iTextSharp.text.Image), 0, 0, True), tag, htmlPipelineContext))
Return list
End If
Return MyBase.[End](ctx, tag, currentContent)
End If
End Function
End Class
I highly recommend just using AngleSharp to parse the HTML, edit the document if required, and save it again.
There are many posts on here about why trying to parse HTML with regular expressions is a bad idea.
var doc = new HtmlParser().Parse(html);
As you aren't actually changing the HTML content, just fixing up the tags, your should be able to just parse it and save it with no changes to fix the tags.
I've created an application in .net to monitor jobs in the printer by using the DLL in the following reference :
http://www.codeproject.com/Articles/51085/Monitor-jobs-in-a-printer-queue-NET?fid=1556859&select=4799234
my question is : how can i delay or prevent user from printing after he print for example 5 times a day ?
Knowing that The print jobs will saved in the DB.
I appreciate any help.
A fairly simply program could be written using the FindFirstPrinterChangeNotification function that monitors all printers available to the user. It should watch for the PRINTER_CHANGE_ADD_JOB event, which indicates a print job has been started. Once the user has exceeded the criteria, your program would then delete any new print jobs the user started. I think it would be best to notify the user rather than just deleting their print jobs silently.
This doesn't prevent users from trying to print, but it does have the same end result. No paper will be produced until your application allows it.
Solved ! I've used the following methods to solve my problem :
to pause printer Job call this :
Public Shared Function PausePrintJob(printerName As String, printJobID As Integer) As Boolean
Dim isActionPerformed As Boolean = False
Dim searchQuery As String = "SELECT * FROM Win32_PrintJob"
Dim searchPrintJobs As New ManagementObjectSearcher(searchQuery)
Dim prntJobCollection As ManagementObjectCollection = searchPrintJobs.[Get]()
For Each prntJob As ManagementObject In prntJobCollection
Dim jobName As System.String = prntJob.Properties("Name").Value.ToString()
Dim splitArr As Char() = New Char(0) {}
splitArr(0) = Convert.ToChar(",")
Dim prnterName As String = jobName.Split(splitArr)(0)
Dim prntJobID As Integer = Convert.ToInt32(jobName.Split(splitArr)(1))
Dim documentName As String = prntJob.Properties("Document").Value.ToString()
If [String].Compare(prnterName, printerName, True) = 0 Then
If prntJobID = printJobID Then
prntJob.InvokeMethod("Pause", Nothing)
isActionPerformed = True
Exit For
End If
End If
Next
Return isActionPerformed
End Function
And to cancel printer jobs i've used the following method :
Public Shared Function CancelPrintJob(printerName As String, printJobID As Integer) As Boolean
Dim isActionPerformed As Boolean = False
Dim searchQuery As String = "SELECT * FROM Win32_PrintJob"
Dim searchPrintJobs As New ManagementObjectSearcher(searchQuery)
Dim prntJobCollection As ManagementObjectCollection = searchPrintJobs.[Get]()
For Each prntJob As ManagementObject In prntJobCollection
Dim jobName As System.String = prntJob.Properties("Name").Value.ToString()
Dim splitArr As Char() = New Char(0) {}
splitArr(0) = Convert.ToChar(",")
Dim prnterName As String = jobName.Split(splitArr)(0)
Dim prntJobID As Integer = Convert.ToInt32(jobName.Split(splitArr)(1))
Dim documentName As String = prntJob.Properties("Document").Value.ToString()
If [String].Compare(prnterName, printerName, True) = 0 Then
If prntJobID = printJobID Then
prntJob.Delete()
isActionPerformed = True
Exit For
End If
End If
Next
Return isActionPerformed
End Function
And if need to resume the printing after pause then you should use :
Public Shared Function ResumePrintJob(printerName As String, printJobID As Integer) As Boolean
Dim isActionPerformed As Boolean = False
Dim searchQuery As String = "SELECT * FROM Win32_PrintJob"
Dim searchPrintJobs As New ManagementObjectSearcher(searchQuery)
Dim prntJobCollection As ManagementObjectCollection = searchPrintJobs.[Get]()
For Each prntJob As ManagementObject In prntJobCollection
Dim jobName As System.String = prntJob.Properties("Name").Value.ToString()
Dim splitArr As Char() = New Char(0) {}
splitArr(0) = Convert.ToChar(",")
Dim prnterName As String = jobName.Split(splitArr)(0)
Dim prntJobID As Integer = Convert.ToInt32(jobName.Split(splitArr)(1))
Dim documentName As String = prntJob.Properties("Document").Value.ToString()
If [String].Compare(prnterName, printerName, True) = 0 Then
If prntJobID = printJobID Then
prntJob.InvokeMethod("Resume", Nothing)
isActionPerformed = True
Exit For
End If
End If
Next
Return isActionPerformed
End Function
I need to verify that a provided username is a Domain Administrator in c#.
Any idea's on how to do this?
You can use WindowsIdentity to get the current user.
Then create a WindowsPrincipal with the WindowsIdentity.
And check WindowsPrincipal.IsInRole(WindowsBuiltInRole.Administrator)
Hope this can help you.
EDIT : I just see the ASP tag now... This link could help you, same thing but for ASP.
Function ADUserInfo(sLogonUser, cOption)
Dim oConnection
Dim oCommand
Dim oRoot
Dim oDomain
Dim sADsPath
Dim sDomain
sDomain = Mid(sLogonUser, 1, Instr(1, sLogonUser, "\") - 1)
Set oConnection = CreateObject("ADODB.Connection")
With oConnection
.Provider = "ADsDSOObject"
.Mode = "1" 'Read
.Properties("Encrypt Password") = True
.Open "Active Directory Provider"
End With
Set oCommand = CreateObject("ADODB.Command")
oCommand.ActiveConnection = oConnection
Set oRoot = GetObject("LDAP://" & sDomain & "/rootdse")
Set oDomain = GetObject("LDAP://" & sDomain & "/" & oRoot.Get("defaultNamingContext"))
sADsPath = "<" & oDomain.ADsPath & ">"
Select Case lcase(cOption)
Case "groups"
ADUserInfo = ADUserGroups(sLogonUser, oConnection, oCommand, oRoot, oDomain, sADsPath)
Case "name"
ADUserInfo = ADUserName(sLogonUser, oConnection, oCommand, oRoot, oDomain, sADsPath)
Case "supervisor"
End Select
End Function
Function ADUserGroups(sLogonUser, oConnection, oCommand, oRoot, oDomain, sADsPath)
Dim sFilter
Dim sAttribsToReturn
Dim sDepth
Dim sDomainSID
Dim vObjectSID
Dim sObjectSID
Dim sGroupRID
Dim iPrimaryGroupID
Dim oPrimaryGroup
Dim oRS
Dim value
Dim cGroups
Dim sDomain
Dim sLogonName
sDomain = Mid(sLogonUser, 1, Instr(1, sLogonUser, "\") - 1)
sLogonName = Mid(sLogonUser, Instr(1, sLogonUser, "\") + 1)
sFilter = "(&(objectCategory=Person)(objectClass=user)(sAMAccountName=" & sLogonName & "))"
sAttribsToReturn = "memberOf,primaryGroupID,objectSID"
sDepth = "subTree"
ocommand.CommandText = sADsPath & ";" & sFilter & ";" & sAttribsToReturn & ";" & sDepth
Set oRS = ocommand.Execute
' Only one user should meet the criteria
If (oRS.RecordCount = 1) Then
' Get that user's info
For i = 0 To oRS.Fields.Count - 1
If (oRS.Fields(i).Name = "memberOf") Then
' I've never seen this field come back with more than
' ONE value, but the original code I started with
' treated the memberOf property as though it was a
' collection. So, I've left it a collection until
' I can verify it. KLW
cGroups = ""
For Each value In oRS.Fields(i).Value
cGroups = cGroups & replace(split(value,",")(0),"CN=","") & ";"
Next
ElseIf (oRS.Fields(i).Name = "primaryGroupID") Then
' need this to get the PrimaryGroup after other group membership has been obtained
' (Primary Group ID and Object SID ID needed to get the primary group)
iPrimaryGroupID = oRS.Fields(i).Value
ElseIf (oRS.Fields(i).Name = "objectSID") Then
' adVarBinary -- need this to get the PrimaryGroup.
' It is not included in the memberOf group list
vObjectSID = oRS.Fields(i).Value
sObjectSID = SDDL_SID(vObjectSID)
End If
Next
' The primary group is not included in memberOf...
' We have the SDDL form of the user's SID.
' Remove the user's RID ( the last sub authority)
' up to the "-"
'
sDomainSID = Mid(sObjectSID, 1, (InStrREV(sObjectSID,"-")))
' Build the SID of the Primary group
' from the domainSID and the Primary Group RID in
' the PrimaryGroupID.
'
sGroupRID = StrRID(iPrimaryGroupID)
sDomainSID = sDomainSID & sGroupRID
' Get the primary group
'
set oPrimaryGroup = GetObject("LDAP://" & sDomain & "/<SID=" & sDomainSID & ">")
cGroups = replace(split(oPrimaryGroup.Get("DistinguishedName"),",")(0),"CN=","") & ";" & cGroups
ADUserGroups = cGroups
End If
End Function
Function ADUserName(sLogonUser, oConnection, oCommand, oRoot, oDomain, sADsPath)
Dim sFilter
Dim sAttribsToReturn
Dim sDepth
Dim sDomainSID
Dim vObjectSID
Dim sObjectSID
Dim sGroupRID
Dim iPrimaryGroupID
Dim oPrimaryGroup
Dim oRS
Dim value
Dim sDomain
Dim sLogonName
sDomain = Mid(sLogonUser, 1, Instr(1, sLogonUser, "\") - 1)
sLogonName = Mid(sLogonUser, Instr(1, sLogonUser, "\") + 1)
sFilter = "(&(objectCategory=Person)(objectClass=user)(sAMAccountName=" & sLogonName & "))"
sAttribsToReturn = "distinguishedName"
sDepth = "subTree"
ocommand.CommandText = sADsPath & ";" & sFilter & ";" & sAttribsToReturn & ";" & sDepth
Set oRS = ocommand.Execute
' Only one user should meet the criteria
If (oRS.RecordCount = 1) Then
' Get that user's info
For i = 0 To oRS.Fields.Count - 1
If (oRS.Fields(i).Name = "distinguishedName") Then
ADUserName = replace(split(oRS.Fields(i).Value,",")(0),"CN=","")
End If
Next
End If
End Function
function SDDL_SID ( oSID )
dim IssueAuthorities(11)
Dim SubAuthorities
Dim strSDDL
Dim IssueIndex
Dim Revision
Dim i, j, k, index, p2, subtotal, dblSubAuth
IssueAuthorities(0) = "-0-0"
IssueAuthorities(1) = "-1-0"
IssueAuthorities(2) = "-2-0"
IssueAuthorities(3) = "-3-0"
IssueAuthorities(4) = "-4"
IssueAuthorities(5) = "-5"
IssueAuthorities(6) = "-?"
IssueAuthorities(7) = "-?"
IssueAuthorities(8) = "-?"
IssueAuthorities(9) = "-?"
' First byte is the revision value
'
Revision = ascb(midB(osid,1,1))
' Second byte is the number of sub authorities in the
' SID
'
SubAuthorities = CInt(ascb(midb(oSID,2,1)))
strSDDL = "S-" & Revision
IssueIndex = CInt(ascb(midb(oSID,8,1)))
strSDDL = strSDDL & IssueAuthorities(IssueIndex)
index = 9
i = index
for k = 1 to SubAuthorities
p2 = 0
subtotal = 0
for j = 1 to 4
dblSubAuth = CDbl(ascb(midb(osid,i,1))) * (2^p2)
subTotal = subTotal + dblSubAuth
p2 = p2 + 8
i = i + 1
next
' Convert the value to a string, add it to the SDDL Sid and continue
'
strSDDL = strSDDL & "-" & cstr(subTotal)
next
SDDL_SID = strSDDL
end function
function Get_HexString( oSID )
Dim outStr, i, b
outStr = ""
for i = 0 to Ubound(oSid)
b = hex(ascb(midb(oSid,i+1,1)))
if( len(b) = 1 ) then b = "0" & b
outStr = outStr & b
next
Get_HexString = outStr
end function
function StrRID( inVal )
dim dLocal
if( (inVal and &H80000000) <> 0 ) then
dLocal = CDbl((inval and &H7FFFFFFF))
dLocal = dLocal + 2^31
StrRID = cstr(dLocal)
else
StrRID = Cstr(inVal)
end if
end function
I need to mute my application because it's using 5 webbrowsers and navigates to sites with flash, this can cause a lot of annoying sound , so I searched everywhere but no luck
I want to know if there is a way to mute either my application or my webbrowsers either through vb code or whatever other language (I will make a plug-in).
Thanks in advance for your help.
On Windows Vista and later, you can set an individual application's sound volume by calling a function inside winmm.dll
[DllImport("winmm.dll")]
private static extern int waveOutSetVolume(IntPtr hwo, uint dwVolume);
And call following static method:
public static void MuteApplication()
{
int NewVolume = 0;
uint NewVolumeAllChannels = (((uint)NewVolume & 0x0000ffff) | ((uint)NewVolume << 16));
waveOutSetVolume(IntPtr.Zero, NewVolumeAllChannels);
}
I think that you will need to set the configuration of IExplorer which is the process who plays that sounds.
You could set a flag to don't play sound using registry:
At this key:
HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main
Value name:
Play_Background_Sounds
Data:
no
Time ago I did a class to manage Regedit operations, you can use it like this:
RegEdit.Set_Value("HKCU\Software\Microsoft\Internet Explorer\Main", _
"Play_Background_Sounds", _
"no", _
Microsoft.Win32.RegistryValueKind.String)
RegEdit.Set_Value("HKCU\Software\Microsoft\Internet Explorer\Main", _
"Play_Background_Sounds", _
"yes", _
Microsoft.Win32.RegistryValueKind.String)
Here is the Class:
#Region " RegEdit "
' [ RegEdit Functions ]
'
' // By Elektro H#cker
'
' Examples :
'
' -----------
' Create Key:
' -----------
' RegEdit.Create_Key("HKCU\Software\MyProgram") ' Creates "HKCU\Software\MyProgram"
' RegEdit.Create_Key("HKEY_CURRENT_USER\Software\MyProgram\Settings\") ' Creates "HKCU\Software\MyProgram\Settings"
'
' -----------
' Delete Key:
' -----------
' RegEdit.Delete_Key("HKLM\Software\7-zip") ' Deletes the "7-zip" tree including subkeys
' RegEdit.Delete_Key("HKEY_LOCAL_MACHINE\Software\7-zip\") ' Deletes the "7-zip" tree including subkeys
'
' -------------
' Delete Value:
' -------------
' RegEdit.Delete_Value("HKCU\Software\7-Zip", "Lang") ' Deletes "Lang" Value
' RegEdit.Delete_Value("HKEY_CURRENT_USER\Software\7-Zip\", "Lang") ' Deletes "Lang" Value
'
' ----------
' Get Value:
' ----------
' Dim Data As String = RegEdit.Get_Value("HKCU\Software\MyProgram", "Value name"))
' Dim Data As String = RegEdit.Get_Value("HKEY_CURRENT_USER\Software\MyProgram", "Value name"))
'
' ----------
' Set Value:
' ----------
' RegEdit.Set_Value("HKCU\Software\MyProgram", "Value name", "Data", Microsoft.Win32.RegistryValueKind.String) ' Create/Replace "Value Name" with "Data" as string data
' RegEdit.Set_Value("HKEY_CURRENT_USER\Software\MyProgram\", "Value name", "Data", Microsoft.Win32.RegistryValueKind.String) ' Create/Replace "Value Name" with "Data" as string data
'
' -----------
' Export Key:
' -----------
' RegEdit.Export_Key("HKLM", "C:\HKLM.reg") ' Export entire "HKEY_LOCAL_MACHINE" Tree to "C:\HKLM.reg" file.
' RegEdit.Export_Key("HKLM\Software\7-zip\", "C:\7-zip.reg") ' Export entire "7-zip" Tree to "C:\7-zip.reg" file.
'
' ------------
' Import File:
' ------------
' RegEdit.Import_RegFile("C:\Registry_File.reg") ' Install a registry file.
'
' ------------
' Jump To Key:
' ------------
' RegEdit.Jump_To_Key("HKLM") ' Opens Regedit at "HKEY_LOCAL_MACHINE" Root.
' RegEdit.Jump_To_Key("HKEY_LOCAL_MACHINE\Software\7-zip\") ' Opens Regedit at "HKEY_LOCAL_MACHINE\Software\7-zip" tree.
'
' -----------
' Exist Key?:
' -----------
' MsgBox(RegEdit.Exist_Key("HKCU\software") ' Checks if "Software" Key exist.
' -------------
' Exist Value?:
' -------------
' MsgBox(RegEdit.Exist_Value("HKLM\software\7-zip", "Path") ' Checks if "Path" value exist.
'
' ------------
' Exist Data?:
' ------------
' MsgBox(RegEdit.Exist_Data("HKLM\software\7-zip", "Path") ' Checks if "Path" value have empty data.
'
' ---------
' Copy Key:
' ---------
' RegEdit.Copy_Key("HKCU", "Software", "7-Zip", "HKLM", "Software", "7-zip") ' Copies "HKCU\Software\7-Zip" to "HKLM\Software\7-Zip"
' RegEdit.Copy_Key("HKCU", "Software", "7-Zip", Nothing, "Software", "7-zip") ' Copies "HKCU\Software\7-Zip" to "HKCU\Software\7-Zip"
' RegEdit.Copy_Key("HKCU", "Software", "7-Zip", "HKLM", "Software", Nothing) ' Copies "HKCU\Software\7-Zip" to "HKLM\Software\"
' RegEdit.Copy_Key("HKCU", "Software", "7-Zip", "HKLM", Nothing, Nothing) ' Copies "HKCU\Software\7-Zip" to "HKLM\"
' RegEdit.Copy_Key("HKCU", "\Software\", "\7-Zip\", "HKLM", "\Software\", "\7-zip\") ' Copies "HKCU\Software\7-Zip" to "HKLM\Software\7-Zip"
'
' -----------
' Copy Value:
' -----------
' RegEdit.Copy_Value("HKLM\software\7-zip", "path", "HKLM\software\7-zip", "path_backup") ' Copies "Path" value with their data to "HKLM\software\7-zip" "path_backup".
'
' -------------------
' Set_UserAccess_Key:
' -------------------
' RegEdit.Set_UserAccess_Key("HKCU\Software\7-Zip", {RegEdit.RegUserAccess.Administrators_Full_Access})
' RegEdit.Set_UserAccess_Key("HKEY_CURRENT_USER\Software\7-Zip", {RegEdit.RegUserAccess.Administrators_Full_Access, RegEdit.RegUserAccess.Creator_Full_Access, RegEdit.RegUserAccess.System_Full_Access})
#Region " RegEdit Class "
Public Class RegEdit
Private Shared RootKey As Microsoft.Win32.RegistryKey = Nothing
Private Shared KeyPath As String = String.Empty
''' <summary>
''' Create a new registry key.
''' </summary>
Public Shared Function Create_Key(ByVal RegKey As String) As Boolean
RootKey = Get_Root_Key(RegKey)
KeyPath = Get_Key_Path(RegKey)
Try
RootKey.CreateSubKey(KeyPath)
RootKey.Dispose()
Return True
Catch ex As Exception
' MsgBox(ex.Message)
' Throw New Exception(ex.Message)
Return False
End Try
End Function
''' <summary>
''' Delete a registry key.
''' </summary>
Public Shared Function Delete_Key(ByVal RegKey As String) As Boolean
RootKey = Get_Root_Key(RegKey)
KeyPath = Get_Key_Path(RegKey)
Try
RootKey.DeleteSubKeyTree(KeyPath)
RootKey.Dispose()
Return True
Catch ex As Exception
' MsgBox(ex.Message)
' Throw New Exception(ex.Message)
Return False
End Try
End Function
''' <summary>
''' Delete a registry key.
''' </summary>
Public Shared Function Delete_Value(ByVal RegKey As String, ByVal RegValue As String) As Boolean
RootKey = Get_Root_Key(RegKey)
KeyPath = Get_Key_Path(RegKey)
Try
RootKey.OpenSubKey(KeyPath, True).DeleteValue(RegValue)
RootKey.Dispose()
Return True
Catch ex As Exception
' MsgBox(ex.Message)
' Throw New Exception(ex.Message)
Return False
End Try
End Function
''' <summary>
''' Get the data of a registry value.
''' </summary>
Public Shared Function Get_Value(ByVal RegKey As String, ByVal RegValue As String) As String
RootKey = Get_Root_Key(RegKey)
KeyPath = RootKey.ToString & "\" & Get_Key_Path(RegKey)
RootKey.Dispose()
Try
Return My.Computer.Registry.GetValue(KeyPath, RegValue, Nothing)
Catch ex As Exception
' MsgBox(ex.Message)
' Throw New Exception(ex.Message)
Return False
End Try
End Function
''' <summary>
''' Set the data of a registry value.
''' If the Key or value don't exist it will be created automatically.
''' </summary>
Public Shared Function Set_Value(ByVal RegKey As String, _
ByVal RegValue As String, _
ByVal RegData As String, _
ByVal RegDataType As Microsoft.Win32.RegistryValueKind) As Boolean
RootKey = Get_Root_Key(RegKey)
KeyPath = RootKey.ToString & "\" & Get_Key_Path(RegKey)
Try
If RegDataType = Microsoft.Win32.RegistryValueKind.Binary Then
My.Computer.Registry.SetValue(KeyPath, RegValue, System.Text.Encoding.ASCII.GetBytes(RegData), Microsoft.Win32.RegistryValueKind.Binary)
RootKey.Dispose()
Else
My.Computer.Registry.SetValue(KeyPath, RegValue, RegData, RegDataType)
RootKey.Dispose()
End If
Return True
Catch ex As Exception
' MsgBox(ex.Message)
' Throw New Exception(ex.Message)
Return False
End Try
End Function
''' <summary>
''' Export a registry key (including sub-keys) to a file.
''' </summary>
Public Shared Function Export_Key(ByVal RegKey As String, ByVal OutputFile As String) As Boolean
Dim RootKey As String = Get_Root_Key(RegKey).ToString
Dim KeyPath As String = RootKey & "\" & Get_Key_Path(RegKey)
If KeyPath.EndsWith("\") Then KeyPath = KeyPath.Substring(0, KeyPath.Length - 1)
Try
Dim Regedit As New Process()
Dim Regedit_Info As New ProcessStartInfo()
Regedit_Info.FileName = "Reg.exe"
Regedit_Info.Arguments = "Export " & """" & KeyPath & """" & " " & """" & OutputFile & """" & " /y"
Regedit_Info.CreateNoWindow = True
Regedit_Info.WindowStyle = ProcessWindowStyle.Hidden
Regedit_Info.UseShellExecute = False
Regedit.StartInfo = Regedit_Info
Regedit.Start()
Regedit.WaitForExit()
If Regedit.ExitCode <> 0 Then
Regedit.Dispose()
Return False
Else
Regedit.Dispose()
Return True
End If
Catch ex As Exception
' MsgBox(ex.Message)
' Throw New Exception(ex.Message)
Return False
End Try
End Function
''' <summary>
''' Import a registry file.
''' </summary>
Public Shared Function Import_RegFile(ByVal RegFile As String) As Boolean
If IO.File.Exists(RegFile) Then
Try
Dim Regedit As New Process()
Dim Regedit_Info As New ProcessStartInfo()
Regedit_Info.FileName = "Reg.exe"
Regedit_Info.Arguments = "Import " & """" & RegFile & """"
Regedit_Info.CreateNoWindow = True
Regedit_Info.WindowStyle = ProcessWindowStyle.Hidden
Regedit_Info.UseShellExecute = False
Regedit.StartInfo = Regedit_Info
Regedit.Start()
Regedit.WaitForExit()
If Regedit.ExitCode <> 0 Then
Regedit.Dispose()
Return False
Else
Regedit.Dispose()
Return True
End If
Catch ex As Exception
' MsgBox(ex.Message)
' Throw New Exception(ex.Message)
Return False
End Try
Else
' MsgBox("File don't exist")
Return False
End If
End Function
''' <summary>
''' Open Regedit at specific key.
''' </summary>
Public Shared Function Jump_To_Key(ByVal RegKey As String) As Boolean
RootKey = Get_Root_Key(RegKey)
KeyPath = RootKey.ToString & "\" & Get_Key_Path(RegKey)
If KeyPath.EndsWith("\") Then KeyPath = KeyPath.Substring(0, KeyPath.Length - 1)
Try
Set_Value("HKCU\Software\Microsoft\Windows\CurrentVersion\Applets\Regedit", "LastKey", "" & KeyPath & "", Microsoft.Win32.RegistryValueKind.String)
RootKey.Dispose()
Process.Start("Regedit.exe")
Return True
Catch ex As Exception
' MsgBox(ex.Message)
' Throw New Exception(ex.Message)
Return False
End Try
End Function
''' <summary>
''' Checks if a Key exist.
''' </summary>
Public Shared Function Exist_Key(ByVal RegKey As String) As Boolean
RootKey = Get_Root_Key(RegKey)
KeyPath = Get_Key_Path(RegKey)
If RootKey Is Nothing OrElse KeyPath Is Nothing Then Return False
If RootKey.OpenSubKey(KeyPath, False) Is Nothing Then
RootKey.Dispose()
Return False
Else
RootKey.Dispose()
Return True
End If
End Function
''' <summary>
''' Checks if a value exist.
''' </summary>
Public Shared Function Exist_Value(ByVal RegKey As String, ByVal RegValue As String) As Boolean
RootKey = Get_Root_Key(RegKey)
KeyPath = Get_Key_Path(RegKey)
Try
If RootKey.OpenSubKey(KeyPath, False).GetValue(RegValue) = String.Empty Then
RootKey.Dispose()
Return False
Else
RootKey.Dispose()
Return True
End If
Catch ex As Exception
' MsgBox(ex.Message)
' Throw New Exception(ex.Message)
Return False
End Try
End Function
''' <summary>
''' Check if a value have empty data.
''' </summary>
Public Shared Function Exist_Data(ByVal RegKey As String, ByVal RegValue As String) As Boolean
RootKey = Get_Root_Key(RegKey)
KeyPath = RootKey.ToString & "\" & Get_Key_Path(RegKey)
Try
If My.Computer.Registry.GetValue(KeyPath, RegValue, Nothing) = Nothing Then
RootKey.Dispose()
Return False
Else
RootKey.Dispose()
Return True
End If
Catch ex As Exception
' MsgBox(ex.Message)
' Throw New Exception(ex.Message)
Return False
End Try
End Function
''' <summary>
''' Copy a key tree to another location of the registry.
''' </summary>
Public Shared Function Copy_Key(ByVal OldRootKey As String, _
ByVal OldPath As String, _
ByVal OldName As String, _
ByVal NewRootKey As String, _
ByVal NewPath As String, _
ByVal NewName As String) As Boolean
If OldPath Is Nothing Then OldPath = ""
If NewRootKey Is Nothing Then NewRootKey = OldRootKey
If NewPath Is Nothing Then NewPath = ""
If NewName Is Nothing Then NewName = ""
If OldRootKey.EndsWith("\") Then OldRootKey = OldRootKey.Substring(0, OldRootKey.Length - 1)
If NewRootKey.EndsWith("\") Then NewRootKey = NewRootKey.Substring(0, NewRootKey.Length - 1)
If OldPath.StartsWith("\") Then OldPath = OldPath.Substring(1, OldPath.Length - 1)
If OldPath.EndsWith("\") Then OldPath = OldPath.Substring(0, OldPath.Length - 1)
If NewPath.StartsWith("\") Then NewPath = NewPath.Substring(1, NewPath.Length - 1)
If NewPath.EndsWith("\") Then NewPath = NewPath.Substring(0, NewPath.Length - 1)
If OldName.StartsWith("\") Then OldName = OldName.Substring(1, OldName.Length - 1)
If OldName.EndsWith("\") Then OldName = OldName.Substring(0, OldName.Length - 1)
If NewName.StartsWith("\") Then NewName = NewName.Substring(1, NewName.Length - 1)
If NewName.EndsWith("\") Then NewName = NewName.Substring(0, NewName.Length - 1)
Dim OrigRootKey As Microsoft.Win32.RegistryKey = Get_Root_Key(OldRootKey)
Dim DestRootKey As Microsoft.Win32.RegistryKey = Get_Root_Key(NewRootKey)
Dim oldkey As Microsoft.Win32.RegistryKey = OrigRootKey.OpenSubKey(OldPath + "\" + OldName, True)
Dim newkey As Microsoft.Win32.RegistryKey = DestRootKey.OpenSubKey(NewPath, True).CreateSubKey(NewName)
Reg_Copy_SubKeys(oldkey, newkey)
Return True
End Function
Private Shared Sub Reg_Copy_SubKeys(OrigKey As Microsoft.Win32.RegistryKey, DestKey As Microsoft.Win32.RegistryKey)
Dim ValueNames As String() = OrigKey.GetValueNames()
Dim SubKeyNames As String() = OrigKey.GetSubKeyNames()
For i As Integer = 0 To ValueNames.Length - 1
Application.DoEvents()
DestKey.SetValue(ValueNames(i), OrigKey.GetValue(ValueNames(i)))
Next
For i As Integer = 0 To SubKeyNames.Length - 1
Application.DoEvents()
Reg_Copy_SubKeys(OrigKey.OpenSubKey(SubKeyNames(i), True), DestKey.CreateSubKey(SubKeyNames(i)))
Next
End Sub
''' <summary>
''' Copy a value with their data to another location of the registry.
''' If the Key don't exist it will be created automatically.
''' </summary>
Public Shared Function Copy_Value(ByVal RegKey As String, ByVal RegValue As String, _
ByVal NewRegKey As String, ByVal NewRegValue As String) As Boolean
Dim OldRootKey As String = Get_Root_Key(RegKey).ToString
Dim OldKeyPath As String = OldRootKey & "\" & Get_Key_Path(RegKey)
Dim NewRootKey As String = Get_Root_Key(NewRegKey).ToString
Dim NewKeyPath As String = NewRootKey & "\" & Get_Key_Path(NewRegKey)
Dim RegData = Get_Value(OldKeyPath, RegValue)
Try
Set_Value(NewKeyPath, NewRegValue, RegData, Microsoft.Win32.RegistryValueKind.Unknown)
Return True
Catch ex As Exception
' MsgBox(ex.Message)
' Throw New Exception(ex.Message)
Return False
End Try
End Function
''' <summary>
''' Valid User identifiers for Regini.exe command.
''' </summary>
Public Enum RegUserAccess As Short
Administrators_Full_Access = 1
Administrators_Read_Access = 2
Administrators_Read_and_Write_Access = 3
Administrators_Read_Write_and_Delete_Access4
Administrators_Read_Write_and_Execute_Access = 20
Creator_Full_Access = 5
Creator_Read_and_Write_Access = 6
Interactive_User_Full_Access = 21
Interactive_User_Read_and_Write_Access = 22
Interactive_User_Read_Write_and_Delete_Access = 23
Power_Users_Full_Access = 11
Power_Users_Read_and_Write_Access = 12
Power_Users_Read_Write_and_Delete_Access = 13
System_Full_Access = 17
System_Operators_Full_Access = 14
System_Operators_Read_and_Write_Access = 15
System_Operators_Read_Write_and_Delete_Access = 16
System_Read_Access = 19
System_Read_and_Write_Access = 18
World_Full_Access = 7
World_Read_Access = 8
World_Read_and_Write_Access = 9
World_Read_Write_and_Delete_Access = 10
End Enum
''' <summary>
''' Modify the User permissions of a registry key.
''' </summary>
Public Shared Function Set_UserAccess_Key(ByVal RegKey As String, ByVal RegUserAccess() As RegUserAccess) As Boolean
Dim PermissionString As String = String.Empty
RootKey = Get_Root_Key(RegKey)
KeyPath = RootKey.ToString & "\" & Get_Key_Path(RegKey)
If KeyPath.EndsWith("\") Then KeyPath = KeyPath.Substring(0, KeyPath.Length - 1)
For Each user In RegUserAccess
' Application.DoEvents()
PermissionString += " " & user
Next
PermissionString = "[" & PermissionString & "]"
PermissionString = PermissionString.Replace("[ ", "[")
Try
Using TextFile As New IO.StreamWriter(System.IO.Path.GetTempPath() & "Regini.ini", False, System.Text.Encoding.Default)
TextFile.WriteLine("""" & KeyPath & """" & " " & PermissionString)
End Using
Dim Regini As New Process()
Dim Regini_Info As New ProcessStartInfo()
Regini_Info.FileName = "Regini.exe"
Regini_Info.Arguments = """" & System.IO.Path.GetTempPath() & "Regini.ini" & """"
Regini_Info.CreateNoWindow = True
Regini_Info.WindowStyle = ProcessWindowStyle.Hidden
Regini_Info.UseShellExecute = False
Regini.StartInfo = Regini_Info
Regini.Start()
Regini.WaitForExit()
If Regini.ExitCode <> 0 Then
RootKey.Dispose()
Regini.Dispose()
Return False
Else
RootKey.Dispose()
Regini.Dispose()
Return True
End If
Catch ex As Exception
' MsgBox(ex.Message)
' Throw New Exception(ex.Message)
Return False
End Try
End Function
' Returns the RootKey formatted
Private Shared Function Get_Root_Key(ByVal RegKey As String) As Microsoft.Win32.RegistryKey
Select Case RegKey.ToUpper.Split("\").First
Case "HKCR", "HKEY_CLASSES_ROOT" : Return Microsoft.Win32.Registry.ClassesRoot
Case "HKCC", "HKEY_CURRENT_CONFIG" : Return Microsoft.Win32.Registry.CurrentConfig
Case "HKCU", "HKEY_CURRENT_USER" : Return Microsoft.Win32.Registry.CurrentUser
Case "HKLM", "HKEY_LOCAL_MACHINE" : Return Microsoft.Win32.Registry.LocalMachine
Case "HKEY_PERFORMANCE_DATA" : Return Microsoft.Win32.Registry.PerformanceData
Case Else : Return Nothing
End Select
End Function
' Returns the KeyPath formatted
Private Shared Function Get_Key_Path(ByVal RegKey As String) As String
If RegKey Is Nothing Then Return Nothing
Dim Path As String = String.Empty
For i As Integer = 1 To RegKey.Split("\").Length - 1
' Application.DoEvents()
Path &= RegKey.Split("\")(i) & "\"
Next
If Not Path.Contains("\") Then Path = Path & "\"
Path = Path.Substring(0, Path.LastIndexOf("\"))
Return Path
End Function
End Class
#End Region
#End Region
Working on a QC integration tool and having trouble creating a test in the Test Plan - unfortunately the API is written for VB6, and I'm working in C#.
Here's what I've got so far:
private void HPQC_Create_Test_Plan_Test(TDConnectionClass tdConnection, string ParentFolderPath, string TestName)
{
try
{
TreeManager treeM = (TreeManager)tdConnection.TreeManager;
ISysTreeNode ParentFolder = (ISysTreeNode)treeM.get_NodeByPath(ParentFolderPath);
TestFactory TestF = (TestFactory)tdConnection.TestFactory;
Test TstTest = (Test)TestF.AddItem(System.DBNull.Value);
TstTest.Name = TestName;
TstTest.Type = "MANUAL";
TstTest.Post();
HPQC_Status_Test_Plan.Text = "Test " + TestName + " created.";
tdConnection.Logout();
tdConnection.Disconnect();
tdConnection = null;
}
catch (Exception ex)
{
HPQC_Status_Test_Plan.Text = "Test Creation Failed.";
Console.WriteLine("[Error] " + ex);
tdConnection.Logout();
tdConnection.Disconnect();
tdConnection = null;
}
}
The code errors out on the Post with a simple "Failed to Post" and I'm at a loss as to why.
Here's the API example in VB6:
Public Sub AddTest(FolderName$, TestName$)
Create new test.
This example assumes that the subject folder containing the
new test is directly under the root "Subject" folder.
Dim objTest As Test
Dim folder As SubjectNode
Dim testF As TestFactory
Dim TreeMgr As TreeManager
Dim Path As String
Dim Trees As List
Dim RootName As String
Dim SubjRoot As SubjectNode
'tdc is the global TDConnection object.
Set TreeMgr = tdc.TreeManager
' Use TreeManager.TreeRoot to get the list of subject
' root nodes from the tree manager.
' There is only one item in this list.
Set Trees = TreeMgr.RootList(TDOLE_SUBJECT)
' Get the name of the subject tree root in your project.
RootName = Trees.Item(1)
Path = RootName & "\" & FolderName
On Error Resume Next
Set folder = TreeMgr.NodeByPath(Path)
On Error GoTo 0
If folder Is Nothing Then 'Create the folder
' Get the SubjectNode root node object from the
' tree manager by name.
Set SubjRoot = TreeMgr.TreeRoot(RootName)
Set folder = SubjRoot.AddNode(FolderName)
End If
Set testF = folder.TestFactory
Set objTest = testF.AddItem(Null)
objTest.name = TestName
objTest.Type = "SYSTEM-TEST"
objTest.Post
Dim VerCtl As VCS
Dim bIsLocked As Boolean
Dim strLockedBy As String
Set VerCtl = objTest.VCS
VerCtl.Refresh
bIsLocked = VerCtl.IsLocked
strLockedBy = VerCtl.LockedBy
' After POST, Test is checked in.
Debug.Print "Is locked: " & bIsLocked
'Is locked: False
Debug.Print "Is locked by: """ & strLockedBy & """"
'Is locked by: ""
VerCtl.CheckOut -1, "To change state", True
VerCtl.Refresh
bIsLocked = VerCtl.IsLocked
strLockedBy = VerCtl.LockedBy
Debug.Print "Is locked: " & bIsLocked
'Is locked: True
Debug.Print "Is locked by: """ & strLockedBy & """"
'Is locked by: "User1"
' Take an arbitrary field to change.
Debug.Print "Status: """ & objTest.Field("TS_STATUS") & """"
'Status: ""
objTest.Field("TS_STATUS") = "Ready"
objTest.Post
VerCtl.CheckIn "", "Changed status"
VerCtl.Refresh
bIsLocked = VerCtl.IsLocked
strLockedBy = VerCtl.LockedBy
Debug.Print "Is locked: " & bIsLocked
'Is locked: False
Debug.Print "Is locked by: """ & strLockedBy & """"
'Is locked by: ""
End Sub
Thanks in advance!
I have something similar but more suited to generating a folder structure also.
Our root folder in QC is "Subject" but you can simply change this in order to create the specific folder you want. Also instead of setting the ["TS_SUBJECT"] title this is not required as we are using the node at the leaf node to create the tests into the specified folder.
private TestFactory addSubjectTreeStructure(String subjectField)
{
String folderRootString = subjectField;
folderRootString = folderRootString.Replace("\\", "/");
String[] folders = folderRootString.Split('/');
// Test Plan Tree Manager
TreeManager treeMgr = tdc.TreeManager;
SubjectNode subjectNode = treeMgr.get_NodeByPath("Subject");
ISysTreeNode node = (ISysTreeNode)subjectNode;
// Creating the folders in test plan.
for (int i = 0; i < folders.Length; i++)
{
try
{
node = node.FindChildNode(folders[i]);
}
catch (Exception ex)
{
node = node.AddNode(folders[i]);
Console.WriteLine(ex.Message + ".\nChild not found. Adding new node: " + folders[i]);
}
}
// Set the leaf folder and then returning the TestFactory from where all test cases will be generated from.
SubjectNode folder = treeMgr.get_NodeById(node.NodeID);
return folder.TestFactory;
}
Then by using the returned test factory you can create the tests in this folder.
Gave it the weekend to think it over, and realized that the code above didn't have a parent attribute to link to in the tree. Unfortunately TreeManager in C# does not have TreeRoot to work with for some reason.
Worked around that by grabbing the path manually for the prototype - the user has to key in parent path like "Root\Subject" into a textbox.
The key attribute was the "TS_Subject" which is the NodeID of the folder that you want to attach the test to.
The following code works for me:
private void HPQC_Create_Test_Plan_Test(TDConnectionClass tdConnection, string ParentFolderPath, string TestName)
{
try
{
TreeManager treeM = (TreeManager)tdConnection.TreeManager;
ISysTreeNode ParentFolder = (ISysTreeNode)treeM.get_NodeByPath(ParentFolderPath);
TestFactory TestF = (TestFactory)tdConnection.TestFactory;
Test TstTest = (Test)TestF.AddItem(System.DBNull.Value);
TstTest.Name = TestName;
TstTest.Type = "MANUAL";
TstTest["TS_SUBJECT"] = ParentFolder.NodeID;
TstTest.Post();
HPQC_Status_Test_Plan.Text = "Test " + TestName + " created.";
tdConnection.Logout();
tdConnection.Disconnect();
tdConnection = null;
}
catch (Exception ex)
{
HPQC_Status_Test_Plan.Text = "Test Creation Failed.";
Console.WriteLine("[Error] " + ex);
tdConnection.Logout();
tdConnection.Disconnect();
tdConnection = null;
}
}