Copy file to remote computer - vb.net

I have created a program which will copy from my computer to other remote computers a specific file. I have successfully did this, but only in the driver C:\ . My question is how can I copy the file to the D:\ drive?
I have tried adding \157.60.113.28\D:\testnew\right.bmp but with no luck. Let me know!
Imports System
Imports System.Runtime.InteropServices
Imports System.Security.Principal
Imports System.Security.Permissions
Public Class Form1
<DllImport("advapi32.DLL", SetLastError:=True)> _
Public Shared Function LogonUser(ByVal lpszUsername As String, ByVal lpszDomain As String, _
ByVal lpszPassword As String, ByVal dwLogonType As Integer, ByVal dwLogonProvider As Integer, _
ByRef phToken As IntPtr) As Integer
End Function
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim admin_token As IntPtr
Dim wid_current As WindowsIdentity = WindowsIdentity.GetCurrent()
Dim wid_admin As WindowsIdentity = Nothing
Dim wic As WindowsImpersonationContext = Nothing
Try
MessageBox.Show("Copying file...")
If LogonUser("Local Admin name", "Local computer name", "pwd", 9, 0, admin_token) <> 0 Then
wid_admin = New WindowsIdentity(admin_token)
wic = wid_admin.Impersonate()
System.IO.File.Copy("C:\right.bmp", "\\157.60.113.28\testnew\right.bmp", True)
MessageBox.Show("Copy succeeded")
Else
MessageBox.Show("Copy Failed")
End If
Catch se As System.Exception
Dim ret As Integer = Marshal.GetLastWin32Error()
MessageBox.Show(ret.ToString(), "Error code: " + ret.ToString())
MessageBox.Show(se.Message)
Finally
If wic IsNot Nothing Then
wic.Undo()
End If
End Try
End Sub
End Class

the path you're looking for is:
\\157.60.113.28\D$\testnew\right.bmp
if you are required to interact with the remote machine regularly it would be wise to map the network path as a network drive in your machine.

Related

How to set the Explorer window of a specific file as a child window of TopMost form?

I made some research, but I can't find something really "interesting". I tried my best to find any kind of documentation or questions that are closest to my case as following:
How to find main window title name of application
how to get the window title of a process
How to get the Title Bar Text by its Process Id
getting the name of a process
How do I get list of Process Names running
Check to see if process is running
How To Get Process Owner ID
How to get the title/name of the last active window?
Get Process ID from Window Title
and also
Process.GetProcessesByName Method
The code I am using to open the process window
Private Async Function ParentMethod() As Task
Dim filePath As String = Await Task.Run(
Function()
Return Directory.EnumerateFiles(My.Settings.Cartellasalvataggio, titolo & ".mp3",
SearchOption.AllDirectories).FirstOrDefault()
End Function)
If Not String.IsNullOrEmpty(filePath) Then
LinkLabel1.Text = "File exist already"
LinkLabel1.Visible = True
PictureBox7.Visible = True
Else
MsgBox("it doesn't exist")
End If
End Function
and the helper class
Imports System.IO
Imports System.Runtime.InteropServices
Public Class NativeMethods
<DllImport("shell32.dll", SetLastError:=True)>
Private Shared Function SHOpenFolderAndSelectItems(
pidlFolder As IntPtr, cidl As UInteger,
<[In], MarshalAs(UnmanagedType.LPArray)> apidl As IntPtr(),
dwFlags As UInteger) As Integer
End Function
<DllImport("shell32.dll", SetLastError:=True)>
Private Shared Sub SHParseDisplayName(
<MarshalAs(UnmanagedType.LPWStr)> name As String,
bindingContext As IntPtr, <Out> ByRef pidl As IntPtr,
sfgaoIn As UInteger, <Out> ByRef psfgaoOut As UInteger)
End Sub
Public Shared Sub OpenFolderAndSelectFile(filePath As String)
Dim dirPath As String = Path.GetDirectoryName(filePath)
Dim fileName As String = Path.GetFileName(filePath)
OpenFolderAndSelectFile(dirPath, fileName)
End Sub
Public Shared Sub OpenFolderAndSelectFile(dirPath As String, fileName As String)
Dim nativeFolder As IntPtr
Dim psfgaoOut As UInteger
SHParseDisplayName(dirPath, IntPtr.Zero, nativeFolder, 0, psfgaoOut)
If nativeFolder = IntPtr.Zero Then
' Log error, can't find folder
Return
End If
Dim nativeFile As IntPtr
SHParseDisplayName(Path.Combine(dirPath, fileName),
IntPtr.Zero, nativeFile, 0, psfgaoOut)
Dim fileArray As IntPtr()
If nativeFile = IntPtr.Zero Then
' Open the folder without the file selected if we can't find the file
fileArray = New IntPtr(-1) {}
Else
fileArray = New IntPtr() {nativeFile}
End If
SHOpenFolderAndSelectItems(nativeFolder, CUInt(fileArray.Length), fileArray, 0)
Marshal.FreeCoTaskMem(nativeFolder)
If nativeFile <> IntPtr.Zero Then
Marshal.FreeCoTaskMem(nativeFile)
End If
End Sub
End Class
then calling it with
NativeMethods.OpenFolderAndSelectFile(filepath,filename & "extension"))
Since I am opening the process this way and NOT with Process class, almost all of them are not suitable to be considered for my case as many of them refer to notepad, while I think the explorer window title and ID changes for every file ( obviously), while "notepad" process, stay "notepad".
I also tried BringToFront, but this latter moves a control in front of other controls, but in this case Explorer is not a control, right?
The least I want to do is to
Get a list of active windows & their process names
as It will waste memory and time usage for no reason as I will need to "filter" process to find my process.
Hope we can find a solution to this, Thanks in advance.
Mattia
This is the solution to it using FindWindowW e SetWindowPos Api.
It is showing Explorer folder on top of top most form.
<DllImport("user32.dll", EntryPoint:="FindWindowW")>
Public Shared Function FindWindowW(<MarshalAs(UnmanagedType.LPTStr)> ByVal lpClassName As String, <MarshalAs(UnmanagedType.LPTStr)> ByVal lpWindowName As String) As IntPtr
End Function
<DllImport("user32.dll")>
Shared Function SetWindowPos(ByVal hWnd As IntPtr, ByVal hWndInsertAfter As IntPtr, ByVal X As Integer, ByVal Y As Integer, ByVal cx As Integer, ByVal cy As Integer, ByVal uFlags As UInteger) As Boolean
End Function
Shared ReadOnly HWND_TOPMOST As IntPtr = New IntPtr(-1)
Const SWP_NOSIZE As UInt32 = &H1
Const SWP_NOMOVE As UInt32 = &H2
Const SWP_SHOWWINDOW As UInt32 = &H40
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Dim inptr = FindWindowW("CabinetWClass", Nothing)
SetWindowPos(inptr, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE Or SWP_SHOWWINDOW)
End Sub

Read INI in Visual Basic vb.NET

I'm trying to read a INI file then dump the values into the registry for a setup application to function.
The INI file looks like this
[Setup Components]
Sybase Adaptive Server Anywhere Client=Yes
Borland Database Engine=Yes
BDERoot=c:\Program Files\Borland\BDE
Program Shortcuts=Yes
ODBC Data Service Name=Yes
Local Client = Yes
Sybase Admin = Yes
Sybase Directory= C:\Program Files\SQL Anywhere 16
DBRoot=c:\Database
Word Link=Yes
Installation Root Folder=c:\program
FireDAC=DB=asa16;eng=ENGINE;dbn=DBNAME;links=TCPIP{Host=127.0.0.1;Port=2638}
[Program Shortcuts]
Desktop=Yes
Start Menu=Yes
Program Title=PROGRAM
EXE Pathname=c:\program.exe
Parameters=DBNAME
Starting Directory=c:\
Icon=icon.ICO
[ODBC Data Service Name]
Data Service Name=DBNAME
Database File Name=c:\database\database.db
Database Name=DBNAME
Server Name=ENGINE
Comm Links=TCPIP{}
PrefetchBuffer=6000
PrefetchRows=50
CommBufferSize=1460
Compress=no
[Service]
Service Name=SQLANYs_DBNAME
Display Name=SQL Anywhere - DBNAME
Service Group=SQLANYServer
Params=-n DBNAME -x TCPIP{} "C:\database\database.db" -n DBNAME
So I need all those items to be dumped into the registry easily.
I'm using Visual Studio 2015, I did attempt to use Ludvik Jerabek's INI reader (http://www.codeproject.com/Articles/21896/INI-Reader-Writer-Class-for-C-VB-NET-and-VBScript) but had no luck getting that to function!
The code i did use for the above was the following:
Dim ini = New IniFile()
ini.Load("setup.ini")
Dim readValue = ini.Sections("Service").Keys("Service Name")
MessageBox.Show(readValue.ToString)
When running this code i got the following error : "Conversion from string "Service" to type "Integer" is not valid. -Also this method means naming each and every key in the INI file which would be quite some task!
I then went down another method after reading some help questions on here and i used the following:
Private Declare Auto Function GetPrivateProfileString Lib "kernel32" (ByVal lpAppName As String,
ByVal lpKeyName As String,
ByVal lpDefault As String,
ByVal lpReturnedString As StringBuilder,
ByVal nSize As Integer,
ByVal lpFileName As String) As Integer
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim sb As StringBuilder
sb = New StringBuilder(500)
Dim readVal = GetPrivateProfileString("Service", "Service Name", "", sb, sb.Capacity, "setup.ini")
MessageBox.Show(readVal.ToString)
End Sub
However this just returns "0"
Any help would be grateful to find a way to get this reading from the INI and dumping to the registry
Using the given IniFile class, this will get you to the config setting values:
Private Sub INIButtonTest_Click(sender As Object, e As EventArgs) Handles INIButtonTest.Click
Try
Dim iniFilePath As String = "H:\Dev\StackOverflow\StackOverflowTest\StackOverflowApp\bin\Debug\test.ini"
Dim myIniFile As New IniFile
myIniFile.Load(iniFilePath)
Dim myValue As String = getIniValue(myIniFile, "Service", "Service Name")
If Not String.IsNullOrEmpty(myValue) Then
MessageBox.Show(String.Format("Found value: [{0}]", myValue))
End If
Catch ex As Exception
MessageBox.Show(String.Concat("Something went wrong:", ex.Message))
End Try
End Sub
Private Function getIniValue(iniFileInstance As IniFile, sectionName As String, sectionKey As String) As String
Dim myValue As String = String.Empty
For Each sect As IniFile.IniSection In iniFileInstance.Sections
If sect.Name = sectionName Then
For Each key As IniFile.IniSection.IniKey In sect.Keys
If key.Name = sectionKey Then
myValue = key.GetValue
Exit For
End If
Next
Exit For
End If
Next
Return myValue
End Function
As an alternate, the code for the original approach is very close to correct, but GetPrivateProfileString doesn't actually exist in Kernel32.dll. You need to add a W to the name, which makes the corrected code:
' With these imports
Imports System.ComponentModel
Imports System.Runtime.InteropServices
Imports System.Text
' Note the W on the function name
Private Declare Auto Function GetPrivateProfileStringW Lib "kernel32" (ByVal lpAppName As String,
ByVal lpKeyName As String,
ByVal lpDefault As String,
ByVal lpReturnedString As StringBuilder,
ByVal nSize As Integer,
ByVal lpFileName As String) As Integer
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim sb As New StringBuilder(500)
Dim result As Integer = GetPrivateProfileStringW("Service", "Service Name", "", sb, sb.Capacity, "setup.ini")
If result > 0 Then
MessageBox.Show(sb.ToString())
Else
Dim ex As New Win32Exception(Marshal.GetLastWin32Error())
MessageBox.Show(ex.Message)
End If
End Sub
If you prefer not to use the W, or you want to call your function something different, you can also use the DllImportAttribute and change the function declaration to:
<DllImport("Kernel32.dll", CharSet:=CharSet.Auto,
SetLastError:=True, EntryPoint:="GetPrivateProfileStringW")>
Private Shared Function GetPrivateProfileString(ByVal lpAppName As String,
ByVal lpKeyName As String,
ByVal lpDefault As String,
ByVal lpReturnedString As StringBuilder,
ByVal nSize As Integer,
ByVal lpFileName As String) As Integer
End Function
This is what I have used since VB 3.0 and it has worked with all versions of windows since 3.1. There have been a few modifications to make it fit into the conventions of the newer dev tools but essentially they are the same routines.
These must be in a public class or in the public area of a form:
Public Declare Function OSGetPrivateProfileString% Lib "kernel32" Alias "GetPrivateProfileStringA"(ByVal AppName As String, ByVal KeyName As String, ByVal keydefault As String, ByVal ReturnString As String, ByVal NumBytes As Integer, ByVal FileName As String)
Public Declare Function OSWritePrivateProfileString Lib "kernel32" Alias "WritePrivateProfileStringA"(ByVal AppName As String, ByVal KeyName As String, ByVal keydefault As String, ByVal FileName As String) As Integer
Then, somewhere in your form's code area or if you have a "functions.vb" class (where the above would be declared) place these two:
Public Shared Function GetINIString(ByVal strItem As String, ByVal strDefault As String, ByVal strSection As String, ByVal filename As String) As String
Const BUFFERSIZE As Integer = 16768
Dim strTemp As New String(Chr(0), BUFFERSIZE)
Dim stringSize As Long = 0
stringSize = OSGetPrivateProfileString%(strSection, strItem, strDefault, strTemp, BUFFERSIZE, filename)
Return Strings.Left(strTemp, stringSize)
End Function
AND
Public Shared Sub PutINIString(strItem As String, strValue As String, strSection As String, iniFilename As String)
Dim i As Integer = 0
i = OSWritePrivateProfileString(strSection, strItem, strValue, iniFilename)
End Sub
This continues to work in VB 2010

Open Folder Path if not already open, if open show window

This seems like a simple task but I cannot seem to produce the results looking for.
currently I have this code
Dim folderpath As String
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
folderpath = "C:\epds\WIP"
Process.Start("explorer.exe", folderpath)
End Sub
That's fine and it opens my folder path as indicated, however, if the instance of that folder is already open in the explorer how do I just make that window current instead of opening a new window explorer?
EDIT: This seemed to do the trick, thanks for pointing me in the right direction #Okuma.Scott
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function FindWindow( _
ByVal lpClassName As String, _
ByVal lpWindowName As String) As IntPtr
End Function
<DllImport("user32.dll", EntryPoint:="FindWindow", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function FindWindowByClass( _
ByVal lpClassName As String, _
ByVal zero As IntPtr) As IntPtr
End Function
<DllImport("user32.dll", EntryPoint:="FindWindow", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function FindWindowByCaption( _
ByVal zero As IntPtr, _
ByVal lpWindowName As String) As IntPtr
End Function
Dim folderpath As String
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
folderpath = "C:\epds\WIP"
'Process.Start("explorer.exe", folderpath)
Dim nWnd As IntPtr
Dim ceroIntPtr As New IntPtr(0)
Dim Wnd_name As String
Wnd_name = "WIP"
nWnd = FindWindow(Nothing, Wnd_name)
'show the info
If nWnd.Equals(ceroIntPtr) Then
Process.Start("explorer.exe", folderpath)
Else
AppActivate(Wnd_name)
SendKeys.SendWait("~")
End If
End Sub
I was trying to solve this same issue and discovered that it seems to work by just calling Process.Start with the desired path:
Process.Start("C:\Temp")
If the folder is already open in an Explorer window it opens the existing window otherwise it opens a new window.
you need to import Imports System.Runtime.InteropServices
then you can use the function Findwindow
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function FindWindow(ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
End Function
Then make 2 dims 1. folderpath and 2 is foldername
Then in your click event use "System.IO.Path.GetFileName(folderpath)" to get the name of the window you are looking for." for you WIP"
Then check with a if statement if FindWindow(vbNullString, foldername) = 0 "not open"
The vbNullString Represents a zero-length string for print and display functions, and for calling external procedures."msdn"
so if findwindow is 0 open the folder and else focus the folder
Dim folderpath As String
Dim foldername As String
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
folderpath = "C:\epds\WIP"
foldername = System.IO.Path.GetFileName(folderpath)
If FindWindow(vbNullString, foldername) = 0 Then
Process.Start("explorer.exe", folderpath)
Else
AppActivate(foldername)
SendKeys.SendWait("~")
End If
End Sub
This works and will not open multiple windows:
Process.Start(new ProcessStartInfo() { FileName = "C:\\", UseShellExecute = true });
The only downside is that it does not bring the opened folder to the foreground (which depending on your use case may or may not be a bad thing!

CreateMsgQueue fails with Win32Error -2147467259

I've recreated some of the OpenNetCF components like PowerManagement and DeviceStatusMonitor. But since they never raised any events I suspected that something was wrong. My first thought was to check the P2PMessageQueue which they both depends on. And then BAM, the CreateMsgQueue returns IntPtr.Zero. Checking for the last Win32Error gives me an error code of value -2147467259 (minus).
Is this just another generic error code that doesn't provide any hints?
Any help would be appreciated.
(FYI: WinCE 5.0, CF 2.0)
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Try
Dim lpName As String = "MyQueue"
Dim lpOptions As MSGQUEUEOPTIONS = New MSGQUEUEOPTIONS()
Dim hMsgQ As IntPtr = IntPtr.Zero
lpOptions.bReadAccess = True
lpOptions.dwMaxMessages = 0
lpOptions.cbMaxMessage = &H1000
lpOptions.dwFlags = MSGQUEUE_ALLOW_BROKEN
lpOptions.dwSize = Marshal.SizeOf(lpOptions)
hMsgQ = CreateMsgQueue(lpName, lpOptions)
If (hMsgQ = IntPtr.Zero) Then
Throw New Win32Exception(Marshal.GetLastWin32Error())
Else
CloseMsgQueue(hMsgQ)
End If
Catch ex As Win32Exception
MessageBox.Show(String.Format(String.Format("Win32Exception: {0}", ex.ErrorCode)))
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
<DllImport("coredll.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
Private Shared Function CloseMsgQueue(ByVal hMsgQ As IntPtr) As Boolean
End Function
<DllImport("coredll.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
Private Shared Function CreateMsgQueue(<MarshalAs(UnmanagedType.LPWStr)> ByVal lpName As String, ByVal lpOptions As MSGQUEUEOPTIONS) As IntPtr
End Function
<StructLayout(LayoutKind.Sequential)> _
Private Structure MSGQUEUEOPTIONS
Public dwSize As Integer
Public dwFlags As Integer
Public dwMaxMessages As Integer
Public cbMaxMessage As Integer
Public bReadAccess As Boolean
End Structure
Private Const MSGQUEUE_ALLOW_BROKEN As Integer = 2
Private Const MSGQUEUE_NOPRECOMMIT As Integer = 1
Private Const MSGQUEUE_MSGALERT As Integer = 1
End Class
The lpOptions parameter is declared incorrectly. You declare it as ByVal but it should be ByRef.
That said, -2147467259 is a bit of an oddity. That's not a Win32 error code. That's a COM HRESULT. Specifically it's 0x80004005. Which is the COM wrapper around the Win32 ERROR_ACCESS_DENIED. Not sure where you get a COM HRESULT from in this code mind you, but it would appear that you don't have sufficient rights for what you are attempting.

Memory Address Read/Write VB Process

When i am Running this Block of code it runs, however when i try to change the running process memory address's string value to somethinhg else it give me an error:
"System.IndexoutofRangeException Index was outside the Bounds of the Array"
These are the Functions:
<DllImport("kernel32.dll", SetLastError:=True)> _
Public Shared Function WriteProcessMemory(ByVal hProcess As IntPtr, ByVal lpBaseAddress As IntPtr, ByVal lpBuffer As Byte(), ByVal nSize As System.UInt32, <Out()> ByRef lpNumberOfBytesWritten As Int32) As Boolean
End Function
Public Shared Function StrToByteArray(ByVal str As String) As Byte()
Dim encoding As New System.Text.ASCIIEncoding()
Return encoding.GetBytes(str)
End Function
Public Shared Function Poke(ByVal proc As Process, ByVal target As Integer, ByVal data As Byte()) As Boolean
Return WriteProcessMemory(proc.Handle, New IntPtr(target), data, data.Length, 0)
End Function
This is the button which executes the changed memory address value string.
Private Sub saveButton_Click(sender As Object, e As EventArgs) Handles saveButton.Click
Try
Dim p As Process() = Process.GetProcessesByName(AppName.Text)
Dim Written As Boolean = False
Written = Poke(p(0), &HB8FDCC, StrToByteArray(TxtVal.Text))
If Written = True Then
MsgBox("WriteProcessMemory Sucess!", MsgBoxStyle.OkOnly, "Poke Memory Status")
ElseIf Written = False Then
MsgBox("WriteProcessMemory Failed!", MsgBoxStyle.OkOnly, "Poke Memory Status")
End If
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
End Class
Do not add the extension of program/application in the name of Process,
in your case, for Chrome
AppName.Text must be "Chrome" instead of "Chrome.exe",
Good Luck.