Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: VB6 ja cmd (VB.NET)

Sivun loppuun

viljami [03.11.2010 10:55:23]

#

Eli miten lähteä ratkaisemaan ongelmaa. Yritän käyttää VB6:lla cmd:tä saan ensimmäisen käskyn menemään läpi, mutta kaikki cmd:ssä tapahtuva ei onnistu aina hetkessä, joten pitää hetki odotella, ennenkuin voidaan antaa uusi käsky. Eli yksinkertaisetettuna..

Annan VB:llä käskyn:

n = Shell("cmd.exe /c ftp")

Ja kaikki toimii, mutta kuinka voin antaa seuraavan käskyn, kun tuo ftp ohjelma on auki. Esimerkiksi "open 192.x.x.x" Ja sitten perään vaikkapa "send a.txt a.txt"

-Viljami-

Grez [03.11.2010 11:07:56]

#

Suosittelen tekemään ennemmin vaikka VB.Netillä. Sillä on huomattavasti helpompaa avata prosessi jonka kanssa voi keskustella. Toki VB6:llakin onnistuu WinAPIa käyttäen, mutta mitään järkeä ei ole tehdä uusia ohjelmia kielellä, jonka tuki on loppunut yli kaksi vuotta sitten.

viljami [03.11.2010 11:35:53]

#

Tiedetään... Ja harmittaa, kun en ole juurikaan kerennyt tuohon nettiin perehtyä ja tarttis tässä tehdä suurinpiirtein nopealla tahdilla käyttöliittymä missä tarvii pyöräyttää kolme cmd ohjelmaa läpi joista yksi on tämä ftp...

Taidan sitten siirtyä toiseksi vahvimman kielen pariin ja tehdä C++ cmd ohjelman jossa sitten kutsutaan näitä loppuja ohjelmia, mahtaa olla helpompi sitä kautta...

Metabolix [03.11.2010 17:27:58]

#

Ei mahda C++:lla olla yhtään sen helpompaa, päinvastoin.

Yksi helppo ratkaisu on kirjoittaa komennot bat-tiedostoon ja ajaa se. Ohjelmien syötteet voi myös tallentaa tiedostoihin ja syöttää ohjelmille näin:

ftp < ftpkomennot.txt

Jos ohjelman ei tarvitse tehdä muuta kuin ajaa muutama muu ohjelma, voisi olla viisasta toteuttaa se kokonaan bat-tiedostona ilman mitään VB:tä tms.

Macro [03.11.2010 18:27:03]

#

Se on muissakin kielissä, esimerkiksi Pythonissa, että jos annat jonkin command line-käskyn ja ohjelma jää pyörimään niin et voi suorittaa seuraavaa ennen kuin ohjelma on sulkeutunut.

Grez [03.11.2010 18:56:45]

#

Eihän tässä edes haluttu suorittaa seuraavaa, vaan antaa ohjeita tuolle käynnistetylle.

Olen kyllä tehnyt taannoin tuon kysytyn koodin vb6:lla mutta tuntuisi hieman väärältä julkaista se, koska se vaan kannustaisi jatkamaan tuhoon tuomitulla tiellä.

neau33 [03.11.2010 22:01:01]

#

Moikka viljami!

tässä toimiva systeemi VB6/VBA ympäristöön...

Private Declare Function ShellExecute Lib "Shell32.dll" _
Alias "ShellExecuteA" (ByVal hwnd As Long, _
ByVal lpOperation As String, ByVal lpFile As String, _
ByVal lpParameters As String, _
ByVal lpDirectory As String, ByVal nshowcmd As Long) As Long


Sub FtpTransfer(ByVal localPath As String)

   If Dir(localPath) = "" Then
      MsgBox "Tiedostoa " & localPath & " ei löydy!"
      Exit Sub
   End If

   Dim batchPath As String
   Dim remoteFile As String
   batchPath = "C:\ftpKomento.dat"

   If InStr(localPath, "\") > 0 Then
     Dim strArray() As String
     strArray = Split(localPath, "\")
     remoteFile = strArray(UBound(strArray))
     Erase strArray
   Else
     remoteFile = localPath
   End If

   On Error Resume Next
   Kill batchPath
   If Err <> 0 Then
      Err.Clear
      On Error GoTo 0
   End If

   Open batchPath For Output As #1
   Print #1, "Open"
   Print #1, "ftp-palvelin"
   Print #1, "käyttäjätunnus"
   Print #1, "salasana"
   Print #1, "put " & localPath _
   & " " & remoteFile & vbCrLf
   Print #1, "Quit": Close #1

   Do While Dir(batchPath) = "": Loop

   z& = ShellExecute(Me.hwnd, vbNullString, _
   "ftp.exe", "-s:" + batchPath, "C:\", 2)
   '(VBA:ssa - Application.hwnd)

End Sub

Grez [03.11.2010 22:07:14]

#

Onneksi muilla ei näytä olevan eettistä ongelmaa asiassa :D (tosin tuo ratkaisu ei ole ihan se mitä ajattelin - joskin toiminee FTP:n kanssa jos ei tulle ylläreitä)

Merri [03.11.2010 23:55:05]

#

Suurin ongelmahan tuossa on, ettei siinä ole minkäänlaista hallintaa ongelmien varalta. Mitä jos FTP ei yhdisty tai jos yhteys katkeaa kesken kaiken? Jos ohjelma tulee jonkun toisen käyttöön, niin sieltä tulee hyvä bugiraportti: "se ei toimi".

Näiden virhetilanteiden hallitsemista varten on oikeastaan pakko käyttää jonkinlaista FTP-luokkaa tai -kontrollia (tai sitten valmista ActiveX-kontrollia tai DLL-kirjastoa). Tämä linkittämäni versio on simppelihkö, toteuttaa itsensä kontrollina ja sorsan näkee, jolloin sitä voi myös muuttaa, esim. tehdä oman version luokkana.

Nean esimerkin ongelmana on vielä se, että se tallentaa C-aseman juureen Windowsin tallennuskäytäntöjen vastaisesti. Koodi ei taida edes toimia Vistalla ja Seiskalla, XP toki hyrrää kitkatta kun sillä ei ole niin paljon käyttöoikeuksiin tehtyjä rajoituksia.

neau33 [04.11.2010 03:47:10]

#

Heippa taas!

tässä vielä systeemi joka antaa palautetta...

Private Sub Command1_Click()
   'Testi esimerkki...

   Dim localPath As String
   Environ("HOMEDRIVE")

   localPath = Environ("HOMEDRIVE") & "\polku\tiedosto.ext"

   If Dir(localPath) = "" Then
      MsgBox "Tiedostoa " & localPath & " ei löydy!"
      Exit Sub
   End If

   Dim remoteFile As String

   If InStr(localPath, "\") > 0 Then
     Dim strArray() As String
     strArray = Split(localPath, "\")
     remoteFile = strArray(UBound(strArray))
     Erase strArray
   Else
     remoteFile = localPath
   End If

   Dim cmdstr As string
   cmdstr = "put " & localPath & " " & remoteFile & vbCrLf

   MsgBox FtpTransfer("server", "user", "password", cmdstr)

End Sub

Function FtpTransfer(ByVal server As String, _
ByVal user As String, ByVal password As String,
ByVal cmdstr As String) As String

   Dim basePath As String
   basePath = Environ("APPDATA") & "\ftpStuff"

   If Dir(basePath, vbDirectory) = "" Then
      MkDir basePath
   End If

   Dim cmdPath As String, resPath As String
   cmdPath = basePath & "\ftpCommand.dat"
   resPath = basePath & "\ftpResult.txt"

   KillFile cmdPath: KillFile resPath

   Open cmdPath For Output As #1
   Print #1, "Open"
   Print #1, server
   Print #1, user
   Print #1, password
   Print #1, cmdstr
   Print #1, "Quit": Close #1

   Do While Dir(cmdPath) = "": Loop
   Shell "cmd.exe /c ftp.exe -s:" _
   & cmdPath & " >" & resPath

   Do While Dir(resPath) = "": Loop
   Open resPath For Input As #1

   FtpTransfer = Input$(LOF(1), 1): Close #1

   KillFile cmdPath: KillFile resPath

End Function

Sub KillFile(ByVal fullPath As String)

   On Error Resume Next
   Kill fullPath
   If Err <> 0 Then
      Err.Clear
      On Error GoTo 0
   End If

End Sub

neau33 [04.11.2010 08:34:31]

#

Heippa taas!

heitin ton edellisen testaamatta suoraan hatusta, mutta tämä toimii...

Private Sub CommandButton1_Click()

   Dim localPath As String

   localPath = Environ("HOMEDRIVE") & "\folderpath\filename.ext"

   If Dir(localPath) = "" Then
      MsgBox "Tiedostoa " & localPath & " ei löydy!"
      Exit Sub
   End If

   Dim remoteFile As String

   If InStr(localPath, "\") > 0 Then
     Dim strArray() As String
     strArray = Split(localPath, "\")
     remoteFile = strArray(UBound(strArray))
     Erase strArray
   Else
     remoteFile = localPath
   End If

   Dim cmdstr As String
   cmdstr = "put " & localPath & " " & remoteFile & vbCrLf

   MsgBox FtpAction("ServerAddress", "YourUserName", "YourPassword", cmdstr)

End Sub

Function FtpAction(ByVal server As String, _
ByVal user As String, ByVal password As String, _
ByVal cmdstr As String) As String

   Dim basePath As String
   basePath = Environ("HOMEDRIVE") & "\ftpStuff"
   If Dir(basePath, vbDirectory) = "" Then
      MkDir basePath
      Do While Dir(basePath, vbDirectory) = "": Loop
   End If


   Dim cmdPath As String, resPath As String
   cmdPath = basePath & "\ftpCommand.dat"
   resPath = basePath & "\ftpResult.txt"

   KillFile cmdPath: KillFile resPath

   Open cmdPath For Output As #1
   Print #1, "Open"
   Print #1, server
   Print #1, user
   Print #1, password
   Print #1, cmdstr
   Print #1, "Quit": Close #1

   Do While Dir(cmdPath) = "": Loop
   Shell "cmd.exe /c ftp.exe -s:" _
   & cmdPath & " >" & Chr(34) & resPath & Chr(34)

JumpBack:

   'ohjelma vaatii referenssin:
   'Microsoft WMI Scripting V1.2 Library
   '(C:\Windows\System32\wbem\wbemdisp.tlb)

   Set MyProcesses = GetObject _
   ("winmgmts:{impersonationLevel=impersonate}") _
   .InstancesOf("Win32_Process")
   For Each MyProcess In MyProcesses
      With MyProcess
         If LCase(.Name) = "cmd.exe" Then
           GoTo JumpBack
         End If
      End With
   Next

   Set MyProcesses = Nothing
   Do While Dir(resPath) = "": Loop

   Open resPath For Input As #1
   FtpAction = Input$(LOF(1), 1): Close #1

   KillFile cmdPath: KillFile resPath

End Function

Sub KillFile(ByVal fullPath As String)

   On Error Resume Next
   Kill fullPath
   If Err <> 0 Then
      Err.Clear
      On Error GoTo 0
   End If

End Sub

viljami [04.11.2010 11:50:44]

#

Moi,

Kiitos eritoten Nealle, sekä myös muille. Eilen illalla istahdin koneelle, ja kirjoitin batin googlen avulla, jolla ajan nuo kolme exeä läpi. Käytännössä minulla on tiedosto, joka ensin parseroidaan yhdellä exellä, sitten käännetään toisella exellä ja lopuksi siirretään serverille käyttäen FTP:tä.

Tällä saatiin nyt tehtyä ne asiat, joita pitikin saada. Tosin tekemättä on edelleen graaffinen käyttöliittymä, joten tässä hyvää mallia, siihen kuinka tuo tehdään.

Kiitos vielä oikein kovasti!


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta