how to remove file association in vb.net

I found this code on google:
        Dim ruta As String = Replace(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase), "file:\", "")
        Dim extension As String = ".ssc"
        Dim name As String = "Diagrama de D&D Lab-Sketcher"
        Dim description As String = "Sketcher Diagram File"
        Dim applicationPath As String = ruta & "\diagrama.exe"

        Dim iconPath As String = Path.Combine(ruta, "h2o.ico")
        AssociateFile(extension, name, description, iconPath, applicationPath)

Open in new window


    Public Sub AssociateFile(ByVal extension As String, ByVal name As String, ByVal description As String, ByVal iconPath As String, ByVal applicationPath As String)
        'MsgBox("1")
        'Validate arguments
        If String.IsNullOrEmpty(extension) OrElse Not extension.StartsWith(".") Then Throw New ArgumentException("Extension must not be null, must also start with '.'", "extension")
        If String.IsNullOrEmpty(description) Then Throw New ArgumentException("description must not be null", "description")
        'MsgBox("2")
        'Allow nothing to be passed for the icon file
        Dim iconFile As FileInfo = Nothing
        If iconPath IsNot Nothing Then
            iconFile = New FileInfo(iconPath)
            If Not iconFile.Exists Then Throw New ArgumentException("Icon file does not exist", "iconPath")
        End If
        'MsgBox("3")
        Dim applicationFile As New FileInfo(applicationPath)
        If Not applicationFile.Exists Then Throw New ArgumentException(applicationPath, "applicationFile")
        'MsgBox("4")
        'Create .extension value
        My.Computer.Registry.ClassesRoot.CreateSubKey(extension).SetValue("", name, Microsoft.Win32.RegistryValueKind.String)
        'MsgBox("5")
        'Create filename value
        My.Computer.Registry.ClassesRoot.CreateSubKey((name & "\shell\open\command")).SetValue("", (applicationFile.FullName & " ""%l"" "), Microsoft.Win32.RegistryValueKind.String)
        'MsgBox("6")
        'Set the description for the file name
        My.Computer.Registry.ClassesRoot.CreateSubKey(name).SetValue("", description)
        'MsgBox("7")
        'Associate an icon if we were passed one
        If iconFile IsNot Nothing Then _
            My.Computer.Registry.ClassesRoot.CreateSubKey((name & "\DefaultIcon")).SetValue("", iconFile.FullName, Microsoft.Win32.RegistryValueKind.String)
    End Sub

Open in new window


It allows me to register and associate to a diagrama.exe all files with the extension "ssc".

I would like to know how to delete this association once that my project is uninstalled
altariamx2003Asked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

altariamx2003Author Commented:
In this link : http://binaryworld.net/

I found and interesting example in vb6 about how to do it (http://binaryworld.net/Main/CodeDetail.aspx?CodeId=1422)

it use the functions:
    GetRegistryValue (http://binaryworld.net/Main/CodeDetail.aspx?CodeId=1542)
    DeleteRegistryKey(http://binaryworld.net/Main/CodeDetail.aspx?CodeId=1423)

After a while I made the translation, and this is my code:
Public Class Form1
    ' Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal dest As Object, ByVal source As Object, ByVal bytes 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, ByVal phkResult As Long) As Long
    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, ByVal lpType As Long, ByVal lpData As Object, ByVal lpcbData As Long) As Long
    Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal dest As Object, ByVal source As Object, ByVal numBytes As Long)
    Private Declare Function RegDeleteKey Lib "advapi32.dll" Alias "RegDeleteKeyA" (ByVal hKey As Long, ByVal lpSubKey As String) As Long
    Const KEY_READ = &H20019 ' ((READ_CONTROL Or KEY_QUERY_VALUE Or
    Declare Sub SHChangeNotify Lib "shell32" (ByVal wEventId As Long, ByVal uFlags As Long, ByVal dwItem1 As Object, ByVal dwItem2 As Object)

    Const REG_SZ = 1
    Const REG_EXPAND_SZ = 2
    Const REG_BINARY = 3
    Const REG_DWORD = 4
    Const REG_MULTI_SZ = 7
    Const ERROR_MORE_DATA = 234
    Const SHCNF_IDLIST = &H0
    Const SHCNE_ASSOCCHANGED = &H8000000&



    Function GetRegistryValue(ByVal hKey As Long, ByVal KeyName As String, ByVal ValueName As String, Optional ByVal DefaultValue As Object = Nothing) As Object
        Dim handle As Long
        Dim resLong As Long
        Dim resString As String
        Dim resBinary() As Byte
        'Dim resBinary1() As Byte
        Dim length As Long
        Dim retVal As Long
        Dim valueType As Long
        'Optional ByRef DefaultValue  As SomeObjectType = Nothing
        ' Prepare the default result
        GetRegistryValue = IIf((DefaultValue = Nothing), Nothing, DefaultValue)

        ' Open the key, exit if not found.
        If RegOpenKeyEx(hKey, KeyName, 0, KEY_READ, handle) Then
            Exit Function
        End If

        ' prepare a 1K receiving resBinary
        length = 1024
        ReDim resBinary(0 To length - 1)

        ' read the registry key
        retVal = RegQueryValueEx(handle, ValueName, 0, valueType, resBinary(0), length)
        ' if resBinary was too small, try again
        If retVal = ERROR_MORE_DATA Then
            ' enlarge the resBinary, and read the value again
            ReDim resBinary(0 To length - 1)
            retVal = RegQueryValueEx(handle, ValueName, 0, valueType, resBinary(0), length)
        End If

        ' return a value corresponding to the value type
        Select Case valueType
            Case REG_DWORD
                CopyMemory(resLong, resBinary(0), 4)
                GetRegistryValue = resLong
            Case REG_SZ, REG_EXPAND_SZ
                ' copy everything but the trailing null char
                resString = Space$(length - 1)

                CopyMemory(resString, resBinary(0), length - 1)
                GetRegistryValue = resString
            Case REG_BINARY
                ' resize the result resBinary
                If length <> UBound(resBinary) + 1 Then
                    ReDim Preserve resBinary(0 To length - 1)
                End If
                'GetRegistryValue = VB6.CopyArray(resBinary)
                'GetRegistryValue = Array.Copy(resBinary, GetRegistryValue, length)
                'GetRegistryValue = VB6.CopyArray(resBinary)

                resBinary.CopyTo(GetRegistryValue, 0)

            Case REG_MULTI_SZ
                ' copy everything but the 2 trailing null chars
                resString = Space$(length - 2)
                CopyMemory(resString, resBinary(0), length - 2)
                GetRegistryValue = resString
            Case Else
                RegCloseKey(handle)
                Err.Raise(1001, , "Unsupported value type")
        End Select

        ' close the registry key
        RegCloseKey(handle)
    End Function


    Sub DeleteRegistryKey(ByVal hKey As Long, ByVal KeyName As String)
        RegDeleteKey(hKey, KeyName)
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim ClassName As String
        Dim Extension As String = "fbl"
        Const HKEY_CLASSES_ROOT = &H80000000

        ' ensure that there is a leading dot
        If Extension.Substring(0, 1) <> "." Then
            Extension = "." & Extension
        End If

        ' read the associated class name
        ClassName = GetRegistryValue(HKEY_CLASSES_ROOT, Extension, "")
        ' exit if there is no extension association
        If Len(ClassName) = 0 Then Exit Sub

        ' delete this key
        DeleteRegistryKey(HKEY_CLASSES_ROOT, Extension)
        ' delete the other key where registration data is found
        DeleteRegistryKey(HKEY_CLASSES_ROOT, ClassName)

        ' notify Windows that file associations have changed
        SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, 0, 0)
    End Sub
End Class

Open in new window



It seems to works, but Im the function GetRegistryValue, on the line: "If RegOpenKeyEx(hKey, KeyName, 0, KEY_READ, handle) Then" when the program try to find the key, no matter what key should I try to find (".doc, ".xls", etc.....) it never find it.

In the example of my code Im looking for a custom type file with the extension ".fbl"

My code is ok???

What im doing wrong????????????
altariamx2003Author Commented:
What does mean the neglected status?
Bob LearnedCommented:
It looks  like the original code in the question is showing how to create an association by creating a Windows registry setting.

        'Create filename value
        My.Computer.Registry.ClassesRoot.CreateSubKey((name & "\shell\open\command")).SetValue("", (applicationFile.FullName & " ""%l"" "), RegistryValueKind.String)
        'Set the description for the file name
        My.Computer.Registry.ClassesRoot.CreateSubKey(name).SetValue("", description)
        'Associate an icon if we were passed one
        If iconFile IsNot Nothing Then _
            My.Computer.Registry.ClassesRoot.CreateSubKey((name & "\DefaultIcon")).SetValue("", iconFile.FullName, RegistryValueKind.String)

To remove the file association, you would need to do the reverse operations, using DeleteSubKey.

RegistryKey.DeleteSubKey Method (String)
https://msdn.microsoft.com/en-us/library/e5kx5x6a(v=vs.110).aspx
Rowby Goren Makes an Impact on Screen and Online

Learn about longtime user Rowby Goren and his great contributions to the site. We explore his method for posing questions that are likely to yield a solution, and take a look at how his career transformed from a Hollywood writer to a website entrepreneur.

altariamx2003Author Commented:
I know that my original code creates an association a program with a custom extension,  thats way Im asking how to delete that association.

can you check the code that I translate to see what is wrong???

Public Class Form1
    ' Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal dest As Object, ByVal source As Object, ByVal bytes 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, ByVal phkResult As Long) As Long
    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, ByVal lpType As Long, ByVal lpData As Object, ByVal lpcbData As Long) As Long
    Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal dest As Object, ByVal source As Object, ByVal numBytes As Long)
    Private Declare Function RegDeleteKey Lib "advapi32.dll" Alias "RegDeleteKeyA" (ByVal hKey As Long, ByVal lpSubKey As String) As Long
    Const KEY_READ = &H20019 ' ((READ_CONTROL Or KEY_QUERY_VALUE Or
    Declare Sub SHChangeNotify Lib "shell32" (ByVal wEventId As Long, ByVal uFlags As Long, ByVal dwItem1 As Object, ByVal dwItem2 As Object)

    Const REG_SZ = 1
    Const REG_EXPAND_SZ = 2
    Const REG_BINARY = 3
    Const REG_DWORD = 4
    Const REG_MULTI_SZ = 7
    Const ERROR_MORE_DATA = 234
    Const SHCNF_IDLIST = &H0
    Const SHCNE_ASSOCCHANGED = &H8000000&



    Function GetRegistryValue(ByVal hKey As Long, ByVal KeyName As String, ByVal ValueName As String, Optional ByVal DefaultValue As Object = Nothing) As Object
        Dim handle As Long
        Dim resLong As Long
        Dim resString As String
        Dim resBinary() As Byte
        'Dim resBinary1() As Byte
        Dim length As Long
        Dim retVal As Long
        Dim valueType As Long
        'Optional ByRef DefaultValue  As SomeObjectType = Nothing
        ' Prepare the default result
        GetRegistryValue = IIf((DefaultValue = Nothing), Nothing, DefaultValue)

        ' Open the key, exit if not found.
        If RegOpenKeyEx(hKey, KeyName, 0, KEY_READ, handle) Then
            Exit Function
        End If

        ' prepare a 1K receiving resBinary
        length = 1024
        ReDim resBinary(0 To length - 1)

        ' read the registry key
        retVal = RegQueryValueEx(handle, ValueName, 0, valueType, resBinary(0), length)
        ' if resBinary was too small, try again
        If retVal = ERROR_MORE_DATA Then
            ' enlarge the resBinary, and read the value again
            ReDim resBinary(0 To length - 1)
            retVal = RegQueryValueEx(handle, ValueName, 0, valueType, resBinary(0), length)
        End If

        ' return a value corresponding to the value type
        Select Case valueType
            Case REG_DWORD
                CopyMemory(resLong, resBinary(0), 4)
                GetRegistryValue = resLong
            Case REG_SZ, REG_EXPAND_SZ
                ' copy everything but the trailing null char
                resString = Space$(length - 1)

                CopyMemory(resString, resBinary(0), length - 1)
                GetRegistryValue = resString
            Case REG_BINARY
                ' resize the result resBinary
                If length <> UBound(resBinary) + 1 Then
                    ReDim Preserve resBinary(0 To length - 1)
                End If
                'GetRegistryValue = VB6.CopyArray(resBinary)
                'GetRegistryValue = Array.Copy(resBinary, GetRegistryValue, length)
                'GetRegistryValue = VB6.CopyArray(resBinary)

                resBinary.CopyTo(GetRegistryValue, 0)

            Case REG_MULTI_SZ
                ' copy everything but the 2 trailing null chars
                resString = Space$(length - 2)
                CopyMemory(resString, resBinary(0), length - 2)
                GetRegistryValue = resString
            Case Else
                RegCloseKey(handle)
                Err.Raise(1001, , "Unsupported value type")
        End Select

        ' close the registry key
        RegCloseKey(handle)
    End Function


    Sub DeleteRegistryKey(ByVal hKey As Long, ByVal KeyName As String)
        RegDeleteKey(hKey, KeyName)
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim ClassName As String
        Dim Extension As String = "fbl"
        Const HKEY_CLASSES_ROOT = &H80000000

        ' ensure that there is a leading dot
        If Extension.Substring(0, 1) <> "." Then
            Extension = "." & Extension
        End If

        ' read the associated class name
        ClassName = GetRegistryValue(HKEY_CLASSES_ROOT, Extension, "")
        ' exit if there is no extension association
        If Len(ClassName) = 0 Then Exit Sub

        ' delete this key
        DeleteRegistryKey(HKEY_CLASSES_ROOT, Extension)
        ' delete the other key where registration data is found
        DeleteRegistryKey(HKEY_CLASSES_ROOT, ClassName)

        ' notify Windows that file associations have changed
        SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, 0, 0)
    End Sub
End Class

Open in new window


It seems to works, but Im the function GetRegistryValue, on the line: "If RegOpenKeyEx(hKey, KeyName, 0, KEY_READ, handle) Then" when the program try to find the key, no matter what key I will try to find (".doc, ".xls", etc.....) it never find it.
CodeCruiserCommented:
The bit wrong with your code is that you are using VB6 approach to manipulate registry when there is built in support for that in VB.NET using My.Computer.Registry namespace which you used in your original code.

As suggested above, just do the reverse of what you do to associate your program.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
altariamx2003Author Commented:
ok thx codecruiser
altariamx2003Author Commented:
that was the solution
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic.NET

From novice to tech pro — start learning today.