Right now I'm trying to code a tool that shall be capable of downloading a file from a specific website, beside some other stuff.
My current solution is, that I open the website from where the file shall be downloaded in Internet Explorer, wait some seconds so the website can be loaded and then send a keystroke to Internet Explorer, which is ALT+S, to save the file to the standard download location.
However, my code fails in the line where the keystroke should be sent.
You'll find it below of course plus the error it throws.
Some facts I believe you'll find useful to know:
My application shall be a console app, no forms app
I'm using the Internet Explorer for this so that I can be sure the application works for every Windows PC
I expect the Internet Explorer to have the default configuration for downloading files to be set to "User prompt", i.e. it's asking wether the file shall be openend or saved
The website, as you'll see in the code below, is a third-party website, so I don't have direct access to the files being hosted on the server
What I specifically like to know is:
Can I solve this problem somehow smarter? Are there other, perhaps easier ways, to download a file than what I did?
How can I make my application wait for the website to be loaded or even wait for the "Open - Save - Cancel" prompt to show up?
How do I get the "SendKeys" part to work correctly?
And most important: Please note that I'm a hobby programmer and just started with VB a few weeks ago. If I missed out some important information or my code looks weird, well, then that's why :)
Sub Download()
Dim IE As Object
IE = CreateObject("InternetExplorer.Application")
Console.WriteLine("Start Download")
IE.Navigate("https://toolslib.net/downloads/finish/1-adwcleaner/") 'Opens the website in Internet Explorer
Do 'Waits for Internet Explorer to be launched before going on
If CBool(Process.GetProcesses.Where(Function(P As Process) _
P.ProcessName = "iexplore").Count) Then
Exit Do
End If
Threading.Thread.Sleep(100)
Loop
IE.Visible = True
Threading.Thread.Sleep(5000) 'Some time for the website to load
IE.SendKeys("%{S}", True)
End Sub
When running this code it throws the following error.
Note: Line 67 is the line where IE.SendKeys("%{S}", True) stands.
Unhandled Exception: System.ArgumentException: The process {0} wasn't found.
at Microsoft.VisualBasic.CompilerServices.Symbols.Container.InvokeMethod(Method TargetProcedure, Object[] Arguments, Boolean[] CopyBack, BindingFlags Flags)
at Microsoft.VisualBasic.CompilerServices.NewLateBinding.CallMethod(Container BaseReference, String MethodName, Object[] Arguments, String[] ArgumentNames, Type[] TypeArguments, Boolean[] CopyBack, BindingFlags InvocationFlags, Boolean ReportErrors, ResolutionFailure& Failure)
at Microsoft.VisualBasic.CompilerServices.NewLateBinding.ObjectLateCall(Object Instance, Type Type, String MemberName, Object[] Arguments, String[] ArgumentNames, Type[] TypeArguments, Boolean[] CopyBack, Boolean IgnoreReturn)
bei Microsoft.VisualBasic.CompilerServices.NewLateBinding.LateCall(Object Instance, Type Type, String MemberName, Object[] Arguments, String[] ArgumentNames, Type[] TypeArguments, Boolean[] CopyBack, Boolean IgnoreReturn)
at MyApp.Module1.Download() in C:\Users\User\Documents\Visual Studio 2017\Projects\MyApp\MyApp\Module1.vb:Line 67.
I used WebBrowser control in form application and its worked fine me!
SendKeys.Send("+{TAB}")
System.Threading.Thread.Sleep(1000)
SendKeys.Send("{ENTER}")
Related
I have been working on this issue for over a month and have tried everything I have found in forums. Desperately need help.
Background:
1 - I recently started using a brand new PC (windows 10)
2 - I am running the exact same VS2019 version as previous PC
3 - This program is form that contains many checkboxes and text boxes. The user makes selections and enters information on the form then they save it. When it saves, I write the state of every control to a text file (aka .enc extension) using streamwriter. When a user then opens the form again it uses streamreader to open that same text file and set the state of every control on the form so the user can see what was previously entered.
4 - The text file is on a shared network, but when examining the file from the network management it does not show as 'in use' by any user including myself.
This program has been running for several years and there have been no changes to the IT infrastructure. Problem only exists for my PC.
Issue:
• When I open an existing project and make NO changes to it and run the program via debug or release and run the exe everything works fine
• As soon as I make ANY change to the source code (including something as simple as adding a comment character), it will throw an exception which I have at the very end of this post.
• The exception being thrown is tricky because it is most definitely not related to disposal of the stream (from a source code perspective). See Item A below
• When I try to modify or delete the text file through windows explorer it gives me a "file in use" message. When I use another PC to try to delete this file, it works without saying "file in use".
• As far as I suspect, there is something going on with a very deep level aspect of the compiler.
• To be clear, this is the issue: Run the program (creates a text file), no issue there. Then I wait, run the program again and then it crashes when trying to load that same text file. When I look at the text file through windows explorer it is 'in use'.
What I have tried:
A) I have tried both methods of disposing streamwriter and streamreader... stream.Close() method as well as using stream Using ... End Using method. See code snippets below.
B) I have used a colleagues PC to run the exact same source project via debug as well as a released exe, and it causes NO issues.
C) I have tried using processMonitor and processExplorer to search for the text file to find a related process or .dll that is causing the hold up. It never shows up in process dumps.
D) Disabling antivirus
**E) Running on another PC. This works.
F) Compiling exe on another PC then running from my PC **Get same Error
G) Repair and re-install of VS
H) safe mode
I have read through hundreds of forum posts and tried almost every suggestion. If you have any ideas and can help me I would much appreciate it, you would be an absolute legend if you were able to figure this out.
Code:
Method 1
Dim filewriter As System.IO.StreamWriter
filewriter = My.Computer.FileSystem.OpenTextFileWriter(dirNewENC & newfile, True)
filewriter.WriteLine("shortcutCreated=" & shortcutCreated)
filewriter.WriteLine("shortcutPath=" & shortcutPath)
...
filewriter.Close()
Method 2
Using filewriter = My.Computer.FileSystem.OpenTextFileWriter(dirNewENC & newfile, True)
filewriter.WriteLine("shortcutCreated=" & shortcutCreated)
filewriter.WriteLine("shortcutPath=" & shortcutPath)
...
End Using
Exception Detail:
System.IO.IOException
HResult=0x80070020
Message=The process cannot access the file '\affs01\Shared\Sales\Quotes\ENC\TEST8%01%TEST%Q99999998%44456%.enc' because it is being used by another process.
Source=mscorlib
StackTrace:
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
at System.IO.StreamReader..ctor(String path, Encoding encoding, Boolean detectEncodingFromByteOrderMarks, Int32 bufferSize, Boolean checkHost)
at System.IO.StreamReader..ctor(String path, Encoding encoding, Boolean detectEncodingFromByteOrderMarks)
at Microsoft.VisualBasic.FileIO.FileSystem.OpenTextFileReader(String file, Encoding encoding)
at Microsoft.VisualBasic.MyServices.FileSystemProxy.OpenTextFileReader(String file)
at Order_Entry.GlobalSubs.checkOrderType() in C:\Users\RB\OneDrive\Code\repos\Order Entry\Order Entry\GlobalSubs.vb:line 6348
at Order_Entry.frm_NewEntry.btn_searchQuote_Click(Object sender, EventArgs e) in C:\Users\RB\OneDrive\Code\repos\Order Entry\Order Entry\frm_NewEntry.vb:line 152
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.PerformClick()
at System.Windows.Forms.Form.ProcessDialogKey(Keys keyData)
at System.Windows.Forms.Control.ProcessDialogKey(Keys keyData)
at System.Windows.Forms.TextBoxBase.ProcessDialogKey(Keys keyData)
at System.Windows.Forms.Control.PreProcessMessage(Message& msg)
at System.Windows.Forms.Control.PreProcessControlMessageInternal(Control target, Message& msg)
at System.Windows.Forms.Application.ThreadContext.PreTranslateMessage(MSG& msg)
at System.Windows.Forms.Application.ThreadContext.System.Windows.Forms.UnsafeNativeMethods.IMsoComponent.FPreTranslateMessage(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
at Order_Entry.My.MyApplication.Main(String[] Args) in :line 83
Along with #Andrew Morton and #Hursey mentioned, I bit the bullet and wiped the PC with a clean reinstall.
Can happily (in one sense) report that the issue is resolved.
Thank you.
...now to get all my apps back.
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
I have a program which runs on some wearable terminals in our warehouse. These terminals connect via remote desktop to our server which actually hosts and runs this program.
This program takes a scan of product, launches another program (if it isn't already running for the current user) which handles some processing, then does some additional processing once finished. One issue I'm running into is checking if the second program is already running. I've tried a lot of different code but this is what I settled on as it seemed to work perfectly fine.
Private Function CheckPrintLabelRunning() As Boolean
Dim selectQuery As String = "Select * From Win32_Process Where Name = 'vbPrintLabel.exe'"
Dim searcher As New System.Management.ManagementObjectSearcher(selectQuery)
Dim processList As System.Management.ManagementObjectCollection = searcher.[Get]()
For Each obj As System.Management.ManagementObject In processList
Dim argList As String() = New String() {String.Empty, String.Empty}
Dim returnVal As Integer = Convert.ToInt32(obj.InvokeMethod("GetOwner", argList))
If returnVal = 0 Then
If argList(0).ToString.ToUpper = Environment.UserName.ToUpper Then
Return True
End If
End If
Next
Return False
End Function
On Thursday, while the users were using the application on the terminals, the following error message popped up in my error logs. This application has seemingly been closing itself down, hitting the main form's FormClosing event (indicating that it isn't a full crash, but something that is handled inappropriately or an environment crash perhaps?). Here is the exception:
System.Management.ManagementException: Not found
at System.Management.ManagementException.ThrowWithExtendedInfo(ManagementStatus errorCode)
at System.Management.ManagementObject.InvokeMethod(String methodName, ManagementBaseObject inParameters, InvokeMethodOptions options)
at System.Management.ManagementObject.InvokeMethod(String methodName, Object[] args)
at vbFullCasePicking.frmFullCasePicking.CheckPrintLabelRunning()
at vbFullCasePicking.frmFullCasePicking.StartPrintLabelListener()
at vbFullCasePicking.frmFullCasePicking.PrintLabel(Boolean blnSMPLabels, String strCartonID)
I would like to point out that in this particular issue, the application did not close itself down, but I am still curious about this error as it's the first I've seen it of all the months this has been in use.
EDIT: More info...the server the application runs on is Windows Server 2003. This issue has not generated any event log entries of any kind as far as we can see.
EDIT 2: I completely forgot about this, but I have a previous question regarding this issue. I was initially querying all the processes which seemed to cause errors when multiple users would try to query at the same time. This is likely the same issue, then, just with a much smaller window. Any input is greatly appreciated.
I was wondering if there is anyway to get the file path of a selected file. I have registered a hotkey in reference to this.
E.g. RegisterHotKey(Me.Handle, 100, MOD_CONTROL Or MOD_SHIFT, Keys.D2)
Which will do certain actions on pressing ctrl, shift and 2. What i want to do is to get the path of a selected file WITHOUT opening OpenFileDialog
e.g. i select mydoc.doc located on my desktop, press ctrl shift and 2, and it will msgbox out the location of the file.
(meaning i click the file mydoc.doc on my desktop, press my hotkey and get the file location. Is there anyway to do this? (Just like how you would click a file in a folder to copy and paste it to another location, i want to click the file press my hotkey and msgbox out its location))
Is there anyway to do this or any direction anyone can point me in?Because i can't find any API which does this...
Thanks!
EDIT:
After reading all the updates and the several links here and there, I started to construct my own function for this, I'm just at the part to determine how many selected icons there are, but i keep getting back 0 icons is there something wrong with what I'm doing?
Public Function getDesktopFiles() As String
Dim vhandle As IntPtr = FindWindow("Progman", "Program Manager")
vhandle = FindWindowEx(vhandle, IntPtr.Zero, "SHELLDLL_DefView", vbNull)
vhandle = FindWindowEx(vhandle, IntPtr.Zero, "SysListView32", "FolderView")
Dim vItemcount As IntPtr
vItemcount = SendMessage(vhandle, LVM_GETSELECTEDCOUNT, 0, 0)
Return vItemcount
End Function
This question has a link to a Raymond Chen blog post which will give you the API calls you require, you will need to convert it to VB but it is based on COM so should be easy. The other answer to that question gives the C# version of Raymond's code...
Edited to add specifics:
1. Include project references to Microsoft Internet Controls (to get the SHDocVw namespace) and Microsoft Shell Controls and Automation (to get the Shell32 namespace)
2. Use SHDocVw.ShellWindows to get an enumeration of open browser windows.
3. Try to cast each item as a ShellBrowserWindow, and then try to cast the Document property as a Shell32.IShellFolderViewDual2 object.
4. The FocusedItem property gives the selected item.
VB.NET code:
Dim windows As New SHDocVw.ShellWindows
For Each window As Object In windows
Dim browser As SHDocVw.ShellBrowserWindow = window
Dim folder As Shell32.IShellFolderViewDual2 = browser.Document
Console.WriteLine(folder.FocusedItem.Path)
Next
The following function copies a file from Source & Path to Dest & Path, normally setting file attributes to normal before copying.
Yet, a user of my app has reported it to fail when copying readonly files, returning a permissions-related error. The user is however running the code as administrator, and the error happens - quite strangely - on the SetLastWriteTimeUtc line.
Although the code reports that the file attributes are set to normal, windows explorer shows that they are set to read only.
Sub CopyFile(ByVal Path As String, ByVal Source As String, ByVal Dest As String)
If IO.File.Exists(Dest & Path) Then IO.File.SetAttributes(Dest & Path, IO.FileAttributes.Normal)
IO.File.Copy(Source & Path, Dest & Path, True)
If Handler.GetSetting(ConfigOptions.TimeOffset, "0") <> "0" Then
IO.File.SetAttributes(Dest & Path, IO.FileAttributes.Normal)
IO.File.SetLastWriteTimeUtc(Dest & Path, IO.File.GetLastWriteTimeUtc(Dest & Path).AddHours(Handler.GetSetting(ConfigOptions.TimeOffset, "0")))
End If
IO.File.SetAttributes(Dest & Path, IO.File.GetAttributes(Source & Path))
End Sub
I just fail to see the problem in this code, so after long hours of searching for the solution, I thought one of SO VB.Net Gurus might help :)
Thanks a lot.
Edit:
The actual error is
Access to the path '(..)' is denied.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize)
at System.IO.File.OpenFile(String path, FileAccess access, SafeFileHandle& handle)
at System.IO.File.SetLastWriteTimeUtc(String path, DateTime lastWriteTimeUtc)
If the files being moved are in a place that requires administration permissions per the Vista User Account Controls (UAC), you will need to run the application as administrator, as in the right click menu from below:
alt text http://www.trendystock.com/images/Run%20as%20administrator%20for%20Vista%20PC.jpg
If this is a hassle, the user can right click the shortcut or .exe, and go to properties where you can select to always run the app as administrator. Alternatively, if it's an option, they could just disable UAC.