Error 438 from using Filesystemobject.OpentTextFile but not on my computer - vb.net

Note: I'm new to using Visual Studio and writing code outside of VB6 and VBA. Also, I've resolved my problem by using IO.File.
However, I really want to learn why this wouldn't work:
Dim FSO As New FileSystemObject
Dim FSOts As TextStream
FSOts = FSO.OpenTextFile(filepath1, IOMode.ForReading, True)
While FSOts.AtEndOfStream = False
temp = FSOts.ReadLine()
MsgBox(temp)
tempcollection.Add(temp)
End While
FSOts.Close()
It works on my computer, but for some reason it won't on others. I've used this object in a vb script before but in that situation the 2nd argument was 'ForReading' and was written in a different IDE (FEMAP) which referenced the 32bit scrrun.dll. In Visual Studio I noticed the scripting library is pointing to syswow64; I'm not sure if that makes any difference. All distributed sites run 64 bit OS and have this library. In any case I get an error 438 when I try to use:
FSOts = FSO.OpenTextFile(filepath1, IOMode.ForReading, True)
VS will not let me compile it with just 'ForReading'.
Again, I've used this object before in vb6 but the 2nd argument was not iomode.forreading but 'ForReading'. In that situation it worked fine on the same machines that are giving me problems (except for mine of course!).

Related

Telling VBA to look at 64-bit registry view

I want to assign an ArrayList to a variable.
Sub Create_ArrayList()
Dim arrL As Object
'Creating an ArrayList, option 1 - fails
Set arrL = CreateObject("System.Collections.ArrayList")
'Creating an ArrayList, option 2 - fails
Set arrL = GetObject("New:{6896B49D-7AFB-34DC-934E-5ADD38EEEE39}")
End Sub
Both options fail :
Run-time error '-2146232576 (80131700)':
Automation error
I found that the CLSID exists in the registry in HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID
The Office is 32-bit and Windows is 64-bit. I am not familiar with the registry, but it seems from what I have read, that 32-bit Office is trying to find ArrayList in some 32-bit Windows location (view), while it actually is in 64-bit location. Can it be the case? How to make the application get ArrayList from the correct location?
It seems, to access an alternative registry view, I should somehow use the flag KEY_WOW64_64KEY (value 0x0100), but the examples that I found are too big to comprehend (eg1, eg2). I don't want to edit registry data, I only want to tell VBA that I am using 64-bit Windows, so the object that I need is to be found somewhere else than it expects.

VBA : Enexpected running VBA from cmd line

I wanted to open an existing ppt using Wscript and modify it. For that I am opening the file in visual studio editor and executing the script from cmd in windows using WScript hi.vbs
But when I ran the same code I am getting error.
Expected end of statement in line 4
Line 4 looks like Dim objNewPowerPoint As Object
However Same case works when I run code in excel VBA editor.
When I am removing the As object I am not getting any error nor any changes are happening in the PPT file.
Wondering what is the possible issue.
I am not using excel vba or word vba i am just running the file from cmd
Sub Open_an_existing_Presentations()
Dim objNewPowerPoint As Object
Dim MyPresentation As Object
Dim pSlides As Object
Set objNewPowerPoint = CreateObject(PowerPoint.Application)
'Make this Application Object Visible
objNewPowerPoint.Visible = True
Please help me how can i modify and more importantly how to see both errors compile and syntax.
FYI : I am completely new into VBA and I am trying to update a PPT and wanted to run vba script from another program so trying something like this. Best suggestions are always welcome
In VBScript you cannot dim something as something.
Dim objNewPowerPoint
Dim MyPresentation
Dim pSlides
And dim is optional and serves no technical purpose in VBS (it merely catches spelling mistakes if Option Explicit is specified, else it does nothing at all as in your case except take time to the process the line). In compiled languages it allocates storage and checks data types when using it.
When you use Set = VBS knows it an object and makes it one (4 x 32 bit integers - One a reference count and another a memory address of the function table for the object - two are unused). If you use x=5555 vbs knows it's a integer.

VBA office 2016 windows7/10 difference: Set IXMLDOMNodeList = DOMDocument60.childNodes

I've got an issue with a piece of VBA code that runs fine on a windows 7 machine, but doesn't work on windows 10. My VBA skills aren't good enough to figure this one out.
This part of the code in run in a Excel class and is used to load a xml file and return the xml as a class.
Public Function GetDomNodeList(ByRef log As Logger) As MSXML2.IXMLDOMNodeList
Dim domdocument As New MSXML2.DOMDocument60
'Open file for handling
domdocument.async = False
domdocument.Load (strThisFilePath)
'Call the helper sub to do the actual work:
Set GetDomNodeList = domdocument.childNodes
End Function
When debugging it tells me there is a type mismatch. I've tried to debug the issue, but I'm running short on knowledge here. My main question is why this works on windows 7 and why not on windows 10 running the same office version (2016) VBA7.1
After a lot of trials I found a solution. Export the class, remove it and import the class again and all magically works again. I'm baffled by this.

VB.NET Resource exe in memory with argument

Alright so i am pretty new to really anything in memory execution. I usually just write the bytes from the embedded resource into the file on the hard drive but for the program i am making for a work project it cannot write the exe to the disk.
So i took the code from Load a .NET assembly from the application's resources and run It from memory, but without terminating the main/host application
I modified the code a little bit in what i would think would work for running it with an argument and it does nothing but crash, not really listing any crash details though besides the windows error reporting.
here is the code:
Dim ass As Assembly = Assembly.Load(My.Resources.bbinst)
Dim method As MethodInfo = ass.EntryPoint
Dim parametersArray As Object() = New Object() {"/q /SERIAL=xxx-xxx"}
If (method IsNot Nothing) Then
Dim instance As Object = ass.CreateInstance(method.Name)
method.Invoke(instance, parametersArray)
If (instance IsNot Nothing) AndAlso (instance.GetType().GetInterfaces.Contains(GetType(IDisposable))) Then
DirectCast(instance, IDisposable).Dispose()
End If
instance = Nothing
method = Nothing
ass = Nothing
Else
Throw New EntryPointNotFoundException("Entrypoint not found in the specified resource. Are you sure it is a .NET assembly?")
End If
bbinst is the exe name that is embedded as bbinst.exe
The parametersArray is the argument i want to run which i converted from a C# sample i found else where.
Can someone help me as to why the program just crashes and error reporting pops up second after, i'm not to good as debugging. I also tried to run it without the arguments and it as well crashed the same way.
Any help is awesome, sometimes i have these random projects at work i don't know why they give me lol
A BadImageFormatException is thrown either when you attempt to load an assembly of the wrong bitness, or when you try to load an assembly that cannot be read, run or compiled by the current runtime.
Regarding bitness: 32-bit (x86) applications cannot load 64-bit code, and 64-bit (x64) applications cannot load 32-bit code. It's that simple.
As for not being able to read, run or compile the assembly: If the assembly that you're trying to load was programmed in a completely different language (more precisely: a language without .NET support) then it would also cause the above exception to be thrown.
Your method of executing an embedded application will only work with assemblies that were coded in a .NET language (C#, VB.NET, F#, C++/CLR, etc.). This is because that doesn't only run the application, it tries to load it like a .NET app linked to an Assembly, and/or AppDomain, class so that you can have some control over it and invoke methods inside it.
Your issue: My bet that your problem is caused by your embedded application not being of the same bitness as the host. Make sure both applications are compiled either as x86, x64 or AnyCPU.
However if it turns out that your embedded program isn't even written in a .NET language then that is the cause of your problem. That code of yours can only run .NET programs/DLLs.
You can invoke the EntryPoint by loading it in the assembly :
Public Shared Sub RunSearch(ByVal pPath As String, ByVal pText As String)
'Get assembly
Dim assembly As Reflection.Assembly = Reflection.Assembly.GetExecutingAssembly()
'Get the resource stream
Dim resourceStream As Stream = assembly.GetManifestResourceStream("path.executable name")
If resourceStream Is Nothing Then
MsgBox("Unexisting Path","Error")
End If
'Read the raw bytes of the resource
Dim resourcesBuffer(CInt(resourceStream.Length) - 1) As Byte
resourceStream.Read(resourcesBuffer, 0, resourcesBuffer.Length)
resourceStream.Close()
'Load the assembly
Dim exeAssembly As Reflection.Assembly = Reflection.Assembly.Load(resourcesBuffer)
Dim args() As String = {pPath, pText}
Dim parameters = New Object() {args}
Try
exeAssembly.EntryPoint.Invoke(Nothing, parameters)
Catch
MsgBox("Error during assembly executing","Error")
End Try
End Sub

WScript in VB.NET?

This is a snipet of code from my program:
WSHShell = WScript.CreateObject("WScript.Shell")
But for some reason, "WScript" is not declared. I know that this code works in VBScript but i'm trying to get it to work with vb.net. Whats going wrong?
The WScript object is specific to Windows Script Host and doesn't exist in .NET Framework.
Actually, all of the WScript.Shell object functionality is available in .NET Framework classes. So if you're porting VBScript code to VB.NET, you should rewrite it using .NET classes rather than using Windows Script Host COM objects.
If, for some reason, you prefer to use COM objects anyway, you need to add the appropriate COM library references to your project in order to have these objects available to your application. In case of WScript.Shell, it's %WinDir%\System32\wshom.ocx (or %WinDir%\SysWOW64\wshom.ocx on 64-bit Windows). Then you can write code like this:
Imports IWshRuntimeLibrary
....
Dim shell As WshShell = New WshShell
MsgBox(shell.ExpandEnvironmentStrings("%windir%"))
Alternatively, you can create instances of COM objects using
Activator.CreateInstance(Type.GetTypeFromProgID(ProgID))
and then work with them using late binding. Like this, for example*:
Imports System.Reflection
Imports System.Runtime.InteropServices
...
Dim shell As Object = Nothing
Dim wshtype As Type = Type.GetTypeFromProgID("WScript.Shell")
If Not wshtype Is Nothing Then
shell = Activator.CreateInstance(wshtype)
End If
If Not shell Is Nothing Then
Dim str As String = CStr(wshtype.InvokeMember(
"ExpandEnvironmentStrings",
BindingFlags.InvokeMethod,
Nothing,
shell,
{"%windir%"}
))
MsgBox(str)
' Do something else
Marshal.ReleaseComObject(shell)
End If
* I don't know VB.NET well, so this code may be ugly; feel free to improve.