Vb6 Opening a custom file with my program in a text box - vb6

Help I am making a word processor and have a custom file extension to save it with but when I save that file and use open with select my program's exe then open it, the program opens with blank text how would I get it to open my text from double click in windows explorer

Inside your code use the following (no way to make it pretty but it works fine, copy and paste)
Private Declare Function RegCreateKey Lib "advapi32.dll" Alias "RegCreateKeyA" (ByVal hKey As Long, ByVal lpSubKey As String, phkResult As Long) As Long
Private Declare Function RegSetValue Lib "advapi32.dll" Alias "RegSetValueA" (ByVal hKey As Long, ByVal lpSubKey As String, ByVal dwType As Long, ByVal lpData As String, ByVal cbData As Long) As Long
Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long
Private Declare Function RegOpenKey Lib "advapi32.dll" Alias "RegOpenKeyExA" (ByVal hKey As Long, ByVal lpSubKey As String, ByVal ulOptions As Long, ByVal samDesired As Long, phkResult As Long) As Long
Private Declare Function RegQueryValue Lib "advapi32.dll" Alias "RegQueryValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal lpReserved As Long, lpType As Long, ByVal lpData As String, lpcbData As Long) As Long
Private Declare Function RegDeleteKey Lib "advapi32.dll" Alias "RegDeleteKeyA" (ByVal hKey As Long, ByVal lpSubKey As String) As Long
Private Const ERROR_SUCCESS = 0&
Private Const ERROR_BADDB = 1&
Private Const ERROR_BADKEY = 2&
Private Const ERROR_CANTOPEN = 3&
Private Const ERROR_CANTREAD = 4&
Private Const ERROR_CANTWRITE = 5&
Private Const ERROR_OUTOFMEMORY = 6&
Private Const ERROR_INVALID_PARAMETER = 7&
Private Const ERROR_ACCESS_DENIED = 8&
Private Const KEY_QUERY_VALUE = &H1&
Private Const KEY_CREATE_SUB_KEY = &H4&
Private Const KEY_ENUMERATE_SUB_KEYS = &H8&
Private Const KEY_NOTIFY = &H10&
Private Const KEY_SET_VALUE = &H2&
Private Const MAX_PATH = 260&
Private Const REG_DWORD As Long = 4
Private Const REG_SZ = 1
Private Const READ_CONTROL = &H20000
Private Const STANDARD_RIGHTS_READ = READ_CONTROL
Private Const STANDARD_RIGHTS_WRITE = READ_CONTROL
Private Const KEY_READ = STANDARD_RIGHTS_READ Or KEY_QUERY_VALUE Or KEY_ENUMERATE_SUB_KEYS Or KEY_NOTIFY
Private Const KEY_WRITE = STANDARD_RIGHTS_WRITE Or KEY_SET_VALUE Or KEY_CREATE_SUB_KEY
Public Const HKEY_CLASSES_ROOT = &H80000000
Public Const HKEY_CURRENT_USER = &H80000001
Public Const HKEY_LOCAL_MACHINE = &H80000002
Public Const HKEY_USERS = &H80000003
Public Sub MakeFileAssociation(Extension As String, PathToApplication As String, ApplicationName As String, Description As String, Optional FullIconPath As String)
Dim ret&
If Left(PathToApplication, 1) <> "\" Then PathToApplication = PathToApplication & "\"
'Create a Root entry called .XXX associated with application name
sKeyName = "." & Extension
sKeyValue = ApplicationName
ret& = WriteKey(HKEY_CLASSES_ROOT, sKeyName, "", sKeyValue)
'Set application key and file description
sKeyName = ApplicationName
sKeyValue = Description
ret& = WriteKey(HKEY_CLASSES_ROOT, sKeyName, "", sKeyValue)
'This sets the default icon for XXX_auto_file
If FullIconPath <> "" Then
sKeyName = ApplicationName & "\DefaultIcon"
sKeyValue = FullIconPath & ",0"
ret& = WriteKey(HKEY_CLASSES_ROOT, sKeyName, "", sKeyValue)
End If
'This sets the command line for XXX_auto_file
sKeyName = ApplicationName & "\shell\open\command"
sKeyValue = Chr(34) & PathToApplication & ApplicationName & ".exe" & Chr(34) & " %1"
ret& = WriteKey(HKEY_CLASSES_ROOT, sKeyName, "", sKeyValue)
End Sub
Public Sub DeleteFileAssociation(Extension As String)
Dim Application As String
Dim ret&
'check if filetype is registred
Application = ReadKey(HKEY_CLASSES_ROOT, "." & Extension, "", "")
If Application <> "" Then
'delete file extension
ret& = DeleteKey(HKEY_CLASSES_ROOT, "." & Extension)
'delete command lines
ret& = DeleteKey(HKEY_CLASSES_ROOT, Application)
End If
End Sub
Public Function CheckFileAssociation(ByVal Extension As String) As String
Extension = "." & Extension
'read in the program name associated with this filetype
CheckFileAssociation = ReadKey(HKEY_CLASSES_ROOT, Extension, "", "")
End Function
Public Function ReadKey(ByVal KeyName As String, ByVal SubKeyName As String, ByVal ValueName As String, ByVal DefaultValue As String) As String
Dim sBuffer As String
Dim lBufferSize As Long
Dim ret&
sBuffer = Space(255)
lBufferSize = Len(sBuffer)
ret& = RegOpenKey(KeyName, SubKeyName, 0, KEY_READ, lphKey&)
If ret& = ERROR_SUCCESS Then
ret& = RegQueryValue(lphKey&, ValueName, 0, REG_SZ, sBuffer, lBufferSize)
ret& = RegCloseKey(lphKey&)
Else
ret& = RegCloseKey(lphKey&)
End If
sBuffer = Trim(sBuffer)
If sBuffer <> "" Then
sBuffer = Left(sBuffer, Len(sBuffer) - 1)
Else
sBuffer = DefaultValue
End If
ReadKey = sBuffer
End Function
Public Function WriteKey(ByVal KeyName As String, ByVal SubKeyName As String, ByVal ValueName As String, ByVal KeyValue As String) As Long
Dim ret&
ret& = RegCreateKey&(KeyName, SubKeyName, lphKey&)
If ret& = ERROR_SUCCESS Then
ret& = RegSetValue&(lphKey&, ValueName, REG_SZ, KeyValue, 0&)
Else
ret& = RegCloseKey(lphKey&)
End If
WriteKey = ret&
End Function
Public Function DeleteKey(ByVal KeyName As String, ByVal SubKeyName As String) As Long
Dim ret&
ret& = RegOpenKey(KeyName, SubKeyName, 0, KEY_WRITE, lphKey&)
If ret& = ERROR_SUCCESS Then
ret& = RegDeleteKey(lphKey&, "") 'delete the key
ret& = RegCloseKey(lphKey&)
End If
DeleteKey = ret&
End Function
Then you can call them and provide the parameter and it will create it for you, delete it and check it. As for handing it via your application when you open the file using the extension, you need to make sure you have a command line parser and feed it with a %1 and use that file name to open the document within your program. That's it.
You can create a main() and set your program startup to use that instead of the usual form1 and inside that put:
Public Sub main()
'Store command line arguments in this array
Dim sArgs() As String
Dim iLoop As Integer
'Assuming that the arguments passed from
'command line will have space in between,
'you can also use comma or other things...
sArgs = Split(Command$, " ")
For iLoop = 0 To UBound(sArgs)
'this will print the command line
'arguments that are passed from the command line
Debug.Print sArgs(iLoop)
Next
End Sub
Depending on what arguments you are passing to the command of your program, you would replace the debug line with the path to the file you just opened with your program and do what you do with it in your application.

Related

VB6: Writing to registry

I have to edit an old legacy VB6 application so that it can edit the registry to write the following:
reg add "HKCU\Software\Microsoft\Print\UnifiedPrintDialog" /v "PreferLegacyPrintDialog" /d 1 /t REG_DWORD /f
How can I emulate the above command in VB6?
I read a few posts using the registry = CreateObject("WScript.shell") methodology but it doesn't seem clear to me and I really don't want to mess around with the registry without knowing what I'm doing. Otherwise, could I just run the command through a ShellExecute or something similar?
Any assistance would be appreciated. Thanks!
For "proper" registry access/read/write in VB6, you would need to implement the appropriate Win32 API methods. Here's a wrapper class for that. But for your simple need, the WScript.Shell approach should it (from the Windows Scripting Host helpfile):
RegWrite supports strType as REG_SZ, REG_EXPAND_SZ, REG_DWORD, and
REG_BINARY. If another data type is passed as strType, RegWrite
returns E_INVALIDARG.
RegWrite automatically converts anyValue to a string when strType is
REG_SZ or REG_EXPAND_SZ. If strType is REG_DWORD, anyValue is
converted to an integer. If strType is REG_BINARY, anyValue must be an
integer.
Example
The following example writes a value and key entry into the
registry:
Set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.RegWrite "HKCU\ScriptEngine\Value", "Some string value"
WshShell.RegWrite "HKCU\ScriptEngine\Key\", 1 ,"REG_DWORD"
You can use the Windows API to accomplish what you need. Here's some general purpose code to read and write to the Registry:
Option Explicit
Private Sub Read_Click()
Text1.Text = ReadRegistry(HKEY_CURRENT_USER, "Software\Microsoft\Print\UnifiedPrintDialog", "PreferLegacyPrintDialog", ValDWord, "1")
End Sub
Private Sub Write_Click()
WriteRegistry HKEY_CURRENT_USER, "Software\Microsoft\Print\UnifiedPrintDialog", "PreferLegacyPrintDialog", ValDWord, Text1.Text
End Sub
In a Module place the following code:
Option Explicit
Public Const HKEY_CLASSES_ROOT = &H80000000
Public Const HKEY_CURRENT_USER = &H80000001
Public Const HKEY_LOCAL_MACHINE = &H80000002
Public Const HKEY_USERS = &H80000003
Public Const HKEY_PERFORMANCE_DATA = &H80000004
Public Const REG_SZ = 1
Public Const REG_DWORD = 4
Public Enum InTypes
ValNull = 0
ValString = 1
ValXString = 2
ValBinary = 3
ValDWord = 4
ValLink = 6
ValMultiString = 7
ValResList = 8
End Enum
Private Const ERROR_SUCCESS = 0&
Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long
Private Declare Function RegCreateKey Lib "advapi32.dll" Alias "RegCreateKeyA" (ByVal hKey As Long, ByVal lpSubKey As String, phkResult As Long) As Long
Private Declare Function RegOpenKey Lib "advapi32.dll" Alias "RegOpenKeyA" (ByVal hKey As Long, ByVal lpSubKey As String, phkResult As Long) As Long
Private Declare Function RegQueryValueEx Lib "advapi32.dll" Alias "RegQueryValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal lpReserved As Long, lpType As Long, lpData As Any, lpcbData As Long) As Long
Private Declare Function RegSetValueEx Lib "advapi32.dll" Alias "RegSetValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal Reserved As Long, ByVal dwType As Long, lpData As Any, ByVal cbData As Long) As Long
Public Function ReadRegistry(ByVal Group As Long, ByVal Section As String, ByVal Key As String, ByVal ValType As InTypes, Optional Default As Variant) As Variant
If ValType = ValString Then
ReadRegistry = ReadString(Group, Section, Key)
If ReadRegistry = "" Then ReadRegistry = Default
ElseIf ValType = ValDWord Then
ReadRegistry = ReadDword(Group, Section, Key)
If ReadRegistry = 0 Then ReadRegistry = Default
End If
End Function
Public Sub WriteRegistry(ByVal Group As Long, ByVal Section As String, ByVal Key As String, ByVal ValType As InTypes, ByVal Value As Variant)
If ValType = ValString Then
WriteString Group, Section, Key, CStr(Value)
ElseIf ValType = ValDWord Then
WriteDword Group, Section, Key, CLng(Value)
End If
End Sub
Private Function ReadString(hKey As Long, strPath As String, strValue As String) As String
Dim keyhand As Long
Dim lResult As Long
Dim strBuf As String
Dim lDataBufSize As Long
Dim intZeroPos As Integer
Dim lValueType As Long
Dim r As Long
r = RegOpenKey(hKey, strPath, keyhand)
lResult = RegQueryValueEx(keyhand, strValue, 0&, lValueType, ByVal 0&, lDataBufSize)
strBuf = String(lDataBufSize, " ")
lResult = RegQueryValueEx(keyhand, strValue, 0&, 0&, ByVal strBuf, lDataBufSize)
If lResult = ERROR_SUCCESS Then
intZeroPos = InStr(strBuf, Chr$(0))
If intZeroPos > 0 Then
ReadString = Left$(strBuf, intZeroPos - 1)
Else
ReadString = strBuf
End If
End If
End Function
Private Sub WriteString(hKey As Long, strPath As String, strValue As String, strdata As String)
Dim keyhand As Long
Dim r As Long
r = RegCreateKey(hKey, strPath, keyhand)
r = RegSetValueEx(keyhand, strValue, 0, REG_SZ, ByVal strdata, Len(strdata))
r = RegCloseKey(keyhand)
End Sub
Private Function ReadDword(ByVal hKey As Long, ByVal strPath As String, ByVal strValueName As String) As Long
Dim lResult As Long
Dim lValueType As Long
Dim lBuf As Long
Dim lDataBufSize As Long
Dim r As Long
Dim keyhand As Long
r = RegOpenKey(hKey, strPath, keyhand)
lDataBufSize = 4
lResult = RegQueryValueEx(keyhand, strValueName, 0&, lValueType, lBuf, lDataBufSize)
If lResult = ERROR_SUCCESS Then
If lValueType = REG_DWORD Then ReadDword = lBuf
End If
r = RegCloseKey(keyhand)
End Function
Private Sub WriteDword(ByVal hKey As Long, ByVal strPath As String, ByVal strValueName As String, ByVal lData As Long)
Dim keyhand As Long
Dim r As Long
r = RegCreateKey(hKey, strPath, keyhand)
r = RegSetValueEx(keyhand, strValueName, 0&, REG_DWORD, lData, 4)
r = RegCloseKey(keyhand)
End Function

VB6 reading registry entry but no data returned

newly signed up desperate user here.
I left the programming business quite a while ago but now and then get asked to make some enhancements etc.
I want to use the registry to store some file locations so the user doesn't have to specify them all the time. I want to store them under HKEY_LOCAL_MACHINE because there are multiple users.
I have got the key created using RegCreateKeyEx, and a value has been entered into the key, with RegSetValueExString, so there is a key under HKEY_LOCAL_MACHINE called SUPPLIERFILE and it has the value "C:\Documents and Settings.." etc.
However when I use RegQueryValueExString it doesn't work: the lpValue string is empty, although the cbdata does contain the length of the string I was expecting to find there. The error retured is 234, ERROR_MORE_DATA.
I have tried using RegGetValue, because I thought maybe a non-null terminated string was the problem, but I haven't got RegGetValue in the api dll.
Any suggestions would be gratefully received, even along the lines of how to terminate a string with a null.
Thanks,
Steve
Your error indicates you have not initialized a large enough string buffer for the API function to use, but without your code, ??? I pulled the code below from a registry utility class I use. I think I have included all the API declarations, and constants used, as well as a method to translate returned errors to something helpful.
Public Enum RegRootKey
HKEY_CLASSES_ROOT = &H80000000
HKEY_CURRENT_CONFIG = &H80000005
HKEY_CURRENT_USER = &H80000001
HKEY_DYN_DATA = &H80000006
HKEY_LOCAL_MACHINE = &H80000002
HKEY_PERFORMANCE_DATA = &H80000004
HKEY_USERS = &H80000003
End Enum
'the following declare is used to return windows error descriptions
Private Declare Function FormatMessage Lib "Kernel32" Alias "FormatMessageA" (ByVal dwFlags As Long, lpSource As Any, ByVal dwMessageId As Long, ByVal dwLanguageId As Long, ByVal lpBuffer As String, ByVal nSize As Long, Arguments As Long) As Long
Private Const FORMAT_MESSAGE_FROM_SYSTEM = &H1000
Private Const FORMAT_MESSAGE_IGNORE_INSERTS = &H200
'key constants
Private Const ERROR_NO_MORE_ITEMS = 259&
Private Const ERROR_MORE_DATA = 234
Private Const ERROR_SUCCESS = 0&
Private Const SYNCHRONIZE = &H100000
Private Const READ_CONTROL = &H20000
Private Const READ_WRITE = 2
Private Const READAPI = 0
Private Const STANDARD_RIGHTS_ALL = &H1F0000
Private Const STANDARD_RIGHTS_REQUIRED = &HF0000
Private Const STANDARD_RIGHTS_EXECUTE = (READ_CONTROL)
Private Const STANDARD_RIGHTS_READ = (READ_CONTROL)
Private Const STANDARD_RIGHTS_WRITE = (READ_CONTROL)
Private Const KEY_NOTIFY = &H10
Private Const KEY_QUERY_VALUE = &H1
Private Const KEY_CREATE_LINK = &H20
Private Const KEY_CREATE_SUB_KEY = &H4
Private Const KEY_ENUMERATE_SUB_KEYS = &H8
Private Const KEY_EVENT = &H1
Private Const KEY_SET_VALUE = &H2
Private Const KEY_ALL_ACCESS = ((STANDARD_RIGHTS_ALL Or KEY_QUERY_VALUE Or KEY_SET_VALUE Or KEY_CREATE_SUB_KEY Or KEY_ENUMERATE_SUB_KEYS Or KEY_NOTIFY Or KEY_CREATE_LINK) And (Not SYNCHRONIZE))
Private Const KEY_READ = ((STANDARD_RIGHTS_READ Or KEY_QUERY_VALUE Or KEY_ENUMERATE_SUB_KEYS Or KEY_NOTIFY) And (Not SYNCHRONIZE))
Private Const KEY_EXECUTE = ((KEY_READ) And (Not SYNCHRONIZE))
Private Const KEY_WRITE = ((STANDARD_RIGHTS_WRITE Or KEY_SET_VALUE Or KEY_CREATE_SUB_KEY) And (Not SYNCHRONIZE))
Private Const REG_OPTION_NON_VOLATILE = 0
Private Const REG_SZ = 1 ' Unicode nul terminated string
Private Const REG_BINARY = 3
Private Const REG_DWORD = 4
Private Const REG_MULTI_SZ = 7 ' Multiple Unicode strings
Private Const REG_NONE = 0 ' No value type
Private Const KEY_WOW64_64KEY As Long = &H100& '32 bit app to access 64 bit hive
Private Const KEY_WOW64_32KEY As Long = &H200& '64 bit app to access 32 bit hive
'API declarations
Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long
Private Declare Function RegQueryValueEx Lib "advapi32.dll" Alias "RegQueryValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal lpReserved As Long, lpType As Long, lpData As Any, lpcbData As Long) As Long
Private Declare Function RegOpenKeyEx Lib "advapi32.dll" Alias "RegOpenKeyExA" (ByVal hKey As Long, ByVal lpSubKey As String, ByVal ulOptions As Long, ByVal samDesired As Long, phkResult As Long) As Long
Private Declare Function RootKeyName Lib "advapi32.dll" Alias "RootKeyNameA" (ByVal lphKey As RegRootKey) As String
Public Function GetStringValue(ByVal hKeyRoot As RegRootKey, ByVal hKeySubKey As String, ByVal ValueName As String, Optional ByVal Default As String) As String
Dim strReturn As String
Dim strBuffer As String
Dim lngType As Long
Dim lngBufLen As Long
Dim lngRst As Long
Dim hKeyHandle As Long
On Error GoTo errGetStringValue
'just to avoid any errors in calling functions using a ubound to check the contents
strBuffer = String(255, vbNullChar)
lngBufLen = Len(strBuffer)
lngRst = RegOpenKeyEx(hKeyRoot, hKeySubKey, 0, KEY_READ Or KEY_WOW64_64KEY, hKeyHandle)
If hKeyHandle <> 0 Then
If StrComp(ValueName, "default", vbTextCompare) = 0 Then
lngRst = RegQueryValueEx(hKeyHandle, "", ByVal 0&, lngType, ByVal strBuffer, lngBufLen)
Else
lngRst = RegQueryValueEx(hKeyHandle, ValueName, ByVal 0&, lngType, ByVal strBuffer, lngBufLen)
End If
End If
If lngRst = 0 Then
If lngType = REG_SZ Then
If lngBufLen > 0 Then
strReturn = Left$(strBuffer, lngBufLen - 1)
Else
strReturn = Default
End If
Else
Err.Raise 1, App.EXEName, FormatClassError(1)
End If
ElseIf lngRst = 2 Then 'the key does not exists so return the default
strReturn = Default
Else 'if the return is non-zero there was an error
Err.Raise lngRst, App.EXEName, "There was an error reading the " & RootKeyName(hKeyRoot) & "\" & _
hKeySubKey & " registry key, " & LCase$(FormatClassError(lngRst))
End If
If hKeyHandle <> 0 Then
lngRst = RegCloseKey(hKeyHandle)
hKeyHandle = 0
End If
GetStringValue = strReturn
Exit Function
errGetStringValue:
If hKeyHandle <> 0 Then
lngRst = RegCloseKey(hKeyHandle)
hKeyHandle = 0
End If
Err.Raise Err.Number, Err.Source & ":GetStringValue", Err.Description
End Function
Private Function FormatClassError(ByVal ErrorNumber As Long) As String
Dim strReturn As String
Dim strBuffer As String
Dim lngBufLen As Long
Dim lngRst As Long
On Error Resume Next
'initialize the buffer to to API function
strBuffer = String(1024, vbNullChar)
lngBufLen = Len(strBuffer)
'make the call to the API function
lngRst = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM Or FORMAT_MESSAGE_IGNORE_INSERTS, ByVal 0&, ErrorNumber, ByVal 0&, strBuffer, lngBufLen, ByVal 0&)
'if the return value is <> 0 then we have a valid message
If lngRst <> 0 Then
strReturn = Left$(strBuffer, lngRst)
Else
'make another call to the API function with the last dll error
lngRst = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM Or FORMAT_MESSAGE_IGNORE_INSERTS, ByVal 0&, Err.LastDllError, ByVal 0&, strBuffer, lngBufLen, ByVal 0&)
If lngRst <> 0 Then
strReturn = Left$(strBuffer, lngRst)
Else
strReturn = "Unable to retrieve error description."
End If
End If
'return the result
FormatClassError = strReturn
End Function
Quick answer: try the GetRegStringValue$ code here
In case you (or others) want to know more
When you call that API, as with many windows APIs you are supposed to provide a buffer (string) to hold the registry value, and you are supposed to pass in the maximum size of your buffer.
MSDN explains
If the buffer specified by lpData parameter is not large enough to hold the data, the function returns ERROR_MORE_DATA and stores the required buffer size in the variable pointed to by lpcbData. In this case, the contents of the lpData buffer are undefined.
You need to allocate a buffer (probably fill your string with spaces) and pass in the size in lpData.
you should check first, if the Registry is really do exist or not. By error handling, we can check for the Registry key Entry.
Private Function RegOSInfo(RegPath As String, RegKey As String) As String
On Error GoTo ErrHandler
Dim osName As String
Dim Reg As Object
Set Reg = CreateObject("WScript.Shell")
RegOSInfo = Reg.RegRead(RegPath & "\" & RegKey)
ErrHandler:
RegOSInfo = "-555" 'custom Error Code, Registry key doesn't exist
End Function
you can handle the Custom error code according to your need.

Deleting a registry subkey in Visual Basic 6

I am working on an application that deletes registry subkeys, but I can't seem to find a solution for that problem... I know it is easier to do this with VB.NET but I want to know how to get this done using VB6
What I have tried...
DeleteRegKey HKEY_CURRENT_USER\Software\Test.
Take this for what it's worth. I haven't used this in a few years so it has not been tested on Windows 8, and I'm not at all sure about Windows 7 either. I pulled this from a utility class so hopefully I got all the declarations.
Private Const KEY_NOTIFY = &H10
Private Const KEY_QUERY_VALUE = &H1
Private Const KEY_CREATE_LINK = &H20
Private Const KEY_CREATE_SUB_KEY = &H4
Private Const KEY_ENUMERATE_SUB_KEYS = &H8
Private Const KEY_EVENT = &H1
Private Const KEY_SET_VALUE = &H2
Private Const KEY_ALL_ACCESS = ((STANDARD_RIGHTS_ALL Or KEY_QUERY_VALUE Or KEY_SET_VALUE Or KEY_CREATE_SUB_KEY Or KEY_ENUMERATE_SUB_KEYS Or KEY_NOTIFY Or KEY_CREATE_LINK) And (Not SYNCHRONIZE))
Private Const KEY_READ = ((STANDARD_RIGHTS_READ Or KEY_QUERY_VALUE Or KEY_ENUMERATE_SUB_KEYS Or KEY_NOTIFY) And (Not SYNCHRONIZE))
Private Const KEY_EXECUTE = ((KEY_READ) And (Not SYNCHRONIZE))
Private Const KEY_WRITE = ((STANDARD_RIGHTS_WRITE Or KEY_SET_VALUE Or KEY_CREATE_SUB_KEY) And (Not SYNCHRONIZE))
Public Enum RegRootKey
HKEY_CLASSES_ROOT = &H80000000
HKEY_CURRENT_CONFIG = &H80000005
HKEY_CURRENT_USER = &H80000001
HKEY_DYN_DATA = &H80000006
HKEY_LOCAL_MACHINE = &H80000002
HKEY_PERFORMANCE_DATA = &H80000004
HKEY_USERS = &H80000003
End Enum
Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long
Private Declare Function RegCreateKeyEx Lib "advapi32.dll" Alias "RegCreateKeyExA" (ByVal hKey As Long, ByVal lpSubKey As String, ByVal Reserved As Long, ByVal lpClass As String, ByVal dwOptions As Long, ByVal samDesired As Long, ByVal lpSecurityAttributes As Long, phkResult As Long, lpdwDisposition As Long) As Long
Private Declare Function RegDeleteKey Lib "advapi32.dll" Alias "RegDeleteKeyA" (ByVal hKey As Long, ByVal lpSubKey As String) As Long
Private Declare Function RegEnumKeyEx Lib "advapi32.dll" Alias "RegEnumKeyExA" (ByVal hKey As Long, ByVal dwIndex As Long, ByVal lpName As String, lpcbName As Long, ByVal lpReserved As Long, ByVal lpClass As String, lpcbClass As Long, lpftLastWriteTime As FILETIME) As Long
Public Function DeleteRegKey(ByVal hKeyRoot As RegRootKey, ByVal hKeySubKey As String, ByVal KeyName As String) As Boolean
Dim lngRst As Long
Dim hKeyReturn As Long
Dim hKeyDisposition As Long
Dim strSubKeys() As String
Dim lngSubKeyCount As Long
Dim i As Long
On Error GoTo errDeleteRegKey
lngRst = RegOpenKeyEx(hKeyRoot, hKeySubKey, ByVal 0&, KEY_READ + KEY_WRITE, hKeyReturn)
If lngRst = 0 Then 'we can continue
' first need to find and delete sub keys
lngSubKeyCount = EnumSubKeys(hKeyRoot, hKeySubKey & "\" & KeyName, strSubKeys)
' recursively call this function to delete all sub keys
For i = 0 To lngSubKeyCount - 1
Call DeleteRegKey(hKeyRoot, hKeySubKey & "\" & KeyName, strSubKeys(i))
Next i
' finally down (up?) to the parent key
lngRst = RegDeleteKey(hKeyReturn, ByVal KeyName)
'close the handle
If hKeyReturn <> 0 Then
lngRst = RegCloseKey(hKeyReturn)
hKeyReturn = 0
End If
End If
If lngRst = 0 Then '0 = success
DeleteRegKey = True
Else
Err.Raise lngRst, App.EXEName, FormatClassError(lngRst)
End If
Exit Function
errDeleteRegKey:
'close the handle
If hKeyReturn <> 0 Then
lngRst = RegCloseKey(hKeyReturn)
hKeyReturn = 0
End If
Err.Raise Err.Number, Err.Source & ":DeleteRegKey", Err.Description
End Function
Add this function to a form, module, or class then
Call DeleteRegKey(HKEY_CURRENT_USER, "Software", "Test")
' or
DeleteRegKey HKEY_CURRENT_USER, "Software", "Test"
' or
Dim blnRst as Boolean
blnRst = DeleteRegKey(HKEY_CURRENT_USER, "Software", "Test")

Calling a script with parameters in a form

I have a form that is supposed to call a script upon a button press. I am trying to invoke it via Command Line. I tested the script in the command line and it works correctly. I can't get the form to run the script in the command shell. Any ideas?
This is the command line string I need ran autonomously by the shell:
cscript.exe proc_image.vbs 170.191.XXX.XXX picName C:\PicStorage
This is what I have currently have in my On_Click() action in my button:
ShellEx "cscript.exe C:\Scripts\proc_image.vbs" & " 170.191.XXX.XXX" & " picName" & " PicStorage"
My goal is to call the script and pass it 3 parameters: an ip address, name of the picture, and final storage destination. My issue is getting the form to execute the above command line in the shell. Thanks
EDIT: Here is the ShellEx Code:
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
Private Declare Function ShellExecuteForExplore Lib "shell32.dll" Alias "ShellExecuteA" _
(ByVal hWnd As Long, ByVal lpOperation As String, ByVal lpFile As String, lpParameters As Any, _
lpDirectory As Any, ByVal nShowCmd As Long) As Long
Public Enum EShellShowConstants
essSW_HIDE = 0
essSW_MAXIMIZE = 3
essSW_MINIMIZE = 6
essSW_SHOWMAXIMIZED = 3
essSW_SHOWMINIMIZED = 2
essSW_SHOWNORMAL = 1
essSW_SHOWNOACTIVATE = 4
essSW_SHOWNA = 8
essSW_SHOWMINNOACTIVE = 7
essSW_SHOWDEFAULT = 10
essSW_RESTORE = 9
essSW_SHOW = 5
End Enum
Private Const ERROR_FILE_NOT_FOUND = 2&
Private Const ERROR_PATH_NOT_FOUND = 3&
Private Const ERROR_BAD_FORMAT = 11&
Private Const SE_ERR_ACCESSDENIED = 5 ' access denied
Private Const SE_ERR_ASSOCINCOMPLETE = 27
Private Const SE_ERR_DDEBUSY = 30
Private Const SE_ERR_DDEFAIL = 29
Private Const SE_ERR_DDETIMEOUT = 28
Private Const SE_ERR_DLLNOTFOUND = 32
Private Const SE_ERR_FNF = 2 ' file not found
Private Const SE_ERR_NOASSOC = 31
Private Const SE_ERR_PNF = 3 ' path not found
Private Const SE_ERR_OOM = 8 ' out of memory
Private Const SE_ERR_SHARE = 26
Public Function ShellEx( _
ByVal sFIle As String, _
Optional ByVal eShowCmd As EShellShowConstants = essSW_SHOWDEFAULT, _
Optional ByVal sParameters As String = "", _
Optional ByVal sDefaultDir As String = "", _
Optional sOperation As String = "open", _
Optional Owner As Long = 0 _
) As Boolean
Dim lR As Long
Dim lErr As Long, sErr As Long
If (InStr(UCase$(sFIle), ".EXE") <> 0) Then
eShowCmd = 0
End If
On Error Resume Next
If (sParameters = "") And (sDefaultDir = "") Then
lR = ShellExecuteForExplore(Owner, sOperation, sFIle, 0, 0, essSW_SHOWNORMAL)
Else
lR = ShellExecute(Owner, sOperation, sFIle, sParameters, sDefaultDir, eShowCmd)
End If
If (lR < 0) Or (lR > 32) Then
ShellEx = True
Else
' raise an appropriate error: *ERROR CODES GO HERE*
End If
End Function
It looks like you are missing C:\ in your ShellEx command just prior to PicStorage string?

Keep getting error 2 (Registry path does not exist) with RegQueryValueEx in VBA

I'm trying to have VBA query the registry to see if an ODBC driver is installed, and I get error 2 when trying to read a key's value. I tried a simpler key/value, but no cigar.
Edit for Clarification
I am developing on a 32-bit system, but this needs to work for both 32 and 64-bit systems. What the problem is is that the call to RegOpenKeyEx works, but RegQueryValueEx returns error 2: file does not exist on my 32-bit system. My syntax appears correct, what am I doing wrong?
Public Const HKEY_LOCAL_MACHINE = &H80000002
Public Const ERROR_SUCCESS = 0& ' Successful
Public Const ERROR_FILE_NOT_FOUND = 2& ' Registry path does not exist
Public Const ERROR_ACCESS_DENIED = 5& ' Requested permissions not available
Public Const STANDARD_RIGHTS_READ = &H20000
Public Const SYNCHRONIZE = &H100000
Public Const KEY_ENUMERATE_SUB_KEYS = &H8
Public Const KEY_NOTIFY = &H10
Public Const KEY_QUERY_VALUE = &H1
Public Const KEY_READ = ((STANDARD_RIGHTS_READ Or KEY_QUERY_VALUE _
Or KEY_ENUMERATE_SUB_KEYS Or KEY_NOTIFY) _
And (Not SYNCHRONIZE))
Public Const REG_SZ = 1 ' Unicode nul terminated string
Public Declare Function RegOpenKeyEx Lib "advapi32.dll" Alias "RegOpenKeyExA" _
(ByVal hKey As Long, ByVal lpSubKey As String, ByVal ulOptions As _
Long, ByVal samDesired As Long, phkResult As Long) As Long
Public Declare Function RegQueryValueEx Lib "advapi32.dll" Alias "RegQueryValueExA" _
(ByVal hKey As Long, lpValueName As String, _
ByVal lpReserved As Long, lpType As Long, _
lpData As Any, lpcbData As Long) As Long
Public Declare Function RegCloseKey Lib "advapi32.dll" _
(ByVal hKey As Long) As Long
Sub TestRegAPI()
Dim KeyName As String, handle As Long, handle2 As String
'KeyName = "SOFTWARE\ODBC\ODBCINST.INI\ODBC Drivers"
KeyName = "SOFTWARE\7-Zip"
r = RegOpenKeyEx(HKEY_LOCAL_MACHINE, KeyName, 0, KEY_READ, handle)
If r Then
MsgBox "Unable to open the specified Registry key, code " & r
Else
'r = RegQueryValueEx(handle, "MySQL ODBC 5.1 Driver", 0, 1&, handle2, length)
r = RegQueryValueEx(handle, "Path", 0, REG_SZ, handle2, length)
RegCloseKey handle
End If
End Sub
This works for me on a 64 bit machine. It is from http://blogs.technet.com/b/heyscriptingguy/archive/2005/07/07/how-can-i-get-a-list-of-the-odbc-drivers-that-are-installed-on-a-computer.aspx
Const HKEY_LOCAL_MACHINE = &H80000002
strComputer = "."
Set objRegistry = GetObject("winmgmts:\\" & strComputer & "\root\default:StdRegProv")
strKeyPath = "SOFTWARE\ODBC\ODBCINST.INI\ODBC Drivers"
objRegistry.EnumValues HKEY_LOCAL_MACHINE, strKeyPath, arrValueNames, arrValueTypes
For i = 0 To UBound(arrValueNames)
strValueName = arrValueNames(i)
objRegistry.GetStringValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName, strValue
Debug.Print arrValueNames(i) & " -- " & strValue
Next
From what I could find on Wikipedia Windows NT4 has WMI as a downloadable add-on and from Windows 2000 on it is a bundled component of Windows. Here my example is loading the installation path to Mozilla Thunderbird:
Const HKEY_LOCAL_MACHINE = &H80000002
Set objRegistry = GetObject("winmgmts:\\.\root\default:StdRegProv")
strKey_Path = "SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\thunderbird.exe"
' here the value name is blank, because I want the default value for the key, otherwise it wouldn't be ""
strValue_Name = ""
objRegistry.GetStringValue HKEY_LOCAL_MACHINE, strKey_Path, strValue_Name, strThunderbird_Path

Resources