Determine if screen is active or not from Windows 8 Registry - windows-8

I am looking at monitors list in
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\DISPLAY
In Windows 7, there are a subkey under each screen node named "Control" that indicate if the screen is active or not.
In Windows 8 there are no such subkey.
How can determine if a monitor is active or not from the Windows 8 registry?

Try this code (I verified this):
Public Function GetMonitorDetails() As List(Of WSGetLoginData.Monitor)
'Open the Display Reg-Key
Dim wmiPNPID As New List(Of String)
Dim mc As System.Management.ManagementClass
Dim moc As ManagementObjectCollection
Dim PathPNPID As String
mc = New ManagementClass("Win32_DesktopMonitor")
moc = mc.GetInstances()
For Each mo In moc
PathPNPID = mo.Item("PNPDeviceID")
If PathPNPID.Trim <> "" AndAlso PathPNPID.Contains("\") Then
PathPNPID = PathPNPID.Substring(PathPNPID.LastIndexOf("\") + 1)
wmiPNPID.Add(PathPNPID.ToUpper)
End If
Next
Dim Display As RegistryKey = Registry.LocalMachine
Dim bFailed As [Boolean] = False
Dim obj_ListMonitor As New List(Of WSGetLoginData.Monitor)
Try
Display = Registry.LocalMachine.OpenSubKey("SYSTEM\CurrentControlSet\Enum\DISPLAY")
Catch
bFailed = True
End Try
If Not bFailed And (Display IsNot Nothing) Then
'Get all MonitorIDss
For Each sMonitorID As String In Display.GetSubKeyNames()
Dim MonitorID As RegistryKey = Display.OpenSubKey(sMonitorID)
If MonitorID IsNot Nothing Then
'Get all Plug&Play ID's
For Each sPNPID As String In MonitorID.GetSubKeyNames()
Dim PnPID As RegistryKey = MonitorID.OpenSubKey(sPNPID)
If PnPID IsNot Nothing Then
Dim sSubkeys As String() = PnPID.GetSubKeyNames()
'Check if Monitor is active
'If Array.IndexOf(sSubkeys, "Control") > -1 Then
If Not wmiPNPID Is Nothing AndAlso wmiPNPID.Count > 0 AndAlso wmiPNPID.Contains(sPNPID.ToUpper) Then
If Array.IndexOf(sSubkeys, "Device Parameters") > -1 Then
Dim DevParam As RegistryKey = PnPID.OpenSubKey("Device Parameters")
Dim sSerial As String = ""
Dim sModel As String = ""
'Define Search Keys
Dim sSerFind As New String(New Char() {ChrW(0), ChrW(0), ChrW(0), ChrW(&HFF)})
Dim sModFind As New String(New Char() {ChrW(0), ChrW(0), ChrW(0), ChrW(&HFC)})
'Get the EDID code
Dim bObj As Byte() = TryCast(DevParam.GetValue("EDID", Nothing), Byte())
If bObj IsNot Nothing Then
'Get the 4 Vesa descriptor blocks
Dim sDescriptor As String() = New String(3) {}
sDescriptor(0) = Encoding.[Default].GetString(bObj, &H36, 18)
sDescriptor(1) = Encoding.[Default].GetString(bObj, &H48, 18)
sDescriptor(2) = Encoding.[Default].GetString(bObj, &H5A, 18)
sDescriptor(3) = Encoding.[Default].GetString(bObj, &H6C, 18)
'Search the Keys
For Each sDesc As String In sDescriptor
If sDesc.Contains(sSerFind) Then
sSerial = sDesc.Substring(4).Replace(vbNullChar, "").Trim()
End If
If sDesc.Contains(sModFind) Then
sModel = sDesc.Substring(4).Replace(vbNullChar, "").Trim()
End If
Next
End If
If Not String.IsNullOrEmpty(sSerial) AndAlso sSerial.Trim <> "" Then
Dim insertar As Boolean = True
If Not obj_ListMonitor Is Nothing AndAlso obj_ListMonitor.Count > 0 Then
For k As Integer = 0 To obj_ListMonitor.Count - 1
If obj_ListMonitor(k).SerialNumber.Trim = sSerial Then
insertar = False
Exit For
End If
Next
End If
If insertar Then
Dim obj_monitor As New WSGetLoginData.Monitor
obj_monitor.UUID = Security.FingerPrint.Value(sModel & sSerial)
obj_monitor.Modelo = sModel
obj_monitor.SerialNumber = sSerial
obj_ListMonitor.Add(obj_monitor)
End If
End If
End If
End If
End If
Next
End If
Next
End If
Return obj_ListMonitor
End Function

Related

OpenXML Adding Notes and Threaded Comments

I'm posting this to help others that may be going through the struggle I went through when trying to add simple notes or threaded comments to an excel spreadsheet using the DocumentFormat.OpenXML library using VB.Net.
I've added my own answer.
Imports System.Text
Imports DocumentFormat.OpenXml
Imports DocumentFormat.OpenXml.Packaging
Imports DocumentFormat.OpenXml.Spreadsheet
Imports System.Runtime.CompilerServices
Imports System.Xml
Imports System.IO
Imports System.Text.RegularExpressions
Imports DocumentFormat.OpenXml.Office2019.Excel.ThreadedComments
Public Class ExcelDocInfo
Public Property WBPart As WorkbookPart = Nothing
Public Property WSPart As WorksheetPart = Nothing
Public Property SData As SheetData = Nothing
End Class
Public Class CellReferenceIndexes
Public ColumnIndex As Integer? = Nothing
Public RowIndex As Integer? = Nothing
Public Sub New()
End Sub
End Class
Public Class OpenXML
Public Shared Function GetThreadedCommentVMLShapeXML(CellReference As String, CommentCount As Integer)
Dim commentVmlXml As String = String.Empty
commentVmlXml = <![CDATA[
<v:shape id="[ShapeID]" type="#_x0000_t202" style='position:absolute; margin-left:59.25pt;margin-top:1.5pt;width:108pt;height:59.25pt;z-index:1; visibility:hidden' fillcolor="infoBackground [80]" strokecolor="none [81]" o:insetmode="auto">
<v:fill color2="infoBackground [80]"/>
<v:shadow color="none [81]" obscured="t"/>
<v:path o:connecttype="none"/>
<v:textbox style='mso-direction-alt:auto'>
<div style='text-align:left'></div>
</v:textbox>
<x:ClientData ObjectType="Note">
<x:MoveWithCells/>
<x:SizeWithCells/>
<x:Anchor>[CoordinatesForVMLCommentShape]</x:Anchor>
<x:AutoFill>False</x:AutoFill>
<x:Row>[RowIndex]</x:Row>
<x:Column>[ColumnIndex]</x:Column>
</x:ClientData>
</v:shape>
]]>.Value.Trim()
Dim ShapeId As String = "_x0000_s" & (1109 + CommentCount + 1).ToString()
commentVmlXml = commentVmlXml.Replace("[ShapeID]", ShapeId)
commentVmlXml = commentVmlXml.Replace("[CoordinatesForVMLCommentShape]", GetAnchorCoordinatesForVMLCommentShape(CellReference))
commentVmlXml = commentVmlXml.Replace("[RowIndex]", (GetIndexesFromCellReference(CellReference).RowIndex - 1).ToString())
commentVmlXml = commentVmlXml.Replace("[ColumnIndex]", (GetIndexesFromCellReference(CellReference).ColumnIndex - 1).ToString())
Return commentVmlXml
End Function
Public Shared Function GetNoteVMLShapeXML(CellReference As String, CommentCount As Integer)
Dim commentVmlXml As String = String.Empty
commentVmlXml = <![CDATA[
<v:shape id="[ShapeID]" type="#_x0000_t202" style='position:absolute; margin-left:59.25pt; margin-top:1.5pt; width:108pt; height:59.25pt; z-index:1; visibility:hidden' fillcolor="#ffffe1" o:insetmode="auto">
<v:fill color2="#ffffe1" />
<v:shadow on="t" color="black" obscured="t" />
<v:path o:connecttype="none" />
<v:textbox style='mso-fit-shape-to-text:true'>
<div style='text-align:left'></div>
</v:textbox>
<x:ClientData ObjectType="Note">
<x:MoveWithCells />
<x:SizeWithCells />
<x:Anchor>[CoordinatesForVMLCommentShape]</x:Anchor>
<x:AutoFill>False</x:AutoFill>
<x:Row>[RowIndex]</x:Row>
<x:Column>[ColumnIndex]</x:Column>
</x:ClientData>
</v:shape>
]]>.Value.Trim()
Dim ShapeId As String = "_x0000_s" & (1109 + CommentCount + 1).ToString()
commentVmlXml = commentVmlXml.Replace("[ShapeID]", ShapeId)
commentVmlXml = commentVmlXml.Replace("[CoordinatesForVMLCommentShape]", GetAnchorCoordinatesForVMLCommentShape(CellReference))
commentVmlXml = commentVmlXml.Replace("[RowIndex]", (GetIndexesFromCellReference(CellReference).RowIndex - 1).ToString())
commentVmlXml = commentVmlXml.Replace("[ColumnIndex]", (GetIndexesFromCellReference(CellReference).ColumnIndex - 1).ToString())
Return commentVmlXml
End Function
Public Shared Function GetAnchorCoordinatesForVMLCommentShape(CellReference As String) As String
Dim coordinates As String = String.Empty
Dim startingRow As Integer = 0
Dim startingColumn As Integer = GetIndexesFromCellReference(CellReference).ColumnIndex - 1
'From upper right coordinate of a rectangle
'[0] Left column
'[1] Left column offset
'[2] Left row
'[3] Left row offset
'To bottom right coordinate of a rectangle
'[4] Right column
'[5] Right column offset
'[6] Right row
'[7] Right row offset
Dim coordList As List(Of Integer) = {0, 0, 0, 0, 0, 0, 0, 0}.ToList()
If Integer.TryParse(GetIndexesFromCellReference(CellReference).RowIndex, startingRow) Then
startingRow -= 1
coordList(0) = startingColumn + 1
coordList(1) = 15
coordList(2) = startingRow
coordList(4) = startingColumn + 3
coordList(5) = 15
coordList(6) = startingRow + 3
If startingRow = 0 Then
coordList(3) = 2
coordList(7) = 16
Else
coordList(3) = 10
coordList(7) = 4
End If
coordinates = String.Join(",", coordList.ConvertAll(Of String)(Function(X) X.ToString()).ToArray())
End If
Return coordinates
End Function
Public Shared Function GetIndexesFromCellReference(CellReference As String) As CellReferenceIndexes
Dim CellReferenceInfo As New CellReferenceIndexes
Dim ColRef As String = ""
For Each C As Char In CellReference
If Not IsNumeric(C) Then
ColRef &= C
Else
Exit For
End If
Next
ColRef = ColRef.ToUpper()
CellReferenceInfo.RowIndex = Strings.Right(CellReference, CellReference.Length - ColRef.Length)
Dim ColIndex As Integer = 0
For Idx As Integer = 0 To ColRef.Length - 1
ColIndex *= 26
Dim charA As Integer = Asc("A")
Dim charColLetter As Integer = Asc(ColRef(Idx))
ColIndex += (charColLetter - charA) + 1
Next
CellReferenceInfo.ColumnIndex = ColIndex
Return CellReferenceInfo
End Function
Public Shared Sub AddNote(DocInfo As ExcelDocInfo, XCell As Cell, XAuthor As String, Comment As String, Optional XFontName As String = "Tahoma", Optional FontSize As Double = 11, Optional FontBold As Boolean = False, Optional FontItalic As Boolean = False, Optional TextColor As System.Drawing.Color = Nothing, Optional HighlightColor As System.Drawing.Color = Nothing)
If DocInfo Is Nothing Then
Exit Sub
End If
If XCell Is Nothing Then
Exit Sub
End If
If String.IsNullOrEmpty(XAuthor) Then
Exit Sub
End If
If String.IsNullOrEmpty(Comment) Then
Exit Sub
End If
If TextColor = Nothing Then TextColor = System.Drawing.Color.Black
Dim CommentsPart As WorksheetCommentsPart = Nothing
If DocInfo.WSPart.WorksheetCommentsPart Is Nothing Then
CommentsPart = DocInfo.WSPart.AddNewPart(Of WorksheetCommentsPart)
Else
CommentsPart = DocInfo.WSPart.WorksheetCommentsPart()
End If
Dim XComments As Comments = CommentsPart.Comments
If XComments Is Nothing Then
XComments = New Comments() With {.MCAttributes = New MarkupCompatibilityAttributes() With {.Ignorable = "xr"}}
XComments.AddNamespaceDeclaration("mc", "http://schemas.openxmlformats.org/markup-compatibility/2006")
XComments.AddNamespaceDeclaration("xr", "http://schemas.microsoft.com/office/spreadsheetml/2014/revision")
CommentsPart.Comments = XComments
End If
Dim XAuthors As Authors = XComments.GetFirstChild(Of Authors)
If XAuthors Is Nothing Then
XAuthors = New Authors()
XComments.Append(XAuthors)
End If
Dim XLAuthor As Author = (From A As Author In XAuthors.ToList() Where A.Text = XAuthor).FirstOrDefault()
If XLAuthor Is Nothing Then
XLAuthor = New Author() With {.Text = XAuthor}
XAuthors.Append(XLAuthor)
End If
Dim AuthorID As UInt32 = Convert.ToUInt32(XAuthors.AsEnumerable.ToList().IndexOf(XLAuthor))
Dim CommList As CommentList = XComments.GetFirstChild(Of CommentList)
If CommList Is Nothing Then
CommList = New CommentList()
XComments.Append(CommList)
End If
Dim XComment As Comment = XComments.CommentList.AppendChild(Of Comment)(New Spreadsheet.Comment() With {
.AuthorID = New UInt32Value(AuthorID),
.Reference = XCell.CellReference,
.ShapeId = New UInt32Value(Convert.ToUInt32(0))
})
Dim XCommentText As New CommentText()
Dim XRun As New Run()
Dim XRunProperties As New RunProperties()
Dim XFontSize As New FontSize() With {.Val = New DoubleValue(Convert.ToDouble(FontSize))}
Dim XColor As New Color() With {.Rgb = New HexBinaryValue With {.Value = System.Drawing.ColorTranslator.ToHtml(System.Drawing.Color.FromArgb(TextColor.ToArgb())).Replace("#", "")}}
Dim XFillColor As Color = Nothing
If HighlightColor <> Nothing Then
XFillColor = New Color() With {.Rgb = New HexBinaryValue With {.Value = System.Drawing.ColorTranslator.ToHtml(System.Drawing.Color.FromArgb(HighlightColor.ToArgb())).Replace("#", "")}}
End If
Dim XRunFont As New RunFont With {.Val = New StringValue(XFontName)}
Dim XRunBold As New Bold() With {.Val = New BooleanValue(FontBold)}
Dim XRunItalic As New Italic() With {.Val = New BooleanValue(FontItalic)}
Dim xRunPropertyCharSet As New RunPropertyCharSet() With {.Val = New Int32Value(Convert.ToInt32(1))}
XRunProperties.Append(XFontSize)
XRunProperties.Append(XColor)
If XFillColor IsNot Nothing Then
XRunProperties.Append(XFillColor)
End If
XRunProperties.Append(XRunFont)
XRunProperties.Append(XRunBold)
XRunProperties.Append(XRunItalic)
XRunProperties.Append(xRunPropertyCharSet)
Dim XText As New Text() With {.Space = SpaceProcessingModeValues.Preserve, .Text = Comment}
XRun.Append(XRunProperties)
XRun.Append(XText)
XCommentText.Append(XRun)
XComment.Append(XCommentText)
Dim DrawingPartList As List(Of VmlDrawingPart) = DocInfo.WSPart.VmlDrawingParts.ToList()
Dim CommentCount As Integer = 0
Dim DrawingPart As VmlDrawingPart = DocInfo.WSPart.GetPartsOfType(Of VmlDrawingPart)().FirstOrDefault()
Dim Writer As XmlTextWriter = Nothing
Dim DrawingPartStream As Stream = Nothing
Dim SR As StreamReader = Nothing
If DrawingPart Is Nothing Then
DrawingPart = DocInfo.WSPart.AddNewPart(Of VmlDrawingPart)()
DrawingPartStream = DrawingPart.GetStream(IO.FileMode.Create)
SR = New StreamReader(DrawingPartStream)
Writer = New XmlTextWriter(DrawingPartStream, Encoding.UTF8)
Dim XMLText As String = <![CDATA[
<xml xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o=\"urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel">
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout>
<v:shapetype id="_x0000_t202" coordsize="21600,21600" o:spt="202" path="m,l,21600r21600,l21600,xe">
<v:stroke joinstyle="miter"/>
<v:path gradientshapeok="t" o:connecttype="rect" />
</v:shapetype>
]]>.Value.Trim()
Writer.WriteRaw(XMLText)
Writer.Flush()
DocInfo.WSPart.Worksheet.AddNamespaceDeclaration("xdr", "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing")
DocInfo.WSPart.Worksheet.AddNamespaceDeclaration("x14", "http://schemas.microsoft.com/office/spreadsheetml/2009/9/main")
Dim PartID As String = DocInfo.WSPart.GetIdOfPart(DrawingPart)
Dim XLegacyDrawing As LegacyDrawing = New LegacyDrawing() With {.Id = PartID}
DocInfo.WSPart.Worksheet.Append(XLegacyDrawing)
Else
DrawingPartStream = DrawingPart.GetStream()
SR = New StreamReader(DrawingPartStream)
Dim ReadText As String = SR.ReadToEnd()
Dim MatchColl As MatchCollection = Nothing
Dim MatchPattern As New Regex("\<v:shape ")
MatchColl = MatchPattern.Matches(ReadText)
CommentCount = MatchColl.Count
MatchColl = Nothing
MatchPattern = Nothing
Writer = New XmlTextWriter(DrawingPartStream, Encoding.UTF8)
End If
Dim commentsVmlXml As String = String.Empty
commentsVmlXml = GetNoteVMLShapeXML(XCell.CellReference.Value, CommentCount)
Writer.WriteRaw(commentsVmlXml)
Writer.Flush()
Writer.Close()
Writer.Dispose()
Writer = Nothing
SR.Close()
SR.Dispose()
DrawingPartStream.Close()
DrawingPartStream.Dispose()
End Sub
Public Shared Sub AddThreadedComment(DocInfo As ExcelDocInfo, XCell As Cell, XAuthor As String, Comment As String)
If DocInfo Is Nothing Then
Exit Sub
End If
If XCell Is Nothing Then
Exit Sub
End If
If String.IsNullOrEmpty(XAuthor) Then
Exit Sub
End If
If String.IsNullOrEmpty(Comment) Then
Exit Sub
End If
Dim CommentsPart As WorksheetCommentsPart = Nothing
If DocInfo.WSPart.WorksheetCommentsPart Is Nothing Then
CommentsPart = DocInfo.WSPart.AddNewPart(Of WorksheetCommentsPart)
Else
CommentsPart = DocInfo.WSPart.WorksheetCommentsPart()
End If
Dim XComments As Comments = CommentsPart.Comments
If XComments Is Nothing Then
XComments = New Comments() With {.MCAttributes = New MarkupCompatibilityAttributes() With {.Ignorable = "xr"}}
XComments.AddNamespaceDeclaration("mc", "http://schemas.openxmlformats.org/markup-compatibility/2006")
XComments.AddNamespaceDeclaration("xr", "http://schemas.microsoft.com/office/spreadsheetml/2014/revision")
CommentsPart.Comments = XComments
End If
Dim PersPart As WorkbookPersonPart = DocInfo.WBPart.GetPartsOfType(Of WorkbookPersonPart).FirstOrDefault()
If PersPart Is Nothing Then
PersPart = DocInfo.WBPart.AddNewPart(Of WorkbookPersonPart)
End If
Dim PersList As PersonList = PersPart.PersonList
If PersList Is Nothing Then
PersList = New PersonList
PersList.AddNamespaceDeclaration("x", "http://schemas.openxmlformats.org/spreadsheetml/2006/main")
PersPart.PersonList = PersList
End If
Dim Pers As Person = (From P As Person In PersList.AsEnumerable() Where P.DisplayName.Value = XAuthor Select P).FirstOrDefault()
If Pers Is Nothing Then
Pers = New Person() With {.DisplayName = New StringValue(XAuthor), .Id = New StringValue("{" & Guid.NewGuid().ToString().ToUpper() & "}"), .UserId = New StringValue(XAuthor), .ProviderId = New StringValue("None")}
PersList.Append(Pers)
End If
Dim XAuthors As Authors = XComments.GetFirstChild(Of Authors)
If XAuthors Is Nothing Then
XAuthors = New Authors()
XComments.Append(XAuthors)
End If
Dim AuthorGUID As String = "{" & Guid.NewGuid().ToString() & "}"
Dim XLAuthor As Author = New Author() With {.Text = "tc=" & AuthorGUID}
XAuthors.Append(XLAuthor)
Dim WSThreadedCommentsPart As WorksheetThreadedCommentsPart = DocInfo.WSPart.WorksheetThreadedCommentsParts.FirstOrDefault()
If WSThreadedCommentsPart Is Nothing Then
WSThreadedCommentsPart = DocInfo.WSPart.AddNewPart(Of WorksheetThreadedCommentsPart)
End If
Dim XThreadedComments As ThreadedComments = WSThreadedCommentsPart.ThreadedComments
If XThreadedComments Is Nothing Then
XThreadedComments = New ThreadedComments()
WSThreadedCommentsPart.ThreadedComments = XThreadedComments
End If
Dim XThreadedComment As ThreadedComment = New ThreadedComment() With {.Ref = New StringValue(XCell.CellReference), .DT = New DateTimeValue(Now().ToUniversalTime()), .PersonId = Pers.Id, .Id = New StringValue(AuthorGUID)}
Dim XThreadedCommentText As New ThreadedCommentText(Comment)
XThreadedComment.Append(XThreadedCommentText)
XThreadedComments.Append(XThreadedComment)
Dim AuthorID As UInt32 = Convert.ToUInt32(XAuthors.ToList().IndexOf(XLAuthor))
Dim CommList As CommentList = XComments.GetFirstChild(Of CommentList)
If CommList Is Nothing Then
CommList = New CommentList()
XComments.Append(CommList)
End If
Dim XComment As Comment = XComments.CommentList.AppendChild(Of Comment)(New Spreadsheet.Comment() With {
.AuthorID = New UInt32Value(AuthorID),
.Reference = XCell.CellReference,
.ShapeId = New UInt32Value(Convert.ToUInt32(0))
})
XComment.SetAttribute(New OpenXmlAttribute("uid", "http://schemas.microsoft.com/office/spreadsheetml/2014/revision", Pers.Id.Value))
Dim Prepend As String = "[Threaded comment]
Your version of Excel allows you to read this threaded comment; however, any edits to it will get removed if the file is opened in a newer version of Excel. Learn more: https://go.microsoft.com/fwlink/?linkid=870924
Comment:
"
Dim XCommentText As New CommentText()
Dim XText As New Text() With {.Text = Prepend & Comment}
XCommentText.Append(XText)
XComment.Append(XCommentText)
Dim DrawingPartList As List(Of VmlDrawingPart) = DocInfo.WSPart.VmlDrawingParts.ToList()
Dim CommentCount As Integer = 0
Dim DrawingPart As VmlDrawingPart = DocInfo.WSPart.GetPartsOfType(Of VmlDrawingPart)().FirstOrDefault()
Dim Writer As XmlTextWriter = Nothing
Dim DrawingPartStream As Stream = Nothing
Dim SR As StreamReader = Nothing
If DrawingPart Is Nothing Then
DrawingPart = DocInfo.WSPart.AddNewPart(Of VmlDrawingPart)()
DrawingPartStream = DrawingPart.GetStream(IO.FileMode.Create)
SR = New StreamReader(DrawingPartStream)
Writer = New XmlTextWriter(DrawingPartStream, Encoding.UTF8)
Dim XMLText As String = <![CDATA[
<xml xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o=\"urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel">
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout>
<v:shapetype id="_x0000_t202" coordsize="21600,21600" o:spt="202" path="m,l,21600r21600,l21600,xe">
<v:stroke joinstyle="miter"/>
<v:path gradientshapeok="t" o:connecttype="rect" />
</v:shapetype>
]]>.Value.Trim()
Writer.WriteRaw(XMLText)
Writer.Flush()
DocInfo.WSPart.Worksheet.AddNamespaceDeclaration("xdr", "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing")
DocInfo.WSPart.Worksheet.AddNamespaceDeclaration("x14", "http://schemas.microsoft.com/office/spreadsheetml/2009/9/main")
Dim PartID As String = DocInfo.WSPart.GetIdOfPart(DrawingPart)
Dim XLegacyDrawing As LegacyDrawing = New LegacyDrawing() With {.Id = PartID}
DocInfo.WSPart.Worksheet.Append(XLegacyDrawing)
Else
DrawingPartStream = DrawingPart.GetStream()
SR = New StreamReader(DrawingPartStream)
Dim ReadText As String = SR.ReadToEnd()
Dim MatchColl As MatchCollection = Nothing
Dim MatchPattern As New Regex("\<v:shape ")
MatchColl = MatchPattern.Matches(ReadText)
CommentCount = MatchColl.Count
MatchColl = Nothing
MatchPattern = Nothing
Writer = New XmlTextWriter(DrawingPartStream, Encoding.UTF8)
End If
Dim commentsVmlXml As String = String.Empty
commentsVmlXml = GetThreadedCommentVMLShapeXML(XCell.CellReference.Value, CommentCount)
Writer.WriteRaw(commentsVmlXml)
Writer.Flush()
Writer.Close()
Writer.Dispose()
Writer = Nothing
SR.Close()
SR.Dispose()
DrawingPartStream.Close()
DrawingPartStream.Dispose()
End Sub
Public Shared Sub FinalizeComments(DocInfo As ExcelDocInfo)
Dim DrawingPart As VmlDrawingPart = DocInfo.WSPart.GetPartsOfType(Of VmlDrawingPart)().FirstOrDefault()
If DrawingPart IsNot Nothing Then
Using DrawingPartStream As Stream = DrawingPart.GetStream()
Using SR As StreamReader = New StreamReader(DrawingPartStream)
Dim ReadText As String = SR.ReadToEnd()
If Not ReadText.ToLower().EndsWith("</xml>") Then
Using Writer As XmlTextWriter = New XmlTextWriter(DrawingPartStream, Encoding.UTF8)
Writer.WriteRaw("</xml>")
Writer.Flush()
Writer.Close()
End Using
End If
SR.Close()
End Using
DrawingPartStream.Close()
End Using
End If
End Sub
Public Shared Function GetCell(ExcelRow As Row, ColumnNumber As Integer) As Cell
Dim WSCell As Cell = Nothing
If (From C As Cell In ExcelRow.Elements(Of Cell) Where C.CellReference.Value = ExcelColToName(ColumnNumber) & ExcelRow.RowIndex.ToString()).Count > 0 Then
WSCell = (From C As Cell In ExcelRow.Elements(Of Cell) Where C.CellReference.Value = ExcelColToName(ColumnNumber) & ExcelRow.RowIndex.ToString()).FirstOrDefault()
Else
WSCell = New Cell() With {.CellReference = ExcelColToName(ColumnNumber) & ExcelRow.RowIndex.ToString()}
ExcelRow.InsertAt(Of Cell)(WSCell, ExcelRow.Elements(Of Cell).Count)
End If
Return WSCell
End Function
Public Shared Function GetRow(SData As SheetData, RowNumber As Integer) As Row
Dim R As Row = Nothing
Dim RIdx As UInt32Value = Convert.ToUInt32(RowNumber)
If SData.Elements(Of Row).Count > 0 Then
R = (From ERow As Row In SData.Elements(Of Row) Where ERow.RowIndex = RIdx).FirstOrDefault()
End If
If R Is Nothing Then
R = New Row() With {.RowIndex = RIdx}
SData.Append(R)
End If
Return R
End Function
End Class
Public Class TestCase
Public Sub RunTest()
'This sample does not dive into the creation of the spreadsheet. This example focuses strictly on notes and threaded comments.
'In a production example, there would be another sub in the OpenXML class that would populate this ExcelDocInfo object.
'Note that this code will fail as the objects within the DocInfo object currently have no reference to actual objects
Dim DocInfo As New ExcelDocInfo
Dim RowIdx As Integer = 1
Dim ColIdx As Integer = 1
Dim XRow As Row = OpenXML.GetRow(DocInfo.SData, RowIdx)
Dim XCell As Cell = OpenXML.GetCell(XRow, ColIdx)
OpenXML.AddThreadedComment(DocInfo, XCell, "Author Name", "Comment Text Goes Here")
OpenXML.FinalizeComments(DocInfo)
End Sub
End Class
Great post - I was going through that struggle. :-)
I had to make the following changes for the code to work in my case.
Without these changes Excel was unable to open the resulting document.
What is still failing is starting off from a ClosedXML generated document that contains old-school notes.
Remove the backslash in 2 locations of xmlns:o=\"urn:schemas-microsoft-com
Add ToUpper here, a GUID needs to be uppercase:
Dim AuthorGUID As String = "{" & Guid.NewGuid().ToString().ToUpper() & "}"
Ensure the x:tableParts element is after the x:legacyDrawing element in the sheet xml
Dim PartID As String = DocInfo.WSPart.GetIdOfPart(DrawingPart)
Dim XLegacyDrawing As LegacyDrawing = New LegacyDrawing() With {.Id = PartID}
Dim tableXMLElement = DocInfo.WSPart.Worksheet.ChildElements().Where(Function(x) x.GetType Is GetType(TableParts)).FirstOrDefault
If tableXMLElement IsNot Nothing Then
tableXMLElement.InsertBeforeSelf(Of OpenXmlElement)(XLegacyDrawing)
Else
DocInfo.WSPart.Worksheet.Append(XLegacyDrawing)
End If

VB.Net signedXml "Invalid character in a Base-64 string"

I'm getting an error everytime I try to upload a XML file to an specific server.
It returns "Invalid character in a Base-64 string". Here the code I'm using to sign:
Public Sub Assinar03(ByVal strArqXMLAssinar As String, ByVal strUri As String, ByVal x509Certificado As X509Certificate2, ByVal strArqXMLAssinado As String)
Dim SR As StreamReader = Nothing
SR = File.OpenText(strArqXMLAssinar)
Dim vXMLString As String = SR.ReadToEnd()
SR.Close()
Dim _xnome As String = String.Empty
Dim _serial As String = String.Empty
If x509Certificado IsNot Nothing Then
_xnome = x509Certificado.Subject.ToString()
_serial = x509Certificado.SerialNumber
End If
Dim _X509Cert As New X509Certificate2()
Dim store As New X509Store("MY", StoreLocation.CurrentUser)
store.Open(OpenFlags.[ReadOnly] Or OpenFlags.OpenExistingOnly)
Dim collection As X509Certificate2Collection = DirectCast(store.Certificates, X509Certificate2Collection)
Dim collection1 As X509Certificate2Collection = DirectCast(collection.Find(X509FindType.FindBySerialNumber, _serial, False), X509Certificate2Collection)
If collection1.Count > 0 Then
_X509Cert = Nothing
For i As Integer = 0 To collection1.Count - 1
If DateTime.Now < collection1(i).NotAfter OrElse Not _X509Cert Is Nothing AndAlso _X509Cert.NotAfter < collection1(i).NotAfter Then
_X509Cert = collection1(i)
End If
Next
If _X509Cert Is Nothing Then _X509Cert = collection1(0)
Dim doc As New XmlDocument()
doc.PreserveWhitespace = False
doc.LoadXml(vXMLString)
Dim qtdeRefUri As Integer = doc.GetElementsByTagName(strUri).Count
Dim reference As New Reference()
Dim keyInfo As New KeyInfo()
Dim signedXml As New SignedXml(doc)
signedXml.SigningKey = _X509Cert.PrivateKey
Dim _Uri As XmlAttributeCollection = doc.GetElementsByTagName(strUri).Item(0).Attributes
For Each _atributo As XmlAttribute In _Uri
If _atributo.Name.ToLower.Trim = "Id".ToLower.Trim Then
reference.Uri = "#" + _atributo.InnerText
End If
Next
If reference.Uri Is Nothing Then reference.Uri = ""
reference.DigestMethod = SignedXml.XmlDsigSHA1Url
'--------------------------------------------------
Dim env As New XmlDsigEnvelopedSignatureTransform()
env.Algorithm = "http://www.w3.org/2000/09/xmldsig#enveloped-signature"
reference.AddTransform(env)
'--------------------------
Dim c14 As New XmlDsigC14NTransform(False)
c14.Algorithm = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315"
reference.AddTransform(c14)
'--------------------------
signedXml.AddReference(reference)
keyInfo.AddClause(New KeyInfoX509Data(_X509Cert))
'--------------------------
signedXml.KeyInfo = keyInfo
signedXml.ComputeSignature()
'--
Dim xmlDigitalSignature As XmlElement = signedXml.GetXml()
doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, True))
XMLDoc = New XmlDocument()
XMLDoc.PreserveWhitespace = False
XMLDoc = doc
Me.vXMLStringAssinado = XMLDoc.OuterXml
'-----------
Dim SW_2 As StreamWriter = File.CreateText(strArqXMLAssinado)
SW_2.Write(Me.vXMLStringAssinado)
SW_2.Close()
'-----------
End If
SR.Close()
End Sub
Is there something else I should add to the code?
The manual tells me to follow the instructions from https://www.w3.org/TR/xmldsig-core/
Turns out it was a line break when saving the document. I set the .PreserveWhitespace property to true before saving the .xml file and not it seems to be working.

Cannot read file from disk

When I upload an excel file from my vb app, it's fine for the first time. If I try it a second time I am having this error: The process cannot access the file (path) because it is bein used by another process. Below is my code:
Dim fd As OpenFileDialog = New OpenFileDialog()
fd.Title = "Open File Dialog"
fd.InitialDirectory = "C:\"
fd.Filter = "All files (*.xlsx)|*.xlsx|All files (*.xlsx)|*.xlsx"
fd.FilterIndex = 2
fd.RestoreDirectory = True
Dim myStream As Stream = Nothing
If fd.ShowDialog() = DialogResult.OK Then
Try
myStream = fd.OpenFile()
If (myStream IsNot Nothing) Then
workbook = APP.Workbooks.Open(fd.FileName)
worksheet = workbook.Worksheets("sheet1")
TextBox1.Text = worksheet.Cells(1, 7).Value
TextBox2.Text = worksheet.Cells(2, 7).Value
TextBox3.Text = worksheet.Cells(3, 7).Value
l1.Text = worksheet.Cells(2, 1).Value * 10
w1.Text = worksheet.Cells(2, 2).Value * 10
q1.Text = worksheet.Cells(2, 3).Value
p1.Text = worksheet.Cells(2, 4).Value..........
Dim Values(119, 3) As String
Values(0, 0) = l1.Text
Values(0, 1) = w1.Text
Values(0, 2) = q1.Text
Values(0, 3) = p1.Text.........
Dim add As Integer = 0
Dim pressing As Integer = 0
If adding.Text = "50" Or adding.Text = "" Then
add = 50
Else
add = Convert.ToInt16(adding.Text)
End If
If press.Text = "20" Or press.Text = "" Then
pressing = 20
Else
pressing = Convert.ToInt16(press.Text)
End If
Dim l As Integer
Dim w As Integer
Dim machinearea As Integer
Dim connetionString As String
Dim cnn As SqlConnection
connetionString = "Data Source=.;Initial Catalog=lumber;User ID=sa;Password=sasql"
cnn = New SqlConnection(connetionString)
Dim cmd As SqlCommand
Dim myreader As SqlDataReader
Dim query As String
query = "SELECT length,width from marea"
cmd = New SqlCommand(query, cnn)
cnn.Open()
myreader = cmd.ExecuteReader()
If myreader.Read() Then
l = myreader.Item("length")
w = myreader.Item("width")
End If
cnn.Close()
machinearea = l * w
Dim allTextBoxes2 = From txt In Me.Panel1.Controls.OfType(Of TextBox)()
Order By txt.TabIndex
Dim txtList2 = allTextBoxes2.ToList()
For i As Int32 = 0 To txtList2.Count - 1
Dim thisTxt = txtList2(i)
Dim nextIndex = If(i + 1 >= txtList2.Count, 0, i + 1)
Dim prevIndex = If(i - 1 < 0, txtList2.Count - 1, i - 1)
Dim nextTxt = txtList2(nextIndex)
Dim prevTxt = txtList2(prevIndex)
Dim testInt As Integer = 0
If thisTxt.Text = "0" Then
thisTxt.Clear()
End If
Next
Dim allTextBoxes = From txt In Me.Panel1.Controls.OfType(Of TextBox)()
Order By txt.TabIndex
Dim txtList = allTextBoxes.ToList()
For i As Int32 = 0 To txtList.Count - 1
Dim thisTxt = txtList(i)
For j = 2 To -1
For k = 1 To 4
thisTxt.Text = worksheet.Cells(i + j, k).Value
Next
Next
Next
End If
Catch Ex As Exception
MessageBox.Show("Cannot read file from disk. Original error: " & Ex.Message)
Finally
' Check this again, since we need to make sure we didn't throw an exception on open.
If (myStream IsNot Nothing) Then
myStream.Close()
End If
End Try
End If
Try
myStream = fd.OpenFile()
If (myStream IsNot Nothing) Then
workbook = APP.Workbooks.Open(fd.FileName, ReadOnly:=True, Notify:=False)
worksheet = workbook.Worksheets("sheet1")
...
Finally
' Check this again, since we need to make sure we didn't throw an exception on open.
If (myStream IsNot Nothing) Then
myStream.Close()
End If
If (workbook IsNot Nothing) Then
workbook.Close()
End If
End Try
Make sure the application is closed and no process is running or it will give you that error.

system.io.ioexception the process cannot access because it is being used by another process

i am getting this problem in some systems, some systems working properly, here my code is,
Dim fileName As String = "FaultTypesByMonth.csv"
Using writer As IO.StreamWriter = New IO.StreamWriter(fileName, True, System.Text.Encoding.Default) '------------ rao new ----
Dim Str As String
Dim i As Integer
Dim j As Integer
Dim headertext1(rsTerms.Columns.Count) As String
Dim k As Integer = 0
Dim arrcols As String = Nothing
For Each column As DataColumn In TempTab.Columns
arrcols += column.ColumnName.ToString() + ","c
k += 1
Next
writer.WriteLine(arrcols)
For i = 0 To (TempTab.Rows.Count - 1)
For j = 0 To (TempTab.Columns.Count - 1)
If j = (TempTab.Columns.Count - 1) Then
Str = (TempTab.Rows(i)(j).ToString)
Else
Str = (TempTab.Rows(i)(j).ToString & ",")
End If
writer.Write(Str)
Next
writer.WriteLine()
Next
writer.Close()
writer.Dispose()
End Using
Dim FileToDelete As String = Nothing
Dim sd As New SaveFileDialog
sd.Filter = "CSV Files (*.csv)|*.csv"
sd.FileName = "FaultTypesByMonth"
If sd.ShowDialog = Windows.Forms.DialogResult.OK Then
FileCopy(fileName, sd.FileName)
MsgBox(" File Saved in selected path")
FileToDelete = fileName
If System.IO.File.Exists(FileToDelete) = True Then
System.IO.File.Delete(FileToDelete)
End If
End If
FileToDelete = fileName
If System.IO.File.Exists(FileToDelete) = True Then
System.IO.File.Delete(FileToDelete)
End If
when i am trying to save this file in desired path, then i am getting this error.
if save in shared folder i am not getting this error
system.io.ioexception the process cannot access because it is being used by another process...
what i am doing wrong,Help me

Creating a DataGridView Programatically and add clickable cells

Evening
I am struggling to achieve what I have set out todo! In a nutshell I am working with the Google Drive API to create an app in VB.net that allows you to view / download files etc.
Basically I am planning on using a couple of different api's for the different cloud provider s I have. The stage I have got to is that I have my collection of files and there various properties in a list. On load I am checking to see if a google account has been added to my program and if so creating a new tabpage on a tabcontrol, I then create the datagridview and add it to the collection on the new tab page. This works fine and displays all my data as is.
What I am trying to achieve is adding a clickable link to my download column instead of displaying the url. I have been trying to manipulate the code found here C# DataGridViewLinkCell Display after converting it to vb.net. This is basically what I have ended up with:
If My.Settings.GoogleClientID <> "" Then
Dim GD As New Properties.GDrive
GD.APIClientID = My.Settings.GoogleClientID
GD.APIClientSecret = My.Settings.GoogleClientSecret
clsDrive.GD = GD
clsDrive.GetSpace()
clsDrive.RefreshFiles()
Dim GoogleDriveTab As New TabPage
GoogleDriveTab.Text = "Google Drive"
tc_CloudManager.TabPages.Add(GoogleDriveTab)
Dim GoogleDriveDGV As New DataGridView
GoogleDriveDGV.Name = "GoogleDriveDGV"
GoogleDriveDGV.Dock = DockStyle.Fill
GoogleDriveDGV.Columns.Add("FileTitle", "File Title")
GoogleDriveDGV.Columns.Add("FileExtension", "File Extension")
GoogleDriveDGV.Columns.Add("FileSize", "File Size")
Dim dgvlc As New DataGridViewLinkColumn()
dgvlc.ActiveLinkColor = Color.Blue
dgvlc.HeaderText = "Download"
GoogleDriveDGV.Columns.Add(dgvlc)
GoogleDriveDGV.RowHeadersVisible = False
Dim c As New customcolumn()
GoogleDriveDGV.Columns.Add(c)
For i As Integer = 0 To GoogleDriveDGV.Columns.Count - 1
GoogleDriveDGV.Columns(i).AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells
Next
Try
For Each DriveFile In GD.DriveFiles
Dim row As DataGridViewRow = DirectCast(GoogleDriveDGV.Rows(0).Clone, DataGridViewRow)
Dim title As String = DriveFile.Title
If title.Length > 60 Then
title = title.Substring(0, 60)
End If
Dim fs As Integer = DriveFile.FileSize
Dim fsf As String
If fs > 1048576 Then
fsf = Math.Round(fs / 1048576, 2) & " MB"
Else
fsf = fs & " Bytes"
End If
Dim fe As String
If DriveFile.FileExtension = "" Then
fe = "Folder"
Else
fe = DriveFile.FileExtension
End If
row.Cells(0).Value = title
row.Cells(1).Value = fe
row.Cells(2).Value = fsf
row.Cells(3).Value = "Download File"
DirectCast(GoogleDriveDGV.Columns(3), customcolumn).urls.Add(3, DriveFile.DownloadUrl)
Next
Catch ex As Exception
MsgBox(ex.ToString)
End Try
GoogleDriveTab.Controls.Add(GoogleDriveDGV)
End If
End Sub
Class customcolumn
Inherits System.Windows.Forms.DataGridViewLinkColumn
Public urls As New Dictionary(Of Integer, String)()
End Class
Private Sub GoogleDriveDGV_CellContentClick(ByVal sender As Object, ByVal e As DataGridViewCellEventArgs)
For Each url As KeyValuePair(Of Integer, String) In DirectCast(GoogleDriveDGV.Columns(e.ColumnIndex), customcolumn).urls
If url.Key = e.RowIndex Then
Process.Start(url.Value)
Exit For
End If
Next
End Sub
I have two problems that I cant figure out:
1) GoogleDriveDGV is not declared here : For Each url As KeyValuePair(Of Integer, String) In DirectCast(GoogleDriveDGV.Columns(e.ColumnIndex), customcolumn).urls
2) If I comment out the GoogleDriveDGV_CellContentClick sub and just try to populate the datagridview I get System.InvalidCastException: Unable to cast object of type 'System.Windows.Forms.DataGridViewLinkColumn' to type 'customcolumn' here DirectCast(GoogleDriveDGV.Columns(3), customcolumn).urls.Add(3, DriveFile.DownloadUrl)
Can anyone let me know if what I am trying to achieve is possible and any hints?
Update!!!
I now have this:
If My.Settings.GoogleClientID <> "" Then
Dim GD As New Properties.GDrive
GD.APIClientID = My.Settings.GoogleClientID
GD.APIClientSecret = My.Settings.GoogleClientSecret
clsDrive.GD = GD
clsDrive.GetSpace()
clsDrive.RefreshFiles()
Dim GoogleDriveTab As New TabPage
GoogleDriveTab.Text = "Google Drive"
tc_CloudManager.TabPages.Add(GoogleDriveTab)
Dim GoogleDriveDGV As New DataGridView
GoogleDriveDGV.Name = "GoogleDriveDGV"
GoogleDriveDGV.Dock = DockStyle.Fill
GoogleDriveDGV.Columns.Add("FileTitle", "File Title")
GoogleDriveDGV.Columns.Add("FileExtension", "File Extension")
GoogleDriveDGV.Columns.Add("FileSize", "File Size")
Dim c As New customcolumn()
GoogleDriveDGV.Columns.Add(c)
GoogleDriveDGV.RowHeadersVisible = False
For i As Integer = 0 To GoogleDriveDGV.Columns.Count - 1
GoogleDriveDGV.Columns(i).AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells
Next
Dim trow As Integer = 0
Try
For Each DriveFile In GD.DriveFiles
Dim row As DataGridViewRow = DirectCast(GoogleDriveDGV.Rows(0).Clone, DataGridViewRow)
Dim title As String = DriveFile.Title
If title.Length > 60 Then
title = title.Substring(0, 60)
End If
Dim fs As Integer = DriveFile.FileSize
Dim fsf As String
If fs > 1048576 Then
fsf = Math.Round(fs / 1048576, 2) & " MB"
Else
fsf = fs & " Bytes"
End If
Dim fe As String
If DriveFile.FileExtension = "" Then
fe = "Folder"
Else
fe = DriveFile.FileExtension
End If
row.Cells(0).Value = title
row.Cells(1).Value = fe
row.Cells(2).Value = fsf
row.Cells(3).Value = "Download"
DirectCast(GoogleDriveDGV.Columns(3), customcolumn).urls.Add(trow, DriveFile.DownloadUrl)
GoogleDriveDGV.Rows.Add(row)
trow = trow + 1
Next
Catch ex As Exception
MsgBox(ex.ToString)
End Try
GoogleDriveTab.Controls.Add(GoogleDriveDGV)
End If
End Sub
Class customcolumn
Inherits System.Windows.Forms.DataGridViewLinkColumn
Public urls As New Dictionary(Of Integer, String)()
End Class
'Private Sub GoogleDriveDGV_CellContentClick(ByVal sender As Object, ByVal e As DataGridViewCellEventArgs)
' For Each url As KeyValuePair(Of Integer, String) In DirectCast(GoogleDriveDGV.Columns(e.ColumnIndex), customcolumn).urls
' If url.Key = e.RowIndex Then
' Process.Start(url.Value)
' Exit For
' End If
' Next
'End Sub
Which is almost there, I now have the datagridview filled with the items and a download link, just cant work out how to solve issue 1 above :-(
Would you believe it I worked it out :-)
Basically I needed to add a handler.
Full code:
Private Sub CloudManager_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
If My.Settings.GoogleClientID <> "" Then
Dim GD As New Properties.GDrive
GD.APIClientID = My.Settings.GoogleClientID
GD.APIClientSecret = My.Settings.GoogleClientSecret
clsDrive.GD = GD
clsDrive.GetSpace()
clsDrive.RefreshFiles()
Dim GoogleDriveTab As New TabPage
GoogleDriveTab.Text = "Google Drive"
tc_CloudManager.TabPages.Add(GoogleDriveTab)
Dim GoogleDriveDGV As New DataGridView
GoogleDriveDGV.Name = "GoogleDriveDGV"
GoogleDriveDGV.Dock = DockStyle.Fill
GoogleDriveDGV.Columns.Add("FileTitle", "File Title")
GoogleDriveDGV.Columns.Add("FileExtension", "File Extension")
GoogleDriveDGV.Columns.Add("FileSize", "File Size")
Dim c As New customcolumn()
GoogleDriveDGV.Columns.Add(c)
AddHandler GoogleDriveDGV.CellContentClick, AddressOf GoogleDriveDGV_CellContentClick
GoogleDriveDGV.RowHeadersVisible = False
For i As Integer = 0 To GoogleDriveDGV.Columns.Count - 1
GoogleDriveDGV.Columns(i).AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells
Next
Dim trow As Integer = 0
Try
For Each DriveFile In GD.DriveFiles
Dim row As DataGridViewRow = DirectCast(GoogleDriveDGV.Rows(0).Clone, DataGridViewRow)
Dim title As String = DriveFile.Title
If title.Length > 60 Then
title = title.Substring(0, 60)
End If
Dim fs As Integer = DriveFile.FileSize
Dim fsf As String
If fs > 1048576 Then
fsf = Math.Round(fs / 1048576, 2) & " MB"
Else
fsf = fs & " Bytes"
End If
Dim fe As String
If DriveFile.FileExtension = "" Then
fe = "Folder"
Else
fe = DriveFile.FileExtension
End If
row.Cells(0).Value = title
row.Cells(1).Value = fe
row.Cells(2).Value = fsf
row.Cells(3).Value = "Download"
DirectCast(GoogleDriveDGV.Columns(3), customcolumn).urls.Add(trow, DriveFile.DownloadUrl)
GoogleDriveDGV.Rows.Add(row)
trow = trow + 1
Next
Catch ex As Exception
MsgBox(ex.ToString)
End Try
GoogleDriveTab.Controls.Add(GoogleDriveDGV)
End If
End Sub
Class customcolumn
Inherits System.Windows.Forms.DataGridViewLinkColumn
Public urls As New Dictionary(Of Integer, String)()
End Class
Private Sub GoogleDriveDGV_CellContentClick(ByVal sender As Object, ByVal e As DataGridViewCellEventArgs)
For Each url As KeyValuePair(Of Integer, String) In DirectCast(sender.Columns(e.ColumnIndex), customcolumn).urls
If url.Key = e.RowIndex Then
Process.Start(url.Value)
Exit For
End If
Next
End Sub
End Class