Getting vbscript to wait until a file is present - vbscript

I'm trying to write an application that sends and receives service calls from a pc to a mobile phone.
I'm using a program called mobile data studio to do most of the work.
Basically the program generates a web-page as its report for a customer and this is mailed to the customer by the system which i have working
The problem is that the system does not wait until the file is generated before it tries to send it as an attachment and i get an error:
CDO.Message1
The system cannot find the file specified.
Position: 58.0
this is the code:
objmessage.Addattachment sFile
Once I click OK on the error the file is then created and if I run the script again it process the mail and the attachment and opens the file if fax is set to "yes" also.
This is all the code:
' Process incoming sessions from Pocket PCs
Function OnIncomingSession (theSession)
' Check if the user indicated a confirmation was desired
If theSession("SendEmail") = "Yes" Then
sendobjMessage theSession
ElseIf theSession("SendFax") = "Yes" Then
sendobjfax theSession
End If
' Set the return value to true to indicate that normal
' processing should continue
OnIncomingSession = True
End Function
Sub sendobjMessage (theSession)
' Get the email address from the session
sEmail = theSession ( "EmailAddress" )
'Get the file name from the session
sFile = "C:\htm\"& theSession("ORN")&"."&"htm"
Const cdoSendUsingPickup = 1 'Send message using the local SMTP service pickup directory.
Const cdoSendUsingPort = 2 'Send the message using the network (SMTP over the network).
Const cdoAnonymous = 0 'Do not authenticate
Const cdoBasic = 1 'basic (clear-text) authentication
Const cdoNTLM = 2 'NTLM
Set objMessage = CreateObject("CDO.Message")
objMessage.Subject = "Our Company - Service Report" & " " & theSession("rdate")
objMessage.From = """Service Department"" <user#mydomain>"
objMessage.To = sEmail
objMessage.TextBody = "Hi " & theSession("sname") & ","
objmessage.Addattachment sFile
Set objfax = CreateObject("WScript.Shell")
objfax.Run sFile
'==This section provides the configuration information for the remote SMTP server.
objMessage.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
'Name or IP of Remote SMTP Server
objMessage.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "smtp.mydomain.com"
'Type of authentication, NONE, Basic (Base64 encoded), NTLM
objMessage.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = cdoBasic
'Your UserID on the SMTP server
objMessage.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/sendusername") = "user#mydomain"
'Your password on the SMTP server
objMessage.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/sendpassword") = "password"
'Server port (typically 25)
objMessage.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25
'Use SSL for the connection (False or True)
objMessage.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/smtpusessl") = False
'Connection Timeout in seconds (the maximum time CDO will try to establish a connection to the SMTP server)
objMessage.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout") = 60
objMessage.Configuration.Fields.Update
'==End remote SMTP server configuration section==
objMessage.Send
End Sub

Option Explicit
Dim retval, fso, file
Set fso = CreateObject ("scripting.filesystemobject")
file = "c:\temp\myfile.txt"
retval = waitTilExists (file, true)
MsgBox "return value: " & retval
Function waitTilExists (ByVal file, withRepeat)
' Sleeps until the file exists
' The polling interval will increase gradually, but never rises above MAX_WAITTIME
' Times out after TIMEOUT msec. Will return false if caused by timeout.
Dim waittime, totalwaittime, rep, doAgain
Const INIT_WAITTIME = 20
Const MAX_WAITTIME = 1000
Const TIMEOUT = 5000
Const SLOPE = 1.1
doAgain = true
Do While doAgain
waittime = INIT_WAITTIME
totalwaittime = 0
Do While totalwaittime < TIMEOUT
waittime = Int (waittime * SLOPE)
If waittime>MAX_WAITTIME Then waittime=MAX_WAITTIME
totalwaittime = totalwaittime + waittime
WScript.sleep waittime
If fso.fileExists (file) Then
waitTilExists = true
Exit Function
End If
Loop
If withRepeat Then
rep = MsgBox ("This file does not exist:" & vbcr & file & vbcr & vbcr & "Keep trying?", vbRetryCancel+vbExclamation, "File not found")
doAgain = (rep = vbRetry)
Else
doAgain = false
End If
Loop
waitTilExists = false
End Function

I might have some helpful tools.
I get the impression that you need:
Routine that creates a delay or pause of a certain period of time
Routine that checks for a file's existence.
Here's a routine for creating a delay or pause:
Sub subSleep(strSeconds) ' subSleep(2)
Dim objShell
Dim strCmd
set objShell = CreateObject("wscript.Shell")
'objShell.Run cmdline,1,False
strCmd = "%COMSPEC% /c ping -n " & strSeconds & " 127.0.0.1>nul"
objShell.Run strCmd,0,1
End Sub
Here's a routine for checking for a file's existence:
Function fnFileExists_Bln(strFULLNamee)
Dim strFULLName
strFULLName = strFULLNamee
Dim objFSO
Set objFSO = CreateObject("scripting.filesystemobject")
fnFileExists_Bln = objFSO.FileExists(strFULLName)
End Function ' Function fnFileExists_Bln(strFULLNamee)
I hope this helps.

Related

Can I eliminate VBS duplicated code via a global script?

I'm not overly familiar with VBS and not sure how to best approach this.
I've got this basic code to work whereby when a value from a machine >= 100 it send out an email. The WinCC triggers this script whenever the tag value changes.
Now, I want to utilise this on a number of other values to monitor parts of machinery and equipment and send out some email alerts.
But, is there any need to replicate the whole email settings code in every script or is there a way that the triggered code can call a global script with the email settings in?
So instead of "Triggered VBS - Check Value - If True - Here's email details - Send Email"
Its more like "Triggered VBS - Check Value - If True - Load Email Setting VBS - Send Email"
Hope that makes sense?
Option Explicit
Function action
Dim TagVari1
Dim TagVari2
Set TagVari1 = HMIRuntime.Tags("TestTag1")
TagVari1.Read
TagVari1.Value = TagVari1.Value +1
Set TagVari2 = HMIRuntime.Tags("TestTag2")
TagVari2.Read
TagVari2.Value = TagVari1.Value
TagVari2.Write
If TagVari2.Value >= 100 Then
Dim objMessage
Set objMessage = CreateObject("CDO.Message")
objMessage.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
objMessage.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "smtp.mydomain.com"
objMessage.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 465
objMessage.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = 1
objMessage.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/sendusername") = "my.email#mydomain.com"
objMessage.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/sendpassword") = "password"
objMessage.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/smtpusessl") = True
objMessage.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout") = "30"
objMessage.Configuration.Fields.Update
objMessage.Subject = "WinCC Message"
objMessage.From = "my.email#mydomain.com"
objMessage.To = "recip.email#outlook.com"
objMessage.TextBody = "This is a test message from WinCC......"
objMessage.Send
x=Msgbox("CHP Alarm" ,0, "Tag2 equal or over 100")
End If
End Function
Here's how to include another *.vbs, courtesy of Frank-Peter Schultze
Put this Sub in your main script(s):
'------------------------------------------------------------------------------
'Purpose : Include another VBScript file into the current one.
'Note : Usage: Include("vbsfile.vbs")
'
' Author: Frank-Peter Schultze
' Source: http://www.fpschultze.de/smartfaq+faq.faqid+51.htm
'------------------------------------------------------------------------------
Sub Include(ByVal strFilename)
Dim objFileSys, objFile, strContent
Set objFileSys = WScript.CreateObject("Scripting.FileSystemObject")
Set objFile = objFileSys.OpenTextFile(strFilename, 1)
strContent = objFile.ReadAll
objFile.Close
Set objFileSys = Nothing
ExecuteGlobal strContent
End Sub
'------------------------------------------------------------------------------
Have your email send routine in another script, e.g. MySendMail.vbs
And then somewhere at the start of your main script call it like
Include("Full\Path\To\MySendMail.vbs")
And that's the one caveat: the included filename must be passed to the Sub with its full path including drive.

Ping function makes the whole excel table slow/unresponsive

I have a function that pings computers from an excel list and gets the ping value of them.
While the script was running, the excel was completely unresponsive. I could fix this with DoEvents, this made it a bit more responsive.
However, the problem starts when the function gets to an offline computer. While it waits for the response of the offline PC, Excel freezes again and the script does not jump to the next PC until it gets the "timeout" from the actual one.
As the default ping timeout value is 4000ms, if I have 100 computers in my list, and 50 of them are turned off, that means I have to wait an extra 3,3 minutes for the script to finish, and also blocks the entire Excel, making it unusable for the duration.
My question is, if is there any way to make this faster or more responsive or smarter?
The actual code:
Function:
Function sPing(sHost) As String
Dim oPing As Object, oRetStatus As Object
Set oPing = GetObject("winmgmts:{impersonationLevel=impersonate}").ExecQuery _
("select * from Win32_PingStatus where address = '" & sHost & "'")
DoEvents
For Each oRetStatus In oPing
DoEvents
If IsNull(oRetStatus.StatusCode) Or oRetStatus.StatusCode <> 0 Then
sPing = "timeout" 'oRetStatus.StatusCode <- error code
Else
sPing = sPing & vbTab & oRetStatus.ResponseTime
End If
Next
End Function
Main:
Sub pingall_Click()
Dim c As Range
Dim p As String
Dim actives As String
actives = ActiveSheet.Name
StopCode = False
Application.EnableCancelKey = xlErrorHandler
On Error GoTo ErrH:
DoEvents
For Each c In Sheets(actives).UsedRange.Cells
If StopCode = True Then
Exit For
End If
DoEvents
If Left(c, 7) = "172.21." Then
p = sPing(c)
[...]
End If
Next c
End Sub
As already noted in the comments, to prevent this from blocking after each call, you need to invoke your pings asynchronously from your function. The way I would approach this would be to delegate your sPing(sHost) function to a VBScript that you create on the fly in a temp folder. The script would look something like this, and it takes the IP address as a command line argument and outputs the result to a file:
Dim args, ping, status
Set ping = GetObject("winmgmts:{impersonationLevel=impersonate}").ExecQuery _
("select * from Win32_PingStatus where address = '" & Wscript.Arguments(0) & "'")
Dim result
For Each status In ping
If IsNull(status.StatusCode) Or status.StatusCode <> 0 Then
result = "timeout"
Else
result = result & vbTab & status.ResponseTime
End If
Next
Dim fso, file
Set fso = CreateObject("Scripting.FileSystemObject")
Set file = fso.CreateTextFile(Wscript.Arguments(0), True)
file.Write result
file.Close
You can create a Sub to write this to a path something like this:
Private Sub WriteScript(path As String)
Dim handle As Integer
handle = FreeFile
Open path & ScriptName For Output As #handle
Print #handle, _
"Dim args, ping, status" & vbCrLf & _
"Set ping = GetObject(""winmgmts:{impersonationLevel=impersonate}"").ExecQuery _" & vbCrLf & _
" (""select * from Win32_PingStatus where address = '"" & Wscript.Arguments(0) & ""'"")" & vbCrLf & _
"Dim result" & vbCrLf & _
"For Each status In ping" & vbCrLf & _
" If IsNull(status.StatusCode) Or status.StatusCode <> 0 Then" & vbCrLf & _
" result = ""timeout""" & vbCrLf & _
" Else" & vbCrLf & _
" result = result & vbTab & status.ResponseTime" & vbCrLf & _
" End If" & vbCrLf & _
"Next" & vbCrLf & _
"Dim fso, file" & vbCrLf & _
"Set fso = CreateObject(""Scripting.FileSystemObject"")" & vbCrLf & _
"Set file = fso.CreateTextFile(Wscript.Arguments(0), True)" & vbCrLf & _
"file.Write result" & vbCrLf & _
"file.Close"
Close #handle
End Sub
After that, it's pretty straightforward - create a new directory in the user's temp directory, plop the script in there, and then use the Shell command to run each ping in its own process. Wait for the length of your timeout, then read the results from the files:
Private Const TempDir = "\PingResults\"
Private Const ScriptName As String = "ping.vbs"
'Important - set this to the time in seconds of your ping timeout.
Private Const Timeout = 4
Sub pingall_Click()
Dim sheet As Worksheet
Set sheet = ActiveSheet
Dim path As String
'Create a temp folder to use.
path = Environ("Temp") & TempDir
MkDir path
'Write your script to the temp folder.
WriteScript path
Dim results As Dictionary
Set results = New Dictionary
Dim index As Long
Dim ip As Variant
Dim command As String
For index = 1 To sheet.UsedRange.Rows.Count
ip = sheet.Cells(index, 1)
If Len(ip) >= 7 Then
If Left$(ip, 1) = "172.21." Then
'Cache the row it was in.
results.Add ip, index
'Shell the script.
command = "wscript " & path & "ping.vbs " & ip
Shell command, vbNormalFocus
End If
End If
Next index
Dim completed As Double
completed = Timer + Timeout
'Wait for the timeout.
Do While Timer < completed
DoEvents
Loop
Dim handle As String, ping As String, result As String
'Loop through the resulting files and update the sheet.
For Each ip In results.Keys
result = Dir$(path & ip)
If Len(result) <> 0 Then
handle = FreeFile
Open path & ip For Input As #handle
ping = Input$(LOF(handle), handle)
Close #handle
Kill path & ip
Else
ping = "timeout"
End If
sheet.Cells(results(ip), 2) = ping
Next ip
'Clean up.
Kill path & "*"
RmDir path
End Sub
Note that this has exactly zero error handling for the file operations, and doesn't respond to your StopCode flag. It should give the basic gist of it though. Also note that if you need to allow the user to cancel it, you won't be able to remove the temp directory because it will still be in use. If that is the case, only create it if it isn't already there and don't remove it when you're done.
You might be able to implement something like this, but I haven't tried it with multiple servers
if your network is fast you can reduce the timeout to 500 ms or less:
.
Public Function serverOk(ByVal dbSrvrNameStr As String) As Boolean
Const PINGS As Byte = 1
Const PING_TIME_OUT As Byte = 500
Const PING_LOCATION As String = "C:\Windows\System32\"
Dim commandResult As Long, serverIsActive As Boolean
commandResult = 1
serverIsActive = False
If Len(dbSrvrNameStr) > 0 Then
Err.Clear
With CreateObject("WScript.Shell")
commandResult = .Run("%comspec% /c " & PING_LOCATION & "ping.exe -n " & PINGS & " -w " & PING_TIME_OUT & " " & dbSrvrNameStr & " | find ""TTL="" > nul 2>&1", 0, True)
commandResult = .Run("%comspec% " & PING_LOCATION & "/c ping.exe -n " & PINGS & " -w " & PING_TIME_OUT & " " & dbSrvrNameStr, 0, True)
serverIsActive = (commandResult = 0)
End With
If serverIsActive And Err.Number = 0 Then
'"DB Server - valid, Ping response: " & commandResult
Else
'"Cannot connect to DB Server, Error: " & Err.Description & ", Ping response: " & commandResult
End If
Err.Clear
End If
serverOk = serverIsActive
End Function
.
Link to "Run Method (Windows Script Host)" from Microsoft:
https://msdn.microsoft.com/en-us/library/d5fk67ky(VS.85).aspx
The 3rd parameter of this command can be overlooked: "bWaitOnReturn" - allows you to execute it asynchronously from VBA

Vbscript to ping a list of machines and check if the IP-Addresses has changed and if they have changed send a Mail

I search for a Script that pings a List of machines and if a IP has changed send a warning mail. Hope somebody can help me.
Greets Mohrjon
Is the ping sufficient information to know that the IP address has changed? - what if the network goes down for a short period of time whilst the script is running?
Anyhow these are three subs i have which i have bodged together which should do what you need
Firstly i would iterate through a text file (csv) to get my ip address, and in this case the name and email
Sub Open_Master_File()
Do While objTextFile.AtEndOfStream <> True
strLine = objTextFile.ReadLine
'skip if comment line found
If inStr(1,strLine, "'") Then
ElseIf inStr(1,strLine, ",") Then
arrayMasterFile = split(strLine, ",")
strStoreName = arrayMasterFile(0)
strComputerIP = arrayMasterFile(1)
strEmailRecipient = arrayMasterFile(2)
'Call ping function to check for online/offline computers
Call Ping_Computer()
End If
Loop
'Release Memory
objTextFile.Close()
Set objTextFile = Nothing
Set objMasterFSO = Nothing
End Sub
next i ping to each of the ip's (btw this will only show if the ip is offline, can you guarantee that the ip is online all of the time?)
Sub Ping_Computer()
Set wshShell = CreateObject("WScript.Shell")
'Run the ping program 3 times, with a 2000ms delay on each, 0 = don't display cmd prompt
'All three pings must be successful for CBool = true
pingSuccessful = Not CBool(wshShell.run("ping -n 3 -w 2000 " & strComputerIP,0,True))
If pingSuccessful = True Then
Else
Call Send_EMail()
End If
'Release memory
Set wshShell = Nothing
End Sub
Send an email
Sub Send_Email()
Set objEmail = CreateObject("CDO.Message")
strSubject = ""
strEmailFrom = ""
strBody = ""
objEmail.Subject = strSubject
objEmail.From = strEmailFrom
objEmail.To = strEmailRecipient
'Use Microsoft schemas for emails
objEmail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = cdoNTLM
objEmail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = strServer
objEmail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = cMailPort
objEmail.Configuration.Fields.Update
objEmail.Textbody = strBody
'Check if an error occurs during the send email process, do not stop program
On Error Resume Next
objEmail.Send
'error on send
If Err.Number <> 0 Then
Else
End If
'clear errors
On Error Goto 0
'Release Memory
Set objEmail = Nothing
End Sub

CDO.message vbscript - transport failed to connect

I have a vbscript on a Windows 7 machine in a branch office. It works just fine. I copied the code to a second branch office Windows 7 machine and I get an error. I'm out of ideas.
Both Windows machines have MS Outlook installed.
Do While asObj.ConnectionState = asCONN_CONNECTED
WeekDayNumber = Weekday(Now())
HourNumber = Hour(Now())
'WScript.Echo asObj.HasData
If asObj.HasData Then
WScript.Echo asObj.ReceiveString
WriteData asObj.ReceiveString
uploadData
CycleDate = Now()
asObj.Sleep 300
Else
If WeekDayNumber > 1 And WeekDayNumber < 7 And HourNumber > 8 And HourNumber < 17 Then
DiffInMinutes = DateDiff("n",CycleDate,Now())
'WScript.Echo "Day=" & WeekDayNumber & vbCrLf & "Hour=" & HourNumber & vbCrLf & "cycle=" & CycleDate & vbCrLf & "diff=" & DiffInMinutes & vbCrLf & " Now=" & Now()
If DiffInMinutes > 2 Then
SendAlertEmail
WriteData "Alert email sent " & Now() & vbCrLf
WScript.Echo cyclecounter & " no data"
CycleDate = Now()
' Sleep 5 minutes
asObj.Sleep 1000
End If
End If
End If
Loop
' And finally, disconnect
WScript.Echo "Disconnect -- we should never get to this point. Call Chris!"
asObj.Disconnect
Else
WScript.Echo "bad connection. You have to restart the script"
End If
Sub WriteData(sData)
Const ForAppending = 8
Const OutputFile = "d:\calldata\calldata_data\CallData_$DATE$mtp.txt"
Dim DateNow
Dim varDate
Dim objFile
Dim objFSO
' WScript.Echo sData
Datenow = Date()
varDate = Year(DateNow) & Right("0" & Month(DateNow), 2) & Right("0" & Day(DateNow), 2)
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile(Replace(OutputFile, "$DATE$", varDate), ForAppending, True)
objFile.WriteLine sData
objFile.Close
Set objFile = Nothing
Set objFSO = Nothing
End Sub
Sub uploadData
Dim objShell
Set objShell = Wscript.CreateObject("WScript.Shell")
objShell.Run "c:\calldata\FTPupload.vbs",10,True
objShell.Run "c:\calldata\updateCallData.vbs",10,True
' Using Set is mandatory
Set objShell = Nothing
End Sub
Sub SendAlertEmail
Set email = CreateObject("CDO.Message")
WScript.Echo "step 1"
email.Subject = "MTP - Possible phone time collection failure"
email.From = "x#gmail.com"
email.To = "x#x.com;x#x.com;x#x.com"
email.TextBody = Now() & " The collection of phone time that is done on the MTP Domain Controller seems to have failed. There has been no data for quite a while."
email.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = 1 'basic (clear-text) authentication
email.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendusername") = "x#gmail.com"
email.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendpassword") = "password"
email.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendusing")=2
email.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver")="smtp.gmail.com"
email.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport")=25
email.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpusessl") = 1
email.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout") = 30
email.Configuration.Fields.Update
email.Send
If Err Then
WScript.Echo "SendMail Failed:" & Err.Description
End If
set email = Nothing
'WScript.Echo"step 2"
End Sub
Gmail is on 465 and not enough is specified.
Here's working code
Set emailObj = CreateObject("CDO.Message")
emailObj.From = "d#gmail.com"
emailObj.To = "d#gmail.com"
emailObj.Subject = "Test CDO"
emailObj.TextBody = "Test CDO"
emailObj.AddAttachment "c:\windows\win.ini"
Set emailConfig = emailObj.Configuration
emailConfig.Fields("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "smtp.gmail.com"
emailConfig.Fields("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 465
emailConfig.Fields("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
emailConfig.Fields("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = 1
emailConfig.Fields("http://schemas.microsoft.com/cdo/configuration/smtpusessl") = true
emailConfig.Fields("http://schemas.microsoft.com/cdo/configuration/sendusername") = "d"
emailConfig.Fields("http://schemas.microsoft.com/cdo/configuration/sendpassword") = "Password1"
emailConfig.Fields.Update
emailObj.Send
If err.number = 0 then Msgbox "Done"
I have received this error before, and for me it was the security rights between one computer and another. it will be worth checking the access rights on the two machines and see if there are differences.

Programmatically add 'My Network Place' for FTP site?

Is there anyway I can create a small exe or batch file to setup a new 'My Network Place' in Windows? Its for an ftp site if that makes any difference.
XP will primarily be the target machine but If I can find something that will work on Vista too thats great.
I wrote this script to connect to a FTP using a proxy server. You could adapt it for your needs. It prompts for the filename and folder you are trying to access. Just cut the code you don't need, and you should be good to go.
You will need to change the FTP Server Name variable as well. Happy coding:
Option Explicit
Dim objShell, strFTPScriptFileName, strFile2Get
Dim strLocalFolderName, strFTPServerName, strLoginID
Dim strPassword, strFTPServerFolder, strFileToGet, returnCode
'Customize code here to fit your needs
strFTPServerName = "proxy.prv"
strLocalFolderName = ""
strLoginID = ""
strPassword = ""
strFTPServerFolder = ""
strFileToGet = ""
strLocalFolderName = GetLocalFolder()
strLoginID = InputBox("Enter FTP Username: ", "Enter FTP Username", "Authentication_Method#Destination_FTP_Host")
strPassword = InputBox("Enter FTP Password: ", "Enter FTP Password", "Authentication_Method#Destination_FTP_Host")
strFTPServerFolder = InputBox("Enter FTP folder that you want to access: ", "Enter FTP Folder", "/")
strFileToGet = InputBox("Enter the filename located on the FTP that you want to retrieve: ", "Enter FTP file", "*.*")
if strLoginID = "" then
WScript.Echo "You must specify a Login ID for this script to work"
WScript.Quit()
end if
if strPassword = "" then
WScript.Echo "You must specify a Password for this script to work"
WScript.Quit()
end if
if strFTPServerFolder = "" then
WScript.Echo "You must specify a FTP Folder to access for this script to work"
WScript.Quit()
end if
if strFileToGet = "" then
WScript.Echo "You must specify a Filename to download for this script to work"
WScript.Quit()
end if
Call WriteFTPScript()
Set objShell = WScript.CreateObject( "WScript.Shell" )
returnCode = objShell.Run( "cmd.exe /c ftp -s:" & chr(34) & strFTPScriptFileName & chr(34), 1, true)
if (returnCode = 0) then
Wscript.echo("Your file has been downloaded.")
else
Wscript.echo("An error has occured while attempting to download your file.")
End if
objShell.Run (strLocalFolderName)
Set objShell = Nothing
' **************************************************************************
' Creates the FTP script text file
Function WriteFTPScript()
Dim objFSO, objMyFile
strFTPScriptFileName = strLocalFolderName & "\FTPScript.txt" 'File to be created to hold ftp script data
Set objFSO = CreateObject("Scripting.FileSystemObject")
If (objFSO.FileExists(strFTPScriptFileName)) Then
objFSO.DeleteFile (strFTPScriptFileName)
End If
Set objMyFile = objFSO.CreateTextFile(strFTPScriptFileName, True)
objMyFile.WriteLine ("open " & strFTPServerName)
objMyFile.WriteLine (strLoginID)
objMyFile.WriteLine (strPassword)
objMyFile.WriteLine ("cd " & strFTPServerFolder)
objMyFile.WriteLine ("lcd " & strLocalFolderName)
objMyFile.WriteLine ("get " & strFileToGet)
objMyFile.WriteLine ("bye")
objMyFile.Close
Set objFSO = Nothing
Set objMyFile = Nothing
End Function
' **************************************************************************
' Dialog box to select folder to download to
Function GetLocalFolder()
Const BIF_returnonlyfsdirs = &H0001
Const BIF_editbox = &H0010
Dim wsh, objDlg, objF
Set objDlg = WScript.CreateObject("Shell.Application")
Set objF = objDlg.BrowseForFolder (&H0, "Select the destination folder to download FTP files to:", BIF_editbox + BIF_returnonlyfsdirs)
If IsValue(objF) Then
GetLocalFolder = objF.ParentFolder.ParseName(objF.Title).Path
Else
WScript.Echo "You MUST specify a folder to download files to. Application will now exit."
WScript.Quit
End If
end function
' **************************************************************************
' Verifies if the the object contains a value
Function IsValue(obj)
Dim tmp
On Error Resume Next
tmp = " " & obj
If Err <> 0 Then
IsValue = False
Else
IsValue = True
End If
On Error GoTo 0
End Function
' **************************************************************************
' Verifies if the the object is a folder
Function IsFolder(obj)
Dim objFSO
Set objFSO = CreateObject("Scripting.FileSystemObject")
if objFSO.IsFolder(obj) then
IsFolder = True
end if
End Function
Yes, there is. The NetHood folder can be manipulated with vbScript. Refer to this forum thread for more information. The following works for me on XP Pro:
Option Explicit
On Error Goto 0
'ShellSpecialFolderConstants
Const ssfNETHOOD = 19 '(&H13) Special Folder NETHOOD
Dim objWSHShell, objShell, objFolder, objFolderItem, strNetHood
Dim strShortcutName, strShortcutPath, objShortcut
Set objWSHShell = CreateObject("Wscript.Shell")
Set objShell = CreateObject("Shell.Application")
Set objFolder = objShell.Namespace(ssfNETHOOD)
Set objFolderItem = objFolder.Self
strNetHood = objFolderItem.Path
strShortcutName = "FTP to localhost"
strShortcutPath = "ftp://username#localhost/"
Set objShortcut = objWSHShell.CreateShortcut(strNetHood & "\" & strShortcutName & ".lnk")
objShortcut.TargetPath = strShortcutPath
objShortcut.Save

Resources