I am trying to use the WinSCP COM library on a old VB6 project I have (it's a legacy application that generates an OCX file, I think we have to use VB6 for it but not 100% sure).
Anyway we want to implement SFTP, and WinSCP can do that readily.
I registered the COM object, and can see the WinSCPNet type library when I go to add the reference. However I can't see the properties/methods of the classes when I look at the library in the object browser. Further, this code fails, it does not get to the 3rd MsgBox ("In SendWinSCP4"), it returns from the function at that point, I think because the property UserName is not exposed.
MsgBox ("in SendWinSCP")
Dim session As WinSCPnet.session
Dim sessionOptions As WinSCPnet.sessionOptions
Dim transferOptions As WinSCPnet.transferOptions
Set session = New WinSCPnet.session
Set sessionOptions = New WinSCPnet.sessionOptions
Set transferOptions = New WinSCPnet.transferOptions
MsgBox ("in SendWinSCP3")
sessionOptions.Protocol = Protocol_Sftp
sessionOptions.HostName = "example.com"
sessionOptions.UserName = "user"
sessionOptions.Password = "example.com"
sessionOptions.SshHostKeyFingerprint = "ssh-rsa 2048 xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx"
MsgBox ("in SendWinSCP4 " & sessionOptions.HostName & "!")
See above, using On Error Resume Next got me past the error.
Related
I would like to create a LotusScript "script" which would add a specified database to a users workspace. What is the best way to create and , especially, distribute such a script to the users? The users have Microsoft Outlook email and do not use Lotus Notes mail.
You can just call an URL like Notes://Server/Path/Database.nsf from an email you can send to your users.
You can find more details about URL syntax here
In your answer you have two questions: create script and distribute it.
0. LotusScript for adding database icons
You can use NotesUIWorkspace.AddDatabase method to add database icons to a users workspace:
Dim ws As New NotesUIWorkspace
'...
ws.AddDatabase("Your DB0 Server", "Your DB0 FilePath")
ws.AddDatabase("Your DB1 Server", "Your DB1 FilePath")
ws.AddDatabase("Your DB2 Server", "Your DB2 FilePath")
'...
1. Distribution of any script
You can send the Notes URL to users which would run your script. For this you need to create a Form which run your script in the PostOpen event:
Sub Postopen(Source As Notesuidocument)
Dim ws As New NotesUIWorkspace
'Your script here
Call ws.CurrentDocument.Close
End Sub
So, is better to create profile document with such a form and send URL of this document to users:
Dim ses As New NotesSession
Dim db As NotesDatabase
Dim doc As NotesDocument
Dim mdoc As NotesDocument
Dim body As NotesMIMEEntity
Dim stream As NotesStream
Dim nname As NotesName
Set db = ses.CurrentDatabase
Set doc = db.GetProfileDocument("YourProfileDocument")
ses.ConvertMIME = False
Set mdoc = db.CreateDocument
mdoc.SendTo = "Your_users_mail#domain.foo"
mdoc.Subject = "Take a look"
Set stream = ses.CreateStream
Set body = mdoc.CreateMIMEEntity
Set nname = ses.CreateName(db.Server)
Call stream.WriteText({Please open this link.})
Call body.SetContentFromText(stream, "text/html;charset=utf-8", ENC_IDENTITY_8BIT)
Call mdoc.Send(False)
In other hand if you want just to add some databases without any computations then you don't need such a script. As suggested by Knut Herrmann:
You could just call an URL like Notes://Server/Path/Database.nsf.
But beware, it does not add database icons to workspace in earlier versions of Lotus Notes (7 or earlier).
I am trying to list QC11 project and domain name in combo box on form load() but I am getting error object required,code I am using:
Dim tdc As New TDAPIOLELib.TDConnection
Dim projectList As Customization
Dim Project As Customization
Dim Domain As Customization
Set tdc = CreateObject("TDApiOle80.TDConnection")
tdc.InitConnectionEx "https://xyz/omu"
For Each Domain In TheTDConnection.DomainsList
Set projectList = tdc.GetAllVisibleProjectDescriptors
For Each Project In projectList
ComboBox1.AddItem (Project.Name)
ComboBox2.AddItem (Project.DomainName)
Next Project
Next Domain
If that's really the code you are using, then for a start this line is probably generating an error:
For Each Domain In TheTDConnection.DomainsList
Based on the rest of your code "TheTDConnection" should be "tdc":
For Each Domain In tdc.DomainsList
Oh, and to be doing this you should almost certainly be logged in first by calling tdc.Login... rather than just connected to the server.
On a related note, the DomainsList property is deprecated. I think you can just loop through the List of ProjectDescriptor objects returned by GetAllVisibleProjectDescriptors since that covers all projects under all domains that the current logged on user has access to.
Edit: this is a complete solution based on the original question. Here's working tested code that will cycle through the domains/projects that the provided user has access to. This assumes you have the QC/ALM Connectivity add-in installed (required).
If you are running this piece of VBScript on a 64 bit machine you need to run it using the 32bit version of wscript.exe: C:\Windows\SysWOW64\wscript.exe "c:\somewhere\myscript.vbs"
msgbox "Creating connection object"
Dim tdc
Set tdc = CreateObject("TDApiOle80.TDConnection")
msgbox "Connecting to QC/ALM"
tdc.InitConnectionEx "http://<yourServer>/qcbin/"
msgbox "Logging in"
tdc.Login "<username>", "<password>"
Dim projDesc
msgbox "Getting project descriptors"
Set projectDescriptors = tdc.GetAllVisibleProjectDescriptors
For Each desc In projectDescriptors
msgbox desc.DomainName & "\" & desc.Name
Next
msgbox "Logging out"
tdc.Logout
msgbox "Disconnecting"
tdc.Disconnect
msgbox "Releasing connection"
tdc.ReleaseConnection
Edit 2:
If you want to parse the resulting XML from sa.GetAllDomains into a list of ALL domain\project items on the server you can do this (This is VBScript since the original question & tag still mention it, and has been tested):
Set objDoc = CreateObject("MSXML.DOMDocument")
objDoc.Load "C:\yourXmlFile.xml"
Set objRoot = objDoc.documentElement
For Each domain in objRoot.selectNodes("TDXItem")
For Each project in domain.selectNodes("PROJECTS_LIST/TDXItem")
msgbox domain.selectSingleNode("DOMAIN_NAME").text & "\" & project.selectSingleNode("PROJECT_NAME").text
Next
Next
I've been looking for a way to get Active Directory's LDAP server url from code running as domain user. The code needs to work correctly in situation with disjoint namespace, if possible. It's unmanaged code so any .NET solutions are not an option unfortunately.
For some reason serverless binding doesn't seem to be working in this case with ADO query returning unhelpful One or more errors occurred during processing of command error when using LDAP://DC=mycompany,DC=local (that's the value of the defaultNamingContext attribute of rootDSE object).
Using the LOGONSERVER and USERDNSDOMAIN environment variables doesn't appear to be an option either because the code also needs to be able to run under the SYSTEM account and there are no such variables there.
Any ideas or hints or specific RTFM advice will be much appreciated.
Update: The DNSHostName attribute of rootDSE seems to be what I need.
I use this Visual Basic Script (VBS). Save the code as .vbs file and use ANSI charset. This script is old, but this can guide you to a better solution.
Set cn = CreateObject("ADODB.Connection")
Set cmd= CreateObject("ADODB.Command")
cn.Provider = "ADsDSOObject;"
cn.open
cmd.ActiveConnection = cn
' Root DSE required to get the default configuration naming context to
' be used as the root of the seach
set objRootDSE = getobject("LDAP://RootDSE")
' Construct the LDAP query that will find all the domain controllers
' in the domain
ldapQuery = "<LDAP://" & objRootDSE.Get("ConfigurationNamingContext") & _
">;((objectClass=nTDSDSA));ADsPath;subtree"
cmd.CommandText = ldapQuery
cmd.Properties("Page Size") = 1000
Set rs = cmd.Execute
do while rs.EOF <> True and rs.BOF <> True
' Bind to the domain controller computer object
' (This is the parent object of the result from the query)
set objDC = getobject(getobject(rs(0)).Parent)
wscript.echo objDC.dNSHostName
rs.MoveNext
Loop
cn.close
The DNSHostName attribute of rootDSE seems to be what I need.
I am trying to update an VBA module to use the System.Windows.Forms.FolderBrowserDialog class. I declared my object as follows:
Dim MyFolderBrowser As New System.Windows.Forms.FolderBrowserDialog
Running this gave me the error User-defined type not defined. I figured the compiler didn't know about that class so I tried going to Tools > References and adding Systems_Windows_Forms, but I'm still getting the same error. Does anyone know what I'm missing here? Do I need a reference to the library in my code as well?
System.Windows.Forms.FolderBrowserDialog looks like something from .Net to me, not VBA.
You can use Application.FileDialog in Access VBA. This sample uses late binding and allows the user to select a folder from a browse dialog.
Const msoFileDialogFolderPicker As Long = 4
Dim objFileDialog As Object ' FileDialog
Set objFileDialog = Application.FileDialog(msoFileDialogFolderPicker)
With objFileDialog
.AllowMultiSelect = False
If .Show Then
Debug.Print .SelectedItems(1)
End If
End With
If you prefer to use early binding, set a reference to the Microsoft Office [version] Object Library. You could then declare the object like this ...
Dim objFileDialog As FileDialog
And you wouldn't need to define the constant, so discard this line if using early binding ...
Const msoFileDialogFolderPicker As Long = 4
I have a test project I'm using to familiarise myself with VB6. Just a listbox, a button to get info, and a button to clear info:
Code:
Option Explicit
Private Sub btnGet_Click()
lstResults.DataSource = GetMenuItems
End Sub
Private Sub btnClear_Click()
lstResults.Clear
End Sub
Public Function GetMenuItems() As ADODB.Recordset
Dim rs As ADODB.Recordset
Dim conn As New ADODB.Connection
conn.ConnectionString = "File Name=C:\connString.udl"
Dim cmd As New ADODB.Command
Set cmd.ActiveConnection = conn
cmd.CommandType = adCmdStoredProc
cmd.CommandText = "dbo.GetMenuItems"
Set rs = cmd.Execute()
GetMenuItems = rs
End Function
The following error appears when I click the Get Items button (btnGet):
Compile Error: Method or Data Member Not Found
At first I thought it might be something to do with the event/button, that some sort of binding between them wasn't present. But just putting in something like "MsgBox("Hello")" works fine. Yet it doesn't even seems to get to the line where the GetMenuItems function is called before throwing the error.
This being my first whirl with VB, I'm a little stumped.
EDIT - I've had a look at the UDL file I was using too. Tested that and its connecting ok on its own.
In Sub btnGet_Click, use
Set lstResults.DataSource = GetMenuItems
Assigning object references without using Set is hardly ever the right thing to do. For what it's worth, omitting Set references the left-hand side's default property; this was part of VB6 (OK, VB4, when classes were introduced) as a help to VB3 programmers, before there were such things as objects. Whatever kind of object lstResults.DataSource returns likely does not have a default property, leading to the "Method or data member not found" error.
You've got a private sub btnGet_Click() calling a public function GetMenuItems(), which may cause problems.
Also I'm not sure you can use a udl as the connection string. Instead, open the UDL (you may need to change the file extension to .txt temporarily), take the connection string out, and use that in place of the file name.
Also, check the stored procedure exists dbo.GetMenuItems