I have an (unregistered) DLL which I could access in VBA as follows:
Declare Function IBarcodeReader Lib "C:\Users\myname\Downloads\interop\zxing.dll" () As Long
Problem is, that this works for functions/subs, but I want to access a class contained in the DLL.
Background:
Trying to read QRCodes embedded in a pdf. Will convert PDF to Bitmap and then use the following library in VBA:
https://github.com/micjahn/ZXing.Net
Function Decode_QR_Code_From_File()
Dim reader As IBarcodeReader
Dim res As Result
Set reader = New BarcodeReader
reader.options.PossibleFormats.Add BarcodeFormat_QR_CODE
Set res = reader.DecodeImageFile("D:\Barcodes\QrCodes\www.png")
End Function
.
Function Decode_QR_Code_From_Byte_Array()
Dim reader As IBarcodeReader
Dim rawRGB(1000) As Byte
Dim res As Result
Set reader = New BarcodeReader
reader.options.PossibleFormats.Add BarcodeFormat_QR_CODE
Rem TODO: load bitmap data to byte array rawRGB
Set res = reader.DecodeImageBytes(rawRGB, 10, 10, BitmapFormat.BitmapFormat_Gray8)
End Function
.
Function Encode_To_QR_Code_To_File()
Dim writer As IBarcodeWriter
Dim qrCodeOptions As QrCodeEncodingOptions
Dim pixelDataResult As PixelData
Set qrCodeOptions = New QrCodeEncodingOptions
Set writer = New BarcodeWriter
writer.Format = BarcodeFormat_QR_CODE
Set writer.options = qrCodeOptions
qrCodeOptions.Height = 100
qrCodeOptions.Width = 100
qrCodeOptions.CharacterSet = "UTF-8"
qrCodeOptions.Margin = 10
qrCodeOptions.ErrorCorrection = ErrorCorrectionLevel_H
writer.WritePngToFile "Test", "D:\interop_qrcode.png"
Rem Or:
Set pixelDataResult = writer.Write("Test")
End Function
.
Function Decode_QR_Code_From_File_CreateObject()
Dim reader As IBarcodeReader
Dim res As Result
Set reader = CreateObject("ZXing.Interop.Decoding.BarcodeReader")
reader.options.PossibleFormats.Add BarcodeFormat_QR_CODE
Set res = reader.DecodeImageFile("D:\Barcodes\QrCodes\www.png")
End Function
Source: Using ZXing.Net with VBA
Edit:
re: registering DLL to be able to use Class methods
Have a seen/tried these suggestions:
How to register a C# or VB.Net DLL
"Successfully registered COM DLL, but can't use class methods"
VBA importing COM-registered dll and calling constructor
The question is unnecessary when ZXing.Net is registered correctly. Using ZXing.Net with VBA describes now in detail how to register ZXing.Net for use with VBA.
Related
I'm trying to create a SHA256 object from MS Access VBA.
I'm running Access 2016 on a Windows machine with .NET 4.8.
Public Function Base64_HMACSHA256(ByVal sTextToHash As String, ByVal sSharedSecretKey As String) As String
Dim asc As Object, enc As Object
Dim TextToHash() As Byte
Dim SharedSecretKey() As Byte
Set asc = CreateObject("System.Text.UTF8Encoding")
'Set enc = CreateObject("System.Security.Cryptography.HMACSHA256") 'THIS SUCCESSFULLY CREATES THE OBJECT
'Set enc = CreateObject("System.Security.Cryptography.SHA256") 'IHF 02/03/22 'CAN'T CREATE OBJECT
'Set enc = CreateObject("System.Security.Cryptography.SHA256CryptoServiceProvider") 'IHF 02/03/22 'CAN'T CREATE OBJECT
'Set enc = CreateObject("System.Security.Cryptography.RSACryptoServiceProvider") 'CAN'T CREATE OBJECT
TextToHash = asc.Getbytes_4(sTextToHash)
SharedSecretKey = asc.Getbytes_4(sSharedSecretKey)
enc.Key = SharedSecretKey
Dim bytes() As Byte
bytes = enc.ComputeHash_2((TextToHash))
Base64_HMACSHA256 = EncodeBase64(bytes)
Set asc = Nothing
Set enc = Nothing
End Function
I ended up doing it all a totally different way, so I never figured this out.
The appropriate class, as noted in the comments, is System.Security.Cryptography.SHA256Managed. Wikibooks has an example.
However, I prefer using the WinAPI CNG api directly (docs). This has some flexibility, performance and security advant.ages. See an example
i'm trying to follow this example to create PDF with an image
Example PDF with an Image
I'm developing with VS2013 in VB.NET (ASP.NET 3.5).
I'm getting crazy, i don't understand 2 things:
what is the name that i've to pass in the IMG tag.
The src-attribute doesn´t contain a http-Url. Instead use the prefix data:imagestream to identify the source type of the image. After the following slash the name of the resource in the manifest of the .NET library is listed.
when the END ovveride function in CustomImageTagProcessor Class is executed
I've embedded an image in the project and the manifest contains
...
}
.mresource public Test1.phone.jpg
{
// Offset: 0x00000000 Length: 0x00003E0D
}
.mresource public Test1.Resources.resources
{
// Offset: 0x00003E11 Length: 0x0000406B
}
I'm debugging step by step but never the code in the ovverride function is executed.
This is the function that produce PDF
Public Function CreateFromHtml(ByVal html As String) As Stream
Dim stream = New MemoryStream()
Using doc = New Document(PageSize.A4)
Using ms = New MemoryStream()
Using writer = PdfWriter.GetInstance(doc, ms)
writer.CloseStream = False
doc.Open()
Dim tagProcessors = CType(Tags.GetHtmlTagProcessorFactory(), DefaultTagProcessorFactory)
tagProcessors.RemoveProcessor(iTextSharp.tool.xml.html.HTML.Tag.IMG)
tagProcessors.AddProcessor(iTextSharp.tool.xml.html.HTML.Tag.IMG, New CustomImageTagProcessor())
Dim cssFiles = New CssFilesImpl()
cssFiles.Add(XMLWorkerHelper.GetInstance().GetDefaultCSS())
Dim cssResolver = New StyleAttrCSSResolver(cssFiles)
Dim charset = Encoding.UTF8
Dim context = New HtmlPipelineContext(New CssAppliersImpl(New XMLWorkerFontProvider()))
context.SetAcceptUnknown(True).AutoBookmark(True).SetTagFactory(tagProcessors)
Dim htmlPipeline = New HtmlPipeline(context, New PdfWriterPipeline(doc, writer))
Dim cssPipeline = New CssResolverPipeline(cssResolver, htmlPipeline)
Dim worker = New XMLWorker(cssPipeline, True)
Dim xmlParser = New XMLParser(True, worker, charset)
Using sr = New StringReader(html)
xmlParser.Parse(sr)
doc.Close()
ms.Position = 0
ms.CopyTo(stream)
stream.Position = 0
End Using
End Using
End Using
End Using
Return stream
End Function
And this is the Class of CustomImageTagProcessor
Imports iTextSharp.tool.xml
Imports System.Reflection
Imports iTextSharp.text
Public Class CustomImageTagProcessor
Inherits iTextSharp.tool.xml.html.Image
Public Overrides Function [End](ByVal ctx As IWorkerContext, ByVal tag As Tag, ByVal currentContent As IList(Of IElement)) As IList(Of IElement)
Dim src = String.Empty
If Not tag.Attributes.TryGetValue(iTextSharp.tool.xml.html.HTML.Attribute.SRC, src) Then Return New List(Of IElement)(1)
If String.IsNullOrEmpty(src) Then Return New List(Of IElement)(1)
If src.StartsWith("data:imagestream/", StringComparison.InvariantCultureIgnoreCase) Then
Dim name = src.Substring(src.IndexOf("/", StringComparison.InvariantCultureIgnoreCase) + 1)
Using stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(name)
Return CreateElementList(ctx, tag, Image.GetInstance(stream))
End Using
End If
Return MyBase.[End](ctx, tag, currentContent)
End Function
Protected Function CreateElementList(ByVal ctx As IWorkerContext, ByVal tag As Tag, ByVal image As Image) As IList(Of IElement)
Dim htmlPipelineContext = GetHtmlPipelineContext(ctx)
Dim result = New List(Of IElement)()
Dim element = GetCssAppliers().Apply(New Chunk(CType(GetCssAppliers().Apply(image, tag, htmlPipelineContext), Image), 0, 0, True), tag, htmlPipelineContext)
result.Add(element)
Return result
End Function
End Class
Thanks so much for any helps.
I hope in you guys.
The problem was a lost
</img>
tag
Self Closed tag is not valid.
When i put tag also code inside overrided function has been executed.
Thanks so much.
I am trying to compile a VB program using the code below, the code requires VB 15.5 and even when I specify LanguageVersion.Latest or LanguageVersion.VisualBasic15_5, I still get error ERR_ExpectedNamedArgument - Named argument expected. Please use language version 15.5 or greater to use non-trailing named arguments. Some code was removed to simplify example.
Public Function CompileVisualBasicString(StringToBeCompiler As String, SeverityToReport As DiagnosticSeverity, ByRef ResultOfConversion As ConversionResult) As EmitResult
If StringToBeCompiler.IsEmptyNullOrWhitespace Then
ResultOfConversion.FilteredListOfFailures = New List(Of Diagnostic)
ResultOfConversion.Success = True
Return Nothing
End If
Dim syntaxTree As SyntaxTree = VisualBasicSyntaxTree.ParseText(StringToBeCompiler)
Dim assemblyName As String = Path.GetRandomFileName()
Dim PreprocessorSymbols As New Dictionary(Of String, Object) From {
{"NETSTANDARD2_0", Nothing}
}
Dim ParseOptions As VisualBasicParseOptions = New VisualBasicParseOptions(
languageVersion:=LanguageVersion.Latest,
documentationMode:=DocumentationMode.Diagnose,
kind:=SourceCodeKind.Regular,
preprocessorSymbols:=PreprocessorSymbols)
Dim CompilationOptions As VisualBasicCompilationOptions = New VisualBasicCompilationOptions(
outputKind:=OutputKind.DynamicallyLinkedLibrary,
optionExplicit:=False,
optionInfer:=True,
optionStrict:=OptionStrict.Off,
parseOptions:=ParseOptions
)
Dim compilation As VisualBasicCompilation = VisualBasicCompilation.Create(
assemblyName:=assemblyName,
syntaxTrees:={syntaxTree},
references:=References,
options:=CompilationOptions
)
Dim CompileResult As EmitResult
Using ms As MemoryStream = New MemoryStream()
CompileResult = compilation.Emit(ms)
End Using
Return CompileResult
End Function
Thank you George, you solved the problem I needed to include the VisualBasicParseOption to Parse in addition to compile.
I'm basically writing a custom Error Logging Form for one of my applications because users cannot be trusted to report the errors to me.
I am obtaining the Form Name using the 'MethodBase' Object and then getting the DeclaringType Name.
Dim st As StackTrace = New StackTrace()
Dim sf As StackFrame = st.GetFrame(1)
Dim mb As MethodBase = sf.GetMethod()
Dim dt As String = mb.DeclaringType.Name
How can I then use this to obtain the Form Object so I can pass this to my 'screenshot method' that screenshots the particular form referenced.
Public Sub SaveAsImage(frm As Form)
'Dim fileName As String = "sth.png"
'define fileName
Dim format As ImageFormat = ImageFormat.Png
Dim image = New Bitmap(frm.Width, frm.Height)
Using g As Graphics = Graphics.FromImage(image)
g.CopyFromScreen(frm.Location, New Point(0, 0), frm.Size)
End Using
image.Save(_LogPath & Date.Now.ToString("ddMMyyyy") & ".png", format)
End Sub
I posted the same solution to a similar question. Try this:
Dim frm = Application.OpenForms.Item(dt)
I want to get just one file from .zip file in VB.NET. I don't need to extract all of .zip file, just one file.
I'm working with framework 4.5.
.NET Framework 4.5 has ZipFile class which can do this for you. This code should get you started:
Dim zipPath As String = "Sample.zip"
Using archive = ZipFile.Open(zipPath, ZipArchiveMode.Read)
Dim entry = archive.GetEntry("MyFile.pdf")
Using reader As New BinaryReader(entry.Open())
System.IO.File.WriteAllBytes("MyFile.pdf", ReadAllBytes(reader))
End Using
End Using
ReadAllBytes() is a helper method that fetches all bytes from a binary stream:
Public Shared Function ReadAllBytes(reader As BinaryReader) As Byte()
Const bufferSize As Integer = 4096
Using ms As New MemoryStream()
Dim buffer(bufferSize) As Byte
Dim count As Integer
Do
count = reader.Read(buffer, 0, buffer.Length)
If count > 0 Then ms.Write(buffer, 0, count)
Loop While count <> 0
Return ms.ToArray()
End Using
End Function
Make sure you're using .NET Framework 4.5 or above and that you have included references to System.IO.Compression and System.IO.Compression.FileSystem.
try with this code with the help of DotNetZip
Using zip As ZipFile = ZipFile.Read(ExistingZipFile)
Dim e As ZipEntry = zip("DocumentToFind.txt")
e.Extract(OutputStream)
End Using
otherwise you can use ZipArchiveClass in this way
Using zip As ZipArchive = ZipFile.Open(zipfile, ZipArchiveMode.Read)
Dim file = zip.Entries.Where(Function(x) x.Name = "fileToFind")
If file IsNot Nothing Then
file.ExtractToFile("yourFile")
End If
End Using
This will allow you to read txt files from a zip line by line
Dim zipPath As String = "ZIP FILE LOCATION"
Using zipStream = New FileStream(last_pafx23_open, FileMode.Open)
Using archive = New ZipArchive(zipStream, ZipArchiveMode.Read)
For Each ent In archive.Entries
MsgBox(ent.ToString)
Using stream = ent.Open()
Using reader = New StreamReader(stream)
While Not reader.EndOfStream
MsgBox(reader.ReadLine)
End While
End Using
End Using
Next
End Using
End Using
Skip the BinaryReader w/ ReadAllBytes() helper function, use ExtractToFile() instead:
Imports System.IO.Compression
Using archive = ZipFile.Open("Sample.zip", ZipArchiveMode.Read)
Dim entry = archive.GetEntry("MyFile.pdf")
If entry IsNot Nothing then entry.ExtractToFile("MyFile.pdf")
End Using
Still needs the references to System.IO.Compression and System.IO.Compression.FileSystem, of course.