I'm updating an installer and need to create a Windows group and add (existing) users to that group.
The users are IIS pseudo-users, ie IIS APPPOOL\username
Is there a simple way to do this using VB6 or VB.NET? I can't find an obvious library/API or any example code
Thanks
You can try the following code extracted from this link to create users. Basically it uses the API NetUserAdd.
Option Explicit
' ---------------------------------------------
' The USER_INFO_3 data structure
' ---------------------------------------------
Private Type USER_INFO_3
usri3_name As Long
usri3_password As Long
usri3_password_age As Long
usri3_priv As Long
usri3_home_dir As Long
usri3_comment As Long
usri3_flags As Long
usri3_script_path As Long
usri3_auth_flags As Long
usri3_full_name As Long
usri3_usr_comment As Long
usri3_parms As Long
usri3_workstations As Long
usri3_last_logon As Long
usri3_last_logoff As Long
usri3_acct_expires As Long
usri3_max_storage As Long
usri3_units_per_week As Long
usri3_logon_hours As Long
usri3_bad_pw_count As Long
usri3_num_logons As Long
usri3_logon_server As Long
usri3_country_code As Long
usri3_code_page As Long
usri3_user_id As Long
usri3_primary_group_id As Long
usri3_profile As Long
usri3_home_dir_drive As Long
usri3_password_expired As Long
End Type
' ---------------------------------------------
' Possible errors with API call
' ---------------------------------------------
Private Const ERROR_ACCESS_DENIED As Long = 5
Private Const NERR_BASE As Long = 2100
Private Const NERR_GroupExists As Long = NERR_BASE + 123
Private Const NERR_NotPrimary As Long = NERR_BASE + 126
Private Const NERR_UserExists As Long = NERR_BASE + 124
Private Const NERR_PasswordTooShort As Long = NERR_BASE + 145
Private Const NERR_InvalidComputer As Long = NERR_BASE + 251
Private Const NERR_Success As Long = 0&
Private Const TIMEQ_FOREVER As Long = -1&
Private Const DOMAIN_GROUP_RID_USERS As Long = &H201&
Private Const USER_MAXSTORAGE_UNLIMITED As Long = -1&
Private Const constUserInfoLevel3 As Long = 3
' ---------------------------------------------
' Used by usri3_flags element of data structure
' ---------------------------------------------
Private Const UF_SCRIPT As Long = &H1&
Private Const UF_ACCOUNTDISABLE As Long = &H2&
Private Const UF_HOMEDIR_REQUIRED As Long = &H8&
Private Const UF_LOCKOUT As Long = &H10&
Private Const UF_PASSWD_NOTREQD As Long = &H20&
Private Const UF_PASSWD_CANT_CHANGE As Long = &H40&
Private Const UF_DONT_EXPIRE_PASSWD As Long = &H10000
Private Const STILL_ACTIVE As Long = &H103&
Private Const UF_NORMAL_ACCOUNT As Long = &H200&
Private Const UF_SERVER_TRUST_ACCOUNT As Long = &H2000&
Private Const PROCESS_QUERY_INFORMATION As Long = &H400&
Private Const UF_TEMP_DUPLICATE_ACCOUNT As Long = &H100&
Private Const UF_INTERDOMAIN_TRUST_ACCOUNT As Long = &H800&
Private Const UF_WORKSTATION_TRUST_ACCOUNT As Long = &H1000&
Private Declare Function NetUserAdd Lib "netapi32.dll" (ServerName As Byte, ByVal Level As Long, Buffer As USER_INFO_3, parm_err As Long) As Long
Private Declare Function NetApiBufferAllocate Lib "netapi32.dll" (ByVal ByteCount As Long, Ptr As Long) As Long
Private Declare Function NetApiBufferFree Lib "Netapi32" (ByVal pBuffer As Long) As Long
' *******************************************************
' Add a user either to NT -- you *MUST* have admin or
' account operator privileges to successfully run
' this function
' Use on NT Only
' *******************************************************
Public Function AddUser(ByVal xi_strServerName As String, _
ByVal xi_strUserName As String, _
ByVal xi_strPassword As String, _
Optional ByVal xi_strUserFullName As String = vbNullString, _
Optional ByVal xi_strUserComment As String = vbNullString) As Boolean
Dim p_strErr As String
Dim p_lngRtn As Long
Dim p_lngPtrUserName As Long
Dim p_lngPtrPassword As Long
Dim p_lngPtrUserFullName As Long
Dim p_lngPtrUserComment As Long
Dim p_lngParameterErr As Long
Dim p_lngFlags As Long
Dim p_abytServerName() As Byte
Dim p_abytUserName() As Byte
Dim p_abytPassword() As Byte
Dim p_abytUserFullName() As Byte
Dim p_abytUserComment() As Byte
Dim p_typUserInfo3 As USER_INFO_3
If xi_strUserFullName = vbNullString Then
xi_strUserName = xi_strUserName
End If
' ------------------------------------------
' Create byte arrays to avoid Unicode hassles
' ------------------------------------------
p_abytServerName = xi_strServerName & vbNullChar
p_abytUserName = xi_strUserName & vbNullChar
p_abytUserFullName = xi_strUserFullName & vbNullChar
p_abytPassword = xi_strPassword & vbNullChar
p_abytUserComment = xi_strUserComment & vbNullChar
' ------------------------------------------
' Allocate buffer space
' ------------------------------------------
p_lngRtn = NetApiBufferAllocate(UBound(p_abytUserName), p_lngPtrUserName)
p_lngRtn = NetApiBufferAllocate(UBound(p_abytUserFullName), p_lngPtrUserFullName)
p_lngRtn = NetApiBufferAllocate(UBound(p_abytPassword), p_lngPtrPassword)
p_lngRtn = NetApiBufferAllocate(UBound(p_abytUserComment), p_lngPtrUserComment)
' ------------------------------------------
' Get pointers to the byte arrays
' ------------------------------------------
p_lngPtrUserName = VarPtr(p_abytUserName(0))
p_lngPtrUserFullName = VarPtr(p_abytUserFullName(0))
p_lngPtrPassword = VarPtr(p_abytPassword(0))
p_lngPtrUserComment = VarPtr(p_abytUserComment(0))
' ------------------------------------------
' Fill the VB structure
' ------------------------------------------
p_lngFlags = UF_NORMAL_ACCOUNT Or UF_SCRIPT Or UF_DONT_EXPIRE_PASSWD
With p_typUserInfo3
.usri3_acct_expires = TIMEQ_FOREVER ' Never expires
.usri3_comment = p_lngPtrUserComment ' Comment
.usri3_flags = p_lngFlags ' There are a number of variations
.usri3_full_name = p_lngPtrUserFullName ' User's full name
.usri3_max_storage = USER_MAXSTORAGE_UNLIMITED ' Can use any amount of disk space
.usri3_name = p_lngPtrUserName ' Name of user account
.usri3_password = p_lngPtrPassword ' Password for user account
.usri3_primary_group_id = DOMAIN_GROUP_RID_USERS ' You MUST use this constant for NetUserAdd
.usri3_script_path = 0& ' Path of user's logon script
.usri3_auth_flags = 0& ' Ignored by NetUserAdd
.usri3_bad_pw_count = 0& ' Ignored by NetUserAdd
.usri3_code_page = 0& ' Code page for user's language
.usri3_country_code = 0& ' Country code for user's language
.usri3_home_dir = 0& ' Can specify path of home directory of this user
.usri3_home_dir_drive = 0& ' Drive letter assign to user's profile
.usri3_last_logoff = 0& ' Not needed when adding a user
.usri3_last_logon = 0& ' Ignored by NetUserAdd
.usri3_logon_hours = 0& ' Null means no restrictions
.usri3_logon_server = 0& ' Null means logon to domain server
.usri3_num_logons = 0& ' Ignored by NetUserAdd
.usri3_parms = 0& ' Used by specific applications
.usri3_password_age = 0& ' Ignored by NetUserAdd
.usri3_password_expired = 0& ' None-zero means user must change password at next logon
.usri3_priv = 0& ' Ignored by NetUserAdd
.usri3_profile = 0& ' Path to a user's profile
.usri3_units_per_week = 0& ' Ignored by NetUserAdd
.usri3_user_id = 0& ' Ignored by NetUserAdd
.usri3_usr_comment = 0& ' User comment
.usri3_workstations = 0& ' Workstations a user can log onto (null = all stations)
End With
' ------------------------------------------
' Attempt to add the user
' ------------------------------------------
p_lngRtn = NetUserAdd(p_abytServerName(0), _
constUserInfoLevel3, _
p_typUserInfo3, _
p_lngParameterErr)
' ------------------------------------------
' Check for error
' ------------------------------------------
If p_lngRtn <> 0 Then
AddUser = False
Select Case p_lngRtn
Case ERROR_ACCESS_DENIED
p_strErr = "User doesn't have sufficient access rights."
Case NERR_GroupExists
p_strErr = "The group already exists."
Case NERR_NotPrimary
p_strErr = "Can only do this operation on the PDC of the domain."
Case NERR_UserExists
p_strErr = "The user account already exists."
Case NERR_PasswordTooShort
p_strErr = "The password is shorter than required."
Case NERR_InvalidComputer
p_strErr = "The computer name is invalid."
Case Else
p_strErr = "Unknown error #" & CStr(p_lngRtn)
End Select
On Error GoTo 0
Err.Raise Number:=p_lngRtn, _
Description:=p_strErr & vbCrLf & _
"Error in parameter " & p_lngParameterErr & _
" when attempting to add the user, " & xi_strUserName, _
Source:="Form1.AddUser"
Else
AddUser = True
End If
' ------------------------------------------
' Be a good programmer and free the memory
' you've allocated
' ------------------------------------------
p_lngRtn = NetApiBufferFree(p_lngPtrUserName)
p_lngRtn = NetApiBufferFree(p_lngPtrPassword)
p_lngRtn = NetApiBufferFree(p_lngPtrUserFullName)
p_lngRtn = NetApiBufferFree(p_lngPtrUserComment)
End Function
EDIT:
I have found the following example in msdn:
Option Explicit
On Error Resume Next
Dim scriptResult ' Script success or failure
Dim groupPath ' ADsPath to the group container
Dim group ' Group object
Dim memberPath ' ADsPath to the member
Dim member ' Member object
Dim groupMemberList ' Used to display group members
Dim errorText ' Error handing text
scriptResult = False
groupPath =
"LDAP://fabrikam.com/CN=TestGroup,OU=TestOU,DC=fabrikam,DC=com"
memberPath = "LDAP://CN=JeffSmith,OU=TestOU,DC=fabrikam,DC=com"
WScript.Echo("Retrieving group object")
Set group = GetObject(groupPath)
If Err.number <> vbEmpty then
Call ErrorHandler("Could not create group object.")
End If
Call ShowMembers(groupPath) 'Optional function call
WScript.Echo("Retrieving new member object")
Set member = GetObject(memberPath)
If Err.number <> vbEmpty then
Call ErrorHandler("Could not get new member object.")
End If
WScript.Echo("Adding member to group.")
group.Add(member.ADsPath)
If Err.number <> vbEmpty then
Call ErrorHandler("Could not add member to group.")
End If
Call ShowMembers(groupPath) ' Optional function call
scriptResult = True
Call FinalResult(scriptResult)
'****************************************************************
' This function displays the members of a group. The function
' takes the ADsPath of the group.
'****************************************************************
Sub ShowMembers(groupPath)
Dim groupMember
Dim groupMemberList
Dim groupObject
Set groupObject = GetObject(groupPath)
Set groupMemberList = groupObject.Members
Select Case groupMemberList.Count
Case 1
WScript.Echo vbcrlf & "The group has one member."
Case 0
WScript.Echo vbcrlf & "The group has no members."
Case Else
WScript.Echo vbcrlf & "The group has " &
groupMemberList.Count &
" members."
End Select
If groupMemberList.Count > 0 then
WScript.Echo vbcrlf & "Here is a member list."
For Each groupMember in groupMemberList
WScript.Echo groupMember.Name
Next
WScript.Echo vbcrlf
End If
Set groupObject = Nothing
Set groupMemberList = Nothing
End Sub
'****************************************************************
' This function shows if the script succeeded or failed. The
' function processed the scriptResult variable.
'****************************************************************
Sub FinalResult(scriptResult)
WScript.Echo vbcrlf
If scriptResult = False then
WScript.Echo "Script failed."
Else
WScript.Echo("Script successfully completed.")
End If
WScript.Quit
End Sub
'****************************************************************
' This function handles errors that occur in the script.
'****************************************************************
Sub ErrorHandler( errorText )
WScript.Echo(vbcrlf & errorText)
WScript.Echo("Error number: " & Err.number)
WScript.Echo("Error Description: " & Err.Description)
Err.Clear
Call FinalResult(scriptResult)
End Sub
Alternatively, you can use Windows Script Host to execute the net tool:
Set objShell = CreateObject("Wscript.Shell")
strCommand = "net localgroup Administrators /add DOMAIN\USERNAME"
Set objExec = objShell.Exec(strCommand)
Related
i have done a connection using DSN, in which i have created a DSN throgh program. In that i have called a function to create a DSN, I dont want to call that function ecerytime i run the software, Instead i want to check whether dsn with the same name is already exist in the system or not, if it is not exist then only call to the function`
Public Sub ConnectDB(Con As ADODB.Connection)
Call CreatSQLDSN("TRDSN", VarSrvNm, VarDbName)
If Cn.State = 1 Then Cn.Close
On Error Resume Next
Con.ConnectionString = "Provider=MSDASQL.1;Persist Security Info=False;User ID=sa;Data Source=TRDSN;Initial Catalog='" & VarDbName & "'"
Con.Open Con.ConnectionString
If Err.Number <> 0 Then
If Err.Number = -2147467259 Then
If MsgBox(ServerName & " Server not Found. Connect to Other Server?", vbQuestion + vbDefaultButton2 + vbYesNo, "") = vbYes Then
PrintFile = Trim(Left(FindWindowPath, 3) & "DosPrint.Bat")
FileSystemObject.CreateTextFile PrintFile, True
Set TextStream = FileSystemObject.OpenTextFile(PrintFile, ForAppending)
TextStream.WriteLine "Del " & Left(FindWindowPath, 3) & "ServerName.dat"
TextStream.Close
Shell PrintFile, vbHide
End If
End
Else
If MsgBox(Err.Description, vbQuestion + vbOKOnly, "") = vbOK Then
Cancel = True
Exit Sub
End If
End If
End If
0
End Sub
Public Function CreatSQLDSN(SqlDsnName As String, SqlServerName As String, SqlDataName As String)
Dim Ret%, Driver$, Attributes$
Driver = "SQL Server" & Chr(0)
Attributes = "Server=" & SqlServerName & Chr(0)
Attributes = Attributes & "DSN=" & SqlDsnName & Chr(0)
Attributes = Attributes & "Database=" & SqlDataName & Chr(0)
Ret = SQLConfigDataSource(vbAPINull, ODBC_Add_User_DSN, Driver, Attributes)
'ret is equal to 1 on success and 0 if there is an error
If Ret <> 1 Then
MsgBox "User DSN Creation Failed"
End If
End Function`
A couple of options come to mind when needing to know if a DSN exists. You could either read through the Registry, or leverage your existing API call. I prefer the second option. It seems like a cleaner way to check for the existence of the DSN. Here is an example of what I am talking about:
Option Explicit
Private Declare Function SQLConfigDataSource Lib "ODBCCP32.DLL" (ByVal hwndParent As Long, ByVal fRequest As Long, ByVal lpszDriver As String, ByVal lpszAttributes As String) As Long
Private Const ODBC_ADD_DSN = 1
Private Const ODBC_CONFIG_DSN = 2
Private Const ODBC_REMOVE_DSN = 3
Private Const ODBC_ADD_SYS_DSN = 4
Private Const ODBC_CONFIG_SYS_DSN = 5
Private Const ODBC_REMOVE_SYS_DSN = 6
Private Const ODBC_REMOVE_DEFAULT_DSN = 7
Private Sub cmdCreate_Click()
Dim VarSrvNm As String
Dim VarDbName As String
VarSrvNm = "MyServer"
VarDbName = "MyDB"
If Not SQLDSNExists("TRDSN", VarSrvNm, VarDbName) Then
If Not CreateSQLDSN("TRDSN", VarSrvNm, VarDbName) Then
MsgBox "User DSN Creation Failed"
End If
End If
End Sub
Public Function CreateSQLDSN(SqlDsnName As String, SqlServerName As String, SqlDataName As String) As Boolean
Dim Ret%, Driver$, Attributes$
Driver = "SQL Server" & Chr(0)
Attributes = "Server=" & SqlServerName & Chr(0)
Attributes = Attributes & "DSN=" & SqlDsnName & Chr(0)
Attributes = Attributes & "Database=" & SqlDataName & Chr(0)
Ret = SQLConfigDataSource(0&, ODBC_ADD_DSN, Driver, Attributes)
'ret is equal to 1 on success and 0 if there is an error
CreateSQLDSN = (Ret = 1)
End Function
Public Function SQLDSNExists(SqlDsnName As String, SqlServerName As String, SqlDataName As String) As Boolean
Dim Ret%, Driver$, Attributes$
Driver = "SQL Server" & Chr(0)
Attributes = "Server=" & SqlServerName & Chr(0)
Attributes = Attributes & "DSN=" & SqlDsnName & Chr(0)
Attributes = Attributes & "Database=" & SqlDataName & Chr(0)
Ret = SQLConfigDataSource(0&, ODBC_CONFIG_DSN, Driver, Attributes)
'ret is equal to 1 on success and 0 if there is an error
SQLDSNExists = (Ret = 1)
End Function
The main idea here is to try to modify the DSN you want to add. If the call fails, then the DSN does not exist.
I've found a vbscript at possibly defunct scripting blog that I would like to use on our Windows 7 system. When I attempt to use it, I get an Invalid Object Path from line 38:
Set objSecuritySettings = objWMIService.Get _
("Win32_LogicalFileSecuritySetting.Path='" & strPath & "'")
Any ideas of why the script would be producing this error? code source: http://www.indented.co.uk/index.php/2008/10/22/listing-explicit-rights/comment-page-1/#comment-3947
Option Explicit
' Looks for a Trustee containing the SECURITY_PRINCIPAL string on
' the file system. Recurses from BASE_PATH down (file and folders).
' Set these values for the search.
Const BASE_PATH = "C:\"
Const SECURITY_PRINCIPAL = "Chris"
Sub FSRecurse(strPath)
' Simple FS recursion
Dim objFolder, objFile, objSubFolder
Set objFolder = objFileSystem.GetFolder(strPath)
For Each objFile in objFolder.Files
CheckDescriptor objFile.Path
Next
For Each objSubFolder in objFolder.SubFolders
CheckDescriptor objSubFolder.Path
FSRecurse objSubFolder.Path
Next
Set objFolder = Nothing
End Sub
Sub CheckDescriptor(strPath)
' Look for the Trustee in the Security Descriptor and filter out
' inherited ACEs
Const ACE_FLAG_INHERITED = &H10 ' 16
Dim objSecuritySettings, objSecurityDescriptor, objACE, objTrustee
Set objSecuritySettings = objWMIService.Get _
("Win32_LogicalFileSecuritySetting.Path='" & strPath & "'")
objSecuritySettings.GetSecurityDescriptor objSecurityDescriptor
For Each objACE in objSecurityDescriptor.dACL
If InStr(1, objACE.Trustee.Name, _
SECURITY_PRINCIPAL, VbTextCompare) > 0 Then
' ACEFlags is binary. Must perform binary comparison.
If objACE.ACEFlags And ACE_FLAG_INHERITED Then
' Problems with negation of the above.
' This is just easier.
Else
EnumAccess strPath, objACE
End If
End If
Next
End Sub
Sub EnumAccess(strPath, objACE)
' Most access mask values have matching Folder versions. These are not
' numerically different, they only differ when interpreted.
' ACE Type
Const ACCESS_ALLOWED_ACE_TYPE = &h0
Const ACCESS_DENIED_ACE_TYPE = &h1
' Base Access Mask values
Const FILE_READ_DATA = &h1
Const FILE_WRITE_DATA = &h2
Const FILE_APPEND_DATA = &h4
Const FILE_READ_EA = &h8
Const FILE_WRITE_EA = &h10
Const FILE_EXECUTE = &h20
Const FILE_DELETE_CHILD = &h40
Const FILE_READ_ATTRIBUTES = &h80
Const FILE_WRITE_ATTRIBUTES = &h100
Const FOLDER_DELETE = &h10000
Const READ_CONTROL = &h20000
Const WRITE_DAC = &h40000
Const WRITE_OWNER = &h80000
Const SYNCHRONIZE = &h100000
' Constructed Access Masks
Dim FULL_CONTROL
FULL_CONTROL = FILE_READ_DATA + FILE_WRITE_DATA + FILE_APPEND_DATA + _
FILE_READ_EA + FILE_WRITE_EA + FILE_EXECUTE + FILE_DELETE_CHILD + _
FILE_READ_ATTRIBUTES + FILE_WRITE_ATTRIBUTES + FOLDER_DELETE + _
READ_CONTROL + WRITE_DAC + WRITE_OWNER + SYNCHRONIZE
Dim READ_ONLY
READ_ONLY = FILE_READ_DATA + FILE_READ_EA + FILE_EXECUTE + _
FILE_READ_ATTRIBUTES + READ_CONTROL + SYNCHRONIZE
Dim MODIFY
MODIFY = FILE_READ_DATA + FILE_WRITE_DATA + FILE_APPEND_DATA + _
FILE_READ_EA + FILE_WRITE_EA + FILE_EXECUTE + _
FILE_READ_ATTRIBUTES + _
FILE_WRITE_ATTRIBUTES + FOLDER_DELETE + READ_CONTROL + SYNCHRONIZE
Dim strRights
Dim intAccessMask
WScript.Echo "Path: " & strPath
WScript.Echo "Username: " & objACE.Trustee.Name
WScript.Echo "Domain: " & objACE.Trustee.Domain
WScript.Echo "ACE Flags (Decimal): " & objACE.ACEFlags
' ACE Type
If objACE.ACEType = ACCESS_ALLOWED_ACE_TYPE Then
WScript.Echo "ACE Type: Allow"
Else
WScript.Echo "ACE Type: Deny"
End If
' Attempt to generate a basic summary of access rights
strRights = ""
intAccessMask = objACE.AccessMask
If intAccessMask = FULL_CONTROL Then
strRights = " (FullControl)"
ElseIf intAccessMask = MODIFY Then
strRights = " (Modify)"
ElseIf intAccessMask = READ_ONLY Then
strRights = " (ReadOnly)"
End If
' Echo the decimal mask with any summarised rights
WScript.Echo "Access Mask (Decimal): " & intAccessMask & strRights
WScript.Echo
End Sub
'
' Main code block
'
Dim objFileSystem, objWMIService
Set objFileSystem = CreateObject("Scripting.FileSystemObject")
' WMI Connection to the local machine
Set objWMIService = GetObject("winmgmts:\\.")
FSRecurse BASE_PATH
Set objWMIService = Nothing
Set objFileSystem = Nothing
You don't escape backslashes in strPath. Backslashes are escape characters in WMI, so unless you turn them into literal backslashes by doubling them, the WMI query won't be able to locate the file.
Also, there's another potential glitch in the command. It uses single quotes for quoting the file name. Single quotes are valid characters in NTFS file names, though. If your script runs into a file whose name contains a single quote that character will prematurely terminate the file name string in the WMI query, and the remainder of the file name will render the query invalid. I ran into the same issue when I wrote this.
Replacing this:
Set objSecuritySettings = objWMIService.Get _
("Win32_LogicalFileSecuritySetting.Path='" & strPath & "'")
with this:
Set objSecuritySettings = objWMIService.Get _
("Win32_LogicalFileSecuritySetting.Path=""" & Replace(strPath,"\","\\") & """")
should get you rid of both problems.
the code is to get data from a microcontroller or any device from serial device using serial port,so i am having problem with port opening and getting data,am having this problem for last 20 days please kindly help me at the earliest :)
Private Sub Command1_Click()
MsgBox ("The port is open " & MSComm1.PortOpen)
If (MSComm1.PortOpen = False) Then
MSComm1.PortOpen = True
End If
Command1.Enabled = False
Command2.Enabled = True
End Sub
Private Sub Command2_Click()
If (MSComm1.PortOpen = True) Then
MSComm1.PortOpen = False
End If
Command1.Enabled = True
Command2.Enabled = False
End Sub
Private Sub Form_Load()
With MSComm1
.CommPort = 1
.RThreshold = 1
.RTSEnable = True
.Settings = "9600,N,8,1"
.InputLen = 127
.SThreshold = 1
End With
End Sub
Private Sub Form_Unload(Cancel As Integer)
If (MSComm1.PortOpen = True) Then
MSComm1.PortOpen = False
End If
End Sub
Private Sub MSComm1_OnComm()
Dim Buffer As String
Select Case MSComm1.CommEvent
Case comEvReceive
'Text1.Text = " "
Buffer = MSComm1.Input
Text1.Text = Text1.Text & Buffer
End Select
End Sub!
Below is the image of interface which contains the MScomm control ,a text box , two command buttons for connecting and disconnecting :
'****** paste this in form'*********
Option Explicit
Dim Portnumber As Integer
Private Sub cmdClose_Click()
On Error GoTo handler
MSComm1.PortOpen = False
Shape1.FillColor = vbRed
cmdOpen.Enabled = True
txtRecieve.Text = ""
Exit Sub
handler: MsgBox Err.Description
End Sub
Private Sub cmdOpen_Click()
On Error GoTo handler
' Debug.Print cboComm.ItemData(cboComm.ListIndex)
portnumber = Mid(cboComm.Text, 4, (Len(cboComm.Text) - 3))
a = Mid(cboComm.Text, 4, (Len(cboComm.Text) - 3))
' If MSComm1.PortOpen = False Then
MSComm1.CommPort = portnumber
MSComm1.PortOpen = True
Shape1.FillColor = vbGreen
cmdOpen.Enabled = False
' End If
Exit Sub
handler: MsgBox Err.Description
End Sub
Private Sub Form_Load()
cboComm.Clear '*** cbo is for combobox
MSComm1.Settings = "9600,n,8,1"
ListComPorts
End Sub
Private Sub ListComPorts()
Dim i As Integer
cboComm.Clear
Static iData As Integer
iData = -1
For i = 1 To 16
If ComAvailable(i) Then
cboComm.AddItem (("COM") & i)
iData = iData + 1
cboComm.ItemData(iData) = i
End If
Next
cboComm.ListIndex = 0
' cmdGet.Enabled = False
End Sub
Private Sub MSComm1_OnComm()
Select Case MSComm1.CommEvent
Case comEvReceive
txtRecieve.Text = MSComm1.Input
Case Else
Debug.Print "Event: " & MSComm1.CommEvent
End Select
End Sub
'**************** End of form code **************
'*********** Now API code******************
'********** Paste in Module**************
Option Explicit
'*** API Declarations
Public Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, lpSecurityAttributes As SECURITY_ATTRIBUTES, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
'*** API Structures
Public Type SECURITY_ATTRIBUTES
nLength As Long
lpSecurityDescriptor As Long
bInheritHandle As Long
End Type
'***API Constants
Public Const FILE_SHARE_READ = &H1
Public Const FILE_SHARE_WRITE = &H2
Public Const OPEN_EXISTING = 3
Public Const FILE_ATTRIBUTE_NORMAL = &H80
'*** Create a Fuction to check whether COM exists or not. If exists return "true" otherwise "false"
Public Function ComAvailable(comnum As Integer) As Boolean
Dim hcom As Long
Dim ret As Long
Dim sec As SECURITY_ATTRIBUTES
hcom = CreateFile("\.\COM" & comnum & "", 0, FILE_SHARE_READ + FILE_SHARE_WRITE, sec, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)
If hcom = -1 Then
ComAvailable = False
Else
ComAvailable = True
'*** close the CO MPort
ret = CloseHandle(hcom)
End If
End Function
''''''''*******End of module code********
I think this will help you.....
If you get error 8002 then the port probably doesn't exist.
Are you using an rs232 connection, or are you connect via an USB port?
Have a look at the code i posted here .... when you run it, it will give a list of available ports on your system.
Is there any way to convert from \Device\HarddiskVolume1\programfile\explorer.exe to C:\programfile\explorer.exe in visual basic 6?
thanks
Try this
Option Explicit
Private Declare Function QueryDosDevice Lib "kernel32" Alias "QueryDosDeviceA" (ByVal lpDeviceName As String, ByVal lpTargetPath As String, ByVal ucchMax As Long) As Long
Private Sub Command1_Click()
Debug.Print pvReplaceDevice("\Device\HarddiskVolume1\aaa.txt")
End Sub
Private Function pvReplaceDevice(sPath As String) As String
Dim sDrive As String
Dim sDevice As String
Dim lIdx As Long
For lIdx = 0 To 25
sDrive = Chr$(65 + lIdx) & ":"
sDevice = Space(1000)
If QueryDosDevice(sDrive, sDevice, Len(sDevice)) <> 0 Then
sDevice = Left$(sDevice, InStr(sDevice, Chr$(0)) - 1)
' Debug.Print sDrive; "="; sDevice
If LCase$(Left$(sPath, Len(sDevice))) = LCase$(sDevice) Then
pvReplaceDevice = sDrive & Mid$(sPath, Len(sDevice) + 1)
Exit Function
End If
End If
Next
pvReplaceDevice = sPath
End Function
If you want an efficient use of API functions, create a class - "DiskDevice"
Option Explicit
Private Declare Function GetLogicalDriveStrings Lib "Kernel32" Alias "GetLogicalDriveStringsW" ( _
ByVal nBufferLength As Long, _
ByVal lpBuffer As Long _
) As Long
Private Declare Function QueryDosDevice Lib "Kernel32.dll" Alias "QueryDosDeviceW" ( _
ByVal lpDeviceName As Long, _
ByVal lpTargetPath As Long, _
ByVal ucchMax As Long _
) As Long
Private m_colDrivesKeyedByDevice As VBA.Collection
Private Sub Class_Initialize()
Dim sDriveStrings As String
Dim vasDriveStrings As Variant
Dim nIndex As Long
Dim sDrive As String
' Allocate max size buffer [A-Z]:\\\0 and retrieve all drives on the system.
sDriveStrings = Space$(105)
GetLogicalDriveStrings 1000, StrPtr(sDriveStrings)
' Split over the null chars between each substring.
vasDriveStrings = Split(sDriveStrings, vbNullChar)
Set m_colDrivesKeyedByDevice = New VBA.Collection
' Iterate through each drive string (escaping later if any item is null string).
For nIndex = 0 To UBound(vasDriveStrings)
sDrive = Left$(vasDriveStrings(nIndex), 2) ' Ignore the backslash.
If Len(sDrive) = 0 Then
Exit For
End If
' Create mapping from Drive => Device
m_colDrivesKeyedByDevice.Add sDrive, GetDeviceForDrive(sDrive)
Next nIndex
End Sub
' Retrieve the device string \device\XXXXXX for the drive X:
Private Function GetDeviceForDrive(ByRef the_sDrive As String)
Const knBufferLen As Long = 1000
Dim sBuffer As String
Dim nRet As Long
sBuffer = Space$(knBufferLen)
nRet = QueryDosDevice(StrPtr(the_sDrive), StrPtr(sBuffer), knBufferLen)
GetDeviceForDrive = Left$(sBuffer, nRet - 2) ' Ignore 2 terminating null chars.
End Function
Public Function GetFilePathFromDevicePath(ByRef the_sDevicePath As String) As String
Dim nPosSecondBackslash As Long
Dim nPosThirdBackslash As Long
Dim sDevice As String
Dim sDisk As String
' Path is always \Device\<device>\path1\path2\etc. Just get everything before the third backslash.
nPosSecondBackslash = InStr(2, the_sDevicePath, "\")
nPosThirdBackslash = InStr(nPosSecondBackslash + 1, the_sDevicePath, "\")
sDevice = Left(the_sDevicePath, nPosThirdBackslash - 1)
sDisk = m_colDrivesKeyedByDevice.Item(sDevice) ' Lookup
' Reassemble, this time with disk.
GetFilePathFromDevicePath = sDisk & Mid$(the_sDevicePath, nPosThirdBackslash)
End Function
Now, you use code like:
Set m_oDiskDevice = New DiskDevice
...
sMyPath = m_oDiskDevice.GetFilePathFromDevicePath("\Device\HarddiskVolume1\programfile\explorer.exe")
That way you don't have to call the API functions multiple times - you just do a collection lookup.
I'm working on an Outlook add-in that requires the Office specific FileDialog to interoperate with a Sharepoint site; the common file dialog doesn't have the interoperability. I know that both Word and Excel have a get_fileDialog method under Globals.ThisAddIn.Application.Application, but Outlook doesn't seem to. How do I launch an Outlook FileDialog? Is it even possible?
Microsoft Common Dialog
If you have COMDLG32.OCX ("Common Dialog ActiveX Control") installed, then you can use this - it's explained here, with an example. (Scroll down just past the screenshot entitled "FIGURE 2: Don't try to select more than one file in Word! ").
It appears that Outlook's Application object does not offer FileDialog. But a simple workaround, if you are willing to have an Excel reference, is:
Dim fd As FileDialog
Set fd = Excel.Application.FileDialog(msoFileDialogFolderPicker)
Dim folder As Variant
If fd.Show = -1 Then
For Each folder In fd.SelectedItems
Debug.Print "Folder:" & folder & "."
Next
End If
'Add a "Module". Then add the declarations like this to it.
Option Explicit
Private Declare Function GetOpenFileName _
Lib "comdlg32.dll" _
Alias "GetOpenFileNameA" (pOpenfilename As OPENFILENAME) As Long
Private Type OPENFILENAME
lStructSize As Long
hwndOwner As Long
hInstance As Long
lpstrFilter As String
lpstrCustomFilter As String
nMaxCustFilter As Long
nFilterIndex As Long
lpstrFile As String
nMaxFile As Long
lpstrFileTitle As String
nMaxFileTitle As Long
lpstrInitialDir As String
lpstrTitle As String
flags As Long
nFileOffset As Integer
nFileExtension As Integer
lpstrDefExt As String
lCustData As Long
lpfnHook As Long
lpTemplateName As String
End Type
Public Function MyOpenFiledialog() As String
Dim OFName As OPENFILENAME
OFName.lStructSize = Len(OFName)
'Set the parent window
OFName.hwndOwner = Application.hWnd
'Set the application's instance
OFName.hInstance = Application.hInstance
'Select a filter
OFName.lpstrFilter = "Text Files (*.txt)" + Chr$(0) + "*.txt" + Chr$(0) + "All Files (*.*)" + Chr$(0) + "*.*" + Chr$(0)
'create a buffer for the file
OFName.lpstrFile = Space$(254)
'set the maximum length of a returned file
OFName.nMaxFile = 255
'Create a buffer for the file title
OFName.lpstrFileTitle = Space$(254)
'Set the maximum length of a returned file title
OFName.nMaxFileTitle = 255
'Set the initial directory
OFName.lpstrInitialDir = "C:\"
'Set the title
OFName.lpstrTitle = "Open File - VB Forums.com"
'No flags
OFName.flags = 0
'Show the 'Open File'-dialog
If GetOpenFileName(OFName) Then
MsgBox "File to Open: " + Trim$(OFName.lpstrFile)
MyOpenFiledialog = Trim$(OFName.lpstrFile)
Else
MsgBox "Cancel was pressed"
MyOpenFiledialog = vbNullString
End If
End Sub 'Usage:
Private Sub Command1_Click()
Text1.Text = MyOpenFiledialog
End Sub
Public Sub TestFileDialog()
Dim otherObject As Excel.Application
Dim fdFolder As office.FileDialog
Set otherObject = New Excel.Application
otherObject.Visible = False
Set fdFolder = otherObject.Application.FileDialog(msoFileDialogFolderPicker)
fdFolder.Show
Debug.Print fdFolder.SelectedItems(1)
otherObject.Quit
Set otherObject = Nothing
End Sub
Private Sub multiEML2MSG()
Const PR_ICON_INDEX = &H10800003
Dim objPost As Outlook.PostItem
Dim objSafePost As Redemption.SafePostItem
Dim objNS As Outlook.NameSpace
Dim objInbox As Outlook.MAPIFolder
Set objNS = Outlook.GetNamespace("MAPI")
Set objInbox = objNS.GetDefaultFolder(olFolderInbox)
Set objPost = objInbox.Items.Add(OlItemType.olPostItem)
Set objSafePost = New Redemption.SafePostItem
Dim xlObj As Excel.Application
Dim fd As Office.FileDialog
Set xlObj = New Excel.Application
Set fd = xlObj.Application.FileDialog(msoFileDialogFolderPicker)
With fd
.Title = "Select your PST File"
.ButtonName = "Ok"
.Show
If fd.SelectedItems.Count <> 0 Then
xDirect$ = fd.SelectedItems(1) & "\"
xFname$ = Dir(xDirect$, 7)
licznik = 1
Do While xFname$ <> ""
XPathEML = xDirect$ & xFname$
XPathMSG = Replace(XPathEML, ".eml", ".msg", , , vbTextCompare)
Debug.Print XPath, Replace(XPath, ".eml", ".msg", , , vbTextCompare)
objPost.Save
objSafePost.Item = objPost
objSafePost.Import XPathEML, Redemption.RedemptionSaveAsType.olRFC822
objSafePost.MessageClass = "IPM.Note"
objSafePost.Fields(PR_ICON_INDEX) = none
objSafePost.SaveAs XPathMSG, Outlook.OlSaveAsType.olMSG
xFname$ = Dir
licznik = licznik + 1
Loop
End If
End With
xlObj.Quit
Set xlObj = Nothing
Set objSafePost = Nothing
Set objPost = Nothing
Set objInbox = Nothing
Set objNS = Nothing
End Sub