.NET Framework Interop (CLR, C#, VB)
Re: .NET Framework Interop (CLR, C#, VB)
Can I inquire why you need that library to work with html?
Re: .NET Framework Interop (CLR, C#, VB)
I wonder if ComObjCreate("HTMLFile") is reliable, due to different IE browser version. Although I have a function like this:
Code: Select all
html2dom(ByRef html, RemoveHeadAndImg = true)
{
if RemoveHeadAndImg {
html := RegExReplace(html, "`as)<head>.*?</head>")
html := RegExReplace(html, "<img .*?>")
}
html := "<!doctype html><meta http-equiv=""X-UA-Compatible"" content=""IE=edge"">" . html
static doc := ComObjCreate("HTMLFile")
doc.open()
doc.write(html)
doc.close()
While !(doc.Readystate = "Complete")
Sleep, 10
return doc
}
Re: .NET Framework Interop (CLR, C#, VB)
I would think that should cover most use cases. Otherwise, you'll just have to code around certain DOM methods not being available on lower IE versions.
Re: .NET Framework Interop (CLR, C#, VB)
Define "work" and "doesn't work".tmplinshi wrote:Can someone tell me why this doesn't work?
I assume an XDocument is an object, not a string or number, and therefore will show nothing in the MsgBox even if the script is successful.
Re: .NET Framework Interop (CLR, C#, VB)
The error message is in Chinese language, so I didn't include the message, my bad, I was too lazy.
I have changed the OS language to English, the error was:
Edit: wait, why the error is from Source: mscorlib but not Gumbo.Bindings.dll?
I have changed the OS language to English, the error was:
The error was caused by the 3rd line:---------------------------
gumbo test.ahk
---------------------------
Error in #include file "D:\code\AutoHotkey\Lib\Clr.ahk":
0x80131513 -
Source: mscorlib
Description: Constructor on type 'Gumbo.Wrappers.GumboWrapper' not found.
HelpFile: (null)
HelpContext: 0
Specifically: CreateInstance_3
Line#
029: }
032: {
033: if !(argCount := Args.MaxIndex())
034: Return,Assembly.CreateInstance_2(TypeName, true)
036: vargs := ComObjArray(0xC, argCount)
037: Loop,argCount
038: vargs[A_Index-1] := Args[A_Index]
---> 042: Return,Assembly.CreateInstance_3(TypeName, true, 0, null, vargs, null, Array_Empty)
043: }
046: {
047: Return,CLR_CompileAssembly(Code, References, "System", "Microsoft.CSharp.CSharpCodeProvider", AppDomain, FileName, CompilerOptions)
048: }
051: {
052: Return,CLR_CompileAssembly(Code, References, "System", "Microsoft.VisualBasic.VBCodeProvider", AppDomain, FileName, CompilerOptions)
053: }
Continue running the script?
---------------------------
Yes No
---------------------------
Code: Select all
testHtml := "<html><body class=""gumbo"">Boo!</body></html>"
GumboBindings := Clr_LoadLibrary("Gumbo.Bindings.dll")
gumbo := Clr_CreateObject(GumboBindings, "Gumbo.Wrappers.GumboWrapper", testHtml)
MsgBox, % gumbo.ToXDocument()
I am not sure but I guess XDocument is a string.https://github.com/rgripper/GumboBindings wrote:Console.WriteLine(gumbo.ToXDocument()); // to XDocument
Re: .NET Framework Interop (CLR, C#, VB)
It is XDocument, not String. I think it is not common C# practice to make simple type aliases, if such is even possible (like the C++ typedef). Even if the content of XDocument is text, at the very least it is an object which contains a string. If you can get the constructor call to work, you can probably verify the type of the object with ComObjType(xdoc, "Class"), or just call xdoc.ToString().
I believe the constructor you want to call is one with an optional parameter. I have not used C# since 2.0, and optional parameters were added in 4.0. I have read that COM callable wrappers support optional parameters, but in this case we are not calling that method directly; we are calling Assembly.CreateInstance_3 (3rd overload of CreateInstance). You probably need to specify all of the parameters, including the optional one, which I think can just be null (ComObject(13,0)).
I believe the constructor you want to call is one with an optional parameter. I have not used C# since 2.0, and optional parameters were added in 4.0. I have read that COM callable wrappers support optional parameters, but in this case we are not calling that method directly; we are calling Assembly.CreateInstance_3 (3rd overload of CreateInstance). You probably need to specify all of the parameters, including the optional one, which I think can just be null (ComObject(13,0)).
Re: .NET Framework Interop (CLR, C#, VB)
Thank you, lexikos. That is what I needed for EPPlus to get a chart onto a worksheet.
ComObject(13,0) was the missing parameter needed for the call.
This will help me out with this topic and the related topic here, where tmplinshi has been of invaluable assistance. I haven't gotten a series into the chart yet, but soon.You've provided a missing building block. Thanks again.
EDIT: Chart series now added also.
Regards,
burque505
ComObject(13,0) was the missing parameter needed for the call.
Code: Select all
chart := ws.Drawings.AddChart("Pie", 5, ComObject(13,0))
EDIT: Chart series now added also.
Regards,
burque505
Re: .NET Framework Interop (CLR, C#, VB)
Thanks lexikos! Good to know ComObject(13,0) for null parameters, that's a useful info for using CLR.ahk.
But adding to it, another error occurred
Code: Select all
gumbo := Clr_CreateObject(GumboBindings, "Gumbo.Wrappers.GumboWrapper", testHtml, ComObject(13, 0))
---------------------------
gumbo test.ahk
---------------------------
Error in #include file "D:\code\AutoHotkey\Lib\Clr.ahk":
0x80131604 -
Source: mscorlib
Description: Exception has been thrown by the target of an invocation.
HelpFile: (null)
HelpContext: 0
Specifically: CreateInstance_3
Line#
029: }
032: {
033: if !(argCount := Args.MaxIndex())
034: Return,Assembly.CreateInstance_2(TypeName, true)
036: vargs := ComObjArray(0xC, argCount)
037: Loop,argCount
038: vargs[A_Index-1] := Args[A_Index]
---> 042: Return,Assembly.CreateInstance_3(TypeName, true, 0, null, vargs, null, Array_Empty)
043: }
046: {
047: Return,CLR_CompileAssembly(Code, References, "System", "Microsoft.CSharp.CSharpCodeProvider", AppDomain, FileName, CompilerOptions)
048: }
051: {
052: Return,CLR_CompileAssembly(Code, References, "System", "Microsoft.VisualBasic.VBCodeProvider", AppDomain, FileName, CompilerOptions)
053: }
Continue running the script?
---------------------------
Yes No
---------------------------
Re: .NET Framework Interop (CLR, C#, VB)
An exception was thrown by the constructor. You probably can't call this constructor from unmanaged (COM) code. I'd guess that you can't use VT_UNKNOWN (13) for this null value since it is a nullable value type, not an object. You may need to use some helper code (C# or VB).
LayoutKind.Automatic
Indicates that the common language runtime is free to reorder the members of the type for efficiency. However, when a value type is passed to unmanaged code, the layout of the members is predictable. An attempt to marshal such a structure automatically causes an exception.
https://docs.microsoft.com/en-us/dotnet ... g-behavior
Re: .NET Framework Interop (CLR, C#, VB)
hmm.. that's difficult for me to continue, I'm giving up on this dll. Thanks again.
Re: .NET Framework Interop (CLR, C#, VB)
Sorry to flog a dead horse here, but I'm having trouble with such a number of third-party (i.e. non-Microsoft) DLLs that I'm still after information to solve this particular one. My hope is that whatever ends up solving this problem will help with my other problem Dlls (i.e. ClosedXml, OfficeOpenXml, SpreadsheetLight, DocX/Xceed.Words.Net, and several others. For all of these, I have tried VB.Net code, C# code, and Clr_LoadLibrary ()).
Using the same code tmplinshi does, i.e., I get this error output from the output window of Scite4Ahk after hitting "No" to continue running script:
I will be grateful for any help understanding this. I have followed through at this link, and have tried recompiling GumboWrappers.dll from source (epic fail, nearly 2000 errors in code on github when compiling with VS 2015 or VS 2017, including over 200 references to "dotnet5.4")). Is it possible the culprit is simply a bad GumboWrappers.DLL?
Regards,
burque505
Using the same code tmplinshi does, i.e.
Code: Select all
gumbo := Clr_CreateObject(GumboBindings, "Gumbo.Wrappers.GumboWrapper", testHtml, ComObject(13, 0))
Code: Select all
Unhandled Exception: System.BadImageFormatException: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)
at Gumbo.NativeMethods.gumbo_destroy_output(GumboOptions& options, IntPtr output)
at Gumbo.Wrappers.GumboWrapper.Dispose()
at Gumbo.Wrappers.GumboWrapper.Finalize()
Regards,
burque505
Re: .NET Framework Interop (CLR, C#, VB)
Probably the wrong .NET Framework version, or bitness (32-bit vs 64-bit, though I think some assemblies are both).
Re: .NET Framework Interop (CLR, C#, VB)
Thanks. I used dumpbin /headers to get the following info. Unless I'm mistaken, both dlls are 32-bit, and GumboBindings.dll was compiled against DotNet v4.52.
gumbo.dll
burque505
gumbo.dll
Spoiler
Gumbo.Bindings.dll
Spoiler
Regards,burque505
Re: .NET Framework Interop (CLR, C#, VB)
I have certainly seen instances where x64 AHK does not seem to like loading x86 DLLs, so further to what Lexikos said, if you haven't already, try x86 AHK
If memory serves actually, when I came across something similar, it was when my AHK code was loading my C# Interception wrapper via CLR, then my Interception wrapper invoked the unmanaged Interception DLL.
It turns out that if the bitness of that DLL did not match the bitness of AHK.... boom.
ie the GumboWrapper DLL may be AnyCPU, but the DLL that it is ultimately wrapping may not be, and I think needs to match the bitness of AHK.
FYI, link to the GumboWrapper ctor:
https://github.com/rgripper/GumboBindin ... per.cs#L46
Hope this helps
If memory serves actually, when I came across something similar, it was when my AHK code was loading my C# Interception wrapper via CLR, then my Interception wrapper invoked the unmanaged Interception DLL.
It turns out that if the bitness of that DLL did not match the bitness of AHK.... boom.
ie the GumboWrapper DLL may be AnyCPU, but the DLL that it is ultimately wrapping may not be, and I think needs to match the bitness of AHK.
FYI, link to the GumboWrapper ctor:
https://github.com/rgripper/GumboBindin ... per.cs#L46
Hope this helps
Re: .NET Framework Interop (CLR, C#, VB)
I appreciate the advice. The very first thing I did, when the OP on GumboBindings came out actually, was try x86 AHK, with no change in results at all. As the spoilers above show, both gumbo.dll and GumboBindings.dll are 32 bit, and GumboBindings.dll was compiled against dotnet 4.52.
It doesn't appear that GumboBindings.dll is maintained, both from the length of time since a commit and because the code contains literally hundreds of errors. [EDIT: I should say, hundreds of errors when compiled with VS 2017 or VS 2015 - more with one than the other, don't remember which had more. I don't have an earlier version of VS to test it, maybe it would compile fine with an earlier version.]
Also, the GumboBindings library itself loads without complaint. Here's the output from ComObjType for it:
I just can't create an object from the loaded library.
Regards,
burque505
It doesn't appear that GumboBindings.dll is maintained, both from the length of time since a commit and because the code contains literally hundreds of errors. [EDIT: I should say, hundreds of errors when compiled with VS 2017 or VS 2015 - more with one than the other, don't remember which had more. I don't have an earlier version of VS to test it, maybe it would compile fine with an earlier version.]
Also, the GumboBindings library itself loads without complaint. Here's the output from ComObjType for it:
Code: Select all
GumboBindings's class is Assembly
Name is _Assembly
CLSID is {28E89A9F-E67D-3028-AA1B-E5EBCDE6F3C8}
VT is 9
Regards,
burque505
Re: .NET Framework Interop (CLR, C#, VB)
In the Ctor, the 2nd param is a GumboWrapperOptions class, which is here: https://github.com/rgripper/GumboBindin ... per.cs#L11
Could you not create one of those? In HotVoice I have factory methods that return classes, and the AHK code can quite happily use these to new up a class, then set some properties etc, and pass it back to the C# code
Could you not create one of those? In HotVoice I have factory methods that return classes, and the AHK code can quite happily use these to new up a class, then set some properties etc, and pass it back to the C# code
Re: .NET Framework Interop (CLR, C#, VB)
Thanks, evilC, let me give that a try.
Re: .NET Framework Interop (CLR, C#, VB)
There is no 64-bit executable that can load a 32-bit dll for execution.evilC wrote:I have certainly seen instances where x64 AHK does not seem to like loading x86 DLLs,
There is no such class. It is a struct. I do not think you can pass this struct between managed and unmanaged code. See my previous post.evilC wrote:In the Ctor, the 2nd param is a GumboWrapperOptions class,
Re: .NET Framework Interop (CLR, C#, VB)
x64 Unicode AHK loads 32-bit EPPlus.dll fine.
HOWEVER: According to this page what lexikos says is 100% correct:
EDIT: This post describes workarounds and the interaction of IPC and COM. I wonder what is going on "under the hood" to allow me to run this 32-bit DLL with 64-bit AHK without (at least intentionally) any effort by me to provide for this functionality in my code.
What am I missing?
Regards,
burque505
Spoiler
Everything seen here and here runs with 64-bit AHK loading this 32-bit DLL. HOWEVER: According to this page what lexikos says is 100% correct:
I got the results in the spoiler following instructions here. Unless that's wrong, the DLL I'm using (which was compiled for "Any CPU"), is 32-bit.However, 32-bit processes cannot load 64-bit DLLs for execution, and 64-bit processes cannot load 32-bit DLLs for execution. This restriction does not apply to DLLs loaded as data files or image resource files; for more information, see LoadLibraryEx.
EDIT: This post describes workarounds and the interaction of IPC and COM. I wonder what is going on "under the hood" to allow me to run this 32-bit DLL with 64-bit AHK without (at least intentionally) any effort by me to provide for this functionality in my code.
What am I missing?
Regards,
burque505
Re: .NET Framework Interop (CLR, C#, VB)
CLR assemblies contain CLR IL code and metadata, not compiled machine code. Your file is neither 32-bit nor 64-bit.
Setting the target platform to something other than "Any CPU" only restricts how the file can be loaded. See Visual Studio .NET Platform Target Explained : Visual Studio Hacks.
Setting the target platform to something other than "Any CPU" only restricts how the file can be loaded. See Visual Studio .NET Platform Target Explained : Visual Studio Hacks.