none
open and close disc tray?

    Question

  • My cousin and I were discussing the difference between Java and VB.Net and I thought I would make a simple application to show him.

     

    My form has two labels a numerical up and down component and a button.

     

    I want to set it so when my cousin presses the button it will open and close his disk tray for the amount of time he chose using the numerical up and down.

    I have tried making the program using a sample I have acquired but ti keeps throwing this error.

    This is the error.

     

     

    PInvokeStackImbalance was detected

    Message: A call to PInvoke function 'WindowsApplication1!WindowsApplication1.Form1::mciSendString' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.


    This is my source.
    Public Class Form1
    
      'Createing a new timer
      Public lol As New Timer
    
      Declare Function mciSendString Lib "winmm.dll" Alias "mciSendStringA" _
      (ByVal lpCommandString As String, ByVal lpReturnString As String, _
      ByVal uReturnLength As Long, ByVal hwndCallback As Long) As Long
    
      Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
    
    
    
        If nmInterval.Value = 0 Then
    
          MessageBox.Show("Please select a number using the box on your left!", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error)
          Exit Sub
    
        ElseIf nmInterval.Value >= 1 Then
          lol.Interval = nmInterval.Value * 1000
          'Setting the properties of lblDisplay
          lblDisplay.Text = "Being Annoying!"
          lblDisplay.ForeColor = Color.Coral
    
          'Starting the timer
          lol.Start()
    
        End If
    
        If lol.Enabled = True Then
    
          mciSendString("open", "", 0, 0)
          mciSendString("close", "", 0, 0)
    
        ElseIf lol.Enabled = False Then
    
          Exit Sub
    
        End If
    
      End Sub
    
    
    End Class
    

    I'm not sure what I have done wrong and I don't have local assisstance installed at the moment.

    Any help would be greatly appriciated.

    Thanks in advance.

    Jai Brown

     

    Sunday, June 20, 2010 4:02 AM

All replies

  • Where is your timer_tick event?, your McisendString for close method  should be inside the timer tick event something like below. Also, you are calling the 2 methods at the same time.

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
           
    mciSendString("close", "", 0, 0)

    End Sub

    Also,  you should declare your timer like Friend WithEvents Timer1 As System.Windows.Forms.Timer. Why dont you drag the timer control from toolbox to your form instead of declared it yourself 

     kaymaf


    CODE CONVERTER SITE

    http://www.carlosag.net/Tools/CodeTranslator/.

    http://www.developerfusion.com/tools/convert/csharp-to-vb/.

    Sunday, June 20, 2010 5:27 AM
  • Thanks heaps kaymaf.

    I will give it a try.

    My cousin seems to think that because vb.net relies on the .net framework it is useless but I am trying to turn him lol.

    If I can get this to work I will mark your post as the answer.

     

    Thanks again

    Jai Brown

     

    Edit:

    Also if I am just dragging the timer from the tool bar I don't need to declare it like this right?

    Friend WithEvents Timer1 As System.Windows.Forms.Timer.

     

    And how would I make it so I can call the open and close functions seperately?

    Would I do this?

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
    
        openTray()
    
      End Sub
    
      Public Sub openTray()
    
        mciSendString("open", "", 0, 0)
    
        closeTray()
    
      End Sub
    
      Public Sub closeTray()
    
        mciSendString("close", "", 0, 0)
    
      End Sub
    If so how can I make it loop for the remainder of Timer1_Tick's Interval?

    Sunday, June 20, 2010 5:58 AM
  • Your message shows up to me like a Dutchman who is telling in a discussion with somebody from Chicago what is the difference between the law from Ohio and Illinois.

    If you want to show something, than use elements from the language and be sure that you know all ins and outs, using old DLL's is certainly not meant as significant of VB Net. Using those is meant to overcome for things which are (still) not possible with Net.

    Take a look at system.windows.media, I don't know if opening and closing of a disc tray is possible with that, but it can be that the feature is removed, because the OS does that if there is needed to load a new disc or a disc is burned.


    Success
    Cor

    Sunday, June 20, 2010 6:09 AM
  • try this

    Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
     
       mciSendString("set cdaudio door open", 0, 0, 0)
       Timer1.Enabled = True
      
     End Sub

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick

      mciSendString("set cdaudio door closed", 0, 0, 0)
      Timer1.Enabled = False

      End Sub

    kaymaf


    CODE CONVERTER SITE

    http://www.carlosag.net/Tools/CodeTranslator/.

    http://www.developerfusion.com/tools/convert/csharp-to-vb/.

    Sunday, June 20, 2010 6:21 AM
  • Your message shows up to me like a Dutchman who is telling in a discussion with somebody from Chicago what is the difference between the law from Ohio and Illinois.

    If you want to show something, than use elements from the language and be sure that you know all ins and outs, using old DLL's is certainly not meant as significant of VB Net. Using those is meant to overcome for things which are (still) not possible with Net.

    Take a look at system.windows.media, I don't know if opening and closing of a disc tray is possible with that, but it can be that the feature is removed, because the OS does that if there is needed to load a new disc or a disc is burned.

     


    Success
    Cor

     What your psychology expression have to do with OP question, If you live in US, you will know that there is state and federal law.

    And there is nothing wrong with the API, not every one is chasing .net around or kissing .NET Axx (sub s for x). Everyone know .net framework is cover up from classic VB.

    kaymaf


    CODE CONVERTER SITE

    http://www.carlosag.net/Tools/CodeTranslator/.

    http://www.developerfusion.com/tools/convert/csharp-to-vb/.

    Sunday, June 20, 2010 6:41 AM
  • Your message shows up to me like a Dutchman who is telling in a discussion with somebody from Chicago what is the difference between the law from Ohio and Illinois.

    If you want to show something, than use elements from the language and be sure that you know all ins and outs, using old DLL's is certainly not meant as significant of VB Net. Using those is meant to overcome for things which are (still) not possible with Net.

    Take a look at system.windows.media, I don't know if opening and closing of a disc tray is possible with that, but it can be that the feature is removed, because the OS does that if there is needed to load a new disc or a disc is burned.

     


    Success
    Cor

     

    That isn't very nice lol.

    I'm sorry if my explanation isn't very good but I am really new to vb.net so I don't understand how to use the dll's. But with batch I know how to. So please don't flame me if I am not getting everything right. I joined this forum to learn how to code better using VB.

    And I am trying to do as many different projects as possible.

     

    @kaymaf

    I tried what you suggested but it throws this error still.

    PInvokeStackImbalance was detected

    Message: A call to PInvoke function 'WindowsApplication1!WindowsApplication1.Form1::mciSendString' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.



    This is my source so far.

     

    Public Class Form1
    
      Declare Function mciSendString Lib "winmm.dll" Alias "mciSendStringA" _
      (ByVal lpCommandString As String, ByVal lpReturnString As String, _
      ByVal uReturnLength As Long, ByVal hwndCallback As Long) As Long
    
      Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
    
    
    
        If nmInterval.Value = 0 Then
    
          MessageBox.Show("Please select a number using the box on your left!", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error)
          Exit Sub
    
        ElseIf nmInterval.Value >= 1 Then
          Timer1.Interval = nmInterval.Value * 1000
          'Setting the properties of lblDisplay
          lblDisplay.Text = "Being Annoying!"
          lblDisplay.ForeColor = Color.Coral
    
          'Starting the timer
          Timer1.Start()
    
        End If
    
        mciSendString("set cdaudio door open", 0, 0, 0)
        Timer1.Enabled = True
    
      End Sub
    
      Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
    
        mciSendString("set cdaudio door closed", 0, 0, 0)
        Timer1.Enabled = False
    
      End Sub
    
    End Class
    

    Sunday, June 20, 2010 6:53 AM
  • It works on my side, Did you add the import to runime as below because when you calling API, you need that.

    Imports System.Runtime.InteropServices

    kaymaf


    CODE CONVERTER SITE

    http://www.carlosag.net/Tools/CodeTranslator/.

    http://www.developerfusion.com/tools/convert/csharp-to-vb/.

    • Marked as answer by Shadow_69_91 Sunday, June 20, 2010 7:48 AM
    • Unmarked as answer by Shadow_69_91 Sunday, June 20, 2010 7:49 AM
    Sunday, June 20, 2010 7:07 AM
  • I have added the import but I still get the error.

    vb.net really doesn't like me today. :(

    Sunday, June 20, 2010 7:51 AM
  • What's the timers interval?

    If it's too short, it will attempt to close the tray before it has fully opened.

    Try changing it to a longer duration like 3000 ms, which is 3 seconds.

    Sunday, June 20, 2010 9:37 AM
  • Hello Jai.Brown,

    As Cor Ligthert wrote, you are only proving that the two languages are able to use API.

    However, try this

    Const drive As String = "D" 'letter must be capitalized
    
    'to open disk tray
    mciSendString("open " & drive & ": type CDAudio alias drive" & drive, Nothing, 0, 0)
    mciSendString("set drive" & drive & " door open", Nothing, 0, 0)
    
    'to close disk tray
    mciSendString("open " & drive & ": type CDAudio alias drive" & drive, Nothing, 0, 0)
    mciSendString("set drive" & drive & " door closed", Nothing, 0, 0)
    
    
    Sunday, June 20, 2010 9:38 AM
  • The correct signature for mcisendstring can be found at http://www.pinvoke.net/default.aspx/winmm.mciSendString

    Sunday, June 20, 2010 10:01 AM
  • Reference Imapi2.dll and Imapi2fs.dll in the System32 directory.  Download and install for XP.

    Imports IMAPI2
    Public Class Form1
      
    Dim Recorder As MsftDiscRecorder2
      
    Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
        Recorder.EjectMedia()
      
    End Sub
      Private Sub Button2_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button2.Click
        Recorder.CloseTray()
      
    End Sub
      Public Sub New()
        InitializeComponent()
        Button1.Text = 
    "Open"
        Button2.Text = "Close"
        Dim Master As New MsftDiscMaster2
        Recorder = 
    New MsftDiscRecorder2
        Recorder.InitializeDiscRecorder(Master(0))
      
    End Sub
    End
     Class

    Opening the tray for a timespan is left as an exercise.

    • Marked as answer by Shadow_69_91 Sunday, June 20, 2010 10:25 AM
    • Unmarked as answer by Shadow_69_91 Sunday, June 20, 2010 10:27 AM
    Sunday, June 20, 2010 10:06 AM
  • What's the timers interval?

    If it's too short, it will attempt to close the tray before it has fully opened.

    Try changing it to a longer duration like 3000 ms, which is 3 seconds.

    I have a numerical up down that allows the user to set the timer. Have a look in my code.

     

    @Nerres I Still get the same error. This is the source using the code you gave me.

    Imports System.Runtime.InteropServices
    
    Public Class Form1
    
      Const drive As String = "D" 'letter must be capitalized
    
      Declare Function mciSendString Lib "winmm.dll" Alias "mciSendStringA" _
      (ByVal lpCommandString As String, ByVal lpReturnString As String, _
      ByVal uReturnLength As Long, ByVal hwndCallback As Long) As Long
    
      Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
    
    
    
        If nmInterval.Value = 0 Then
    
          MessageBox.Show("Please select a number using the box on your left!", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error)
          Exit Sub
    
        ElseIf nmInterval.Value >= 1 Then
          Timer1.Interval = nmInterval.Value * 1000
    
          'Setting the properties of lblDisplay
          lblDisplay.Text = "Being Annoying!"
          lblDisplay.ForeColor = Color.Coral
    
          'Starting the timer
          Timer1.Start()
    
        End If
    
    
        'to open disk tray
        mciSendString("open " & drive & ": type CDAudio alias drive" & drive, Nothing, 0, 0)
        mciSendString("set drive" & drive & " door open", Nothing, 0, 0)
    
      End Sub
    
      Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
    
        'to close disk tray
        mciSendString("open " & drive & ": type CDAudio alias drive" & drive, Nothing, 0, 0)
        mciSendString("set drive" & drive & " door closed", Nothing, 0, 0)
    
      End Sub
    
    End Class
    

    Sunday, June 20, 2010 10:11 AM
  • This Reference Imapi2.dll and Imapi2fs.dll in the System32 directory.  Download and install for XP.

    Imports IMAPI2
    Public Class Form1
      
    Dim Recorder As MsftDiscRecorder2
      
    Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
        Recorder.EjectMedia()
      
    End Sub
      Private Sub Button2_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button2.Click
        Recorder.CloseTray()
      
    End Sub
      Public Sub New()
        InitializeComponent()
        Button1.Text = 
    "Open"
        Button2.Text = "Close"
        Dim Master As New MsftDiscMaster2
        Recorder = 
    New MsftDiscRecorder2
        Recorder.InitializeDiscRecorder(Master(0))
      
    End Sub
    End
     Class

    Opening the tray for a timespan is left as an exercise.




    This works perfect thank you. now I just need to figure out how to make it open and close on a loop with a one second interval between each command until the timer has finished counting.
    Sunday, June 20, 2010 10:29 AM
  • Hello Jai.Brown,

    this works for me (follow 'changed to')

    Public Class Form1
    
      Const drive As String = "D" 'letter must be capitalized
    
      'Declare Function mciSendString Lib "winmm.dll" Alias "mciSendStringA" _
      '(ByVal lpCommandString As String, ByVal lpReturnString As String, _
      'ByVal uReturnLength As Long, ByVal hwndCallback As Long) As Long
    
      'changed to
      Declare Function mciSendString Lib "winmm.dll" Alias "mciSendStringA" (ByVal command As String, ByVal buffer As String, ByVal bufferSize As Int32, ByVal hwndCallback As IntPtr) As Int32
    
      Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
    
       If nmInterval.Value = 0 Then
    
         MessageBox.Show("Please select a number using the box on your left!", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error)
         Exit Sub
    
       ElseIf nmInterval.Value >= 1 Then
         Timer1.Interval = CInt(nmInterval.Value * 1000)
    
         'Setting the properties of lblDisplay
         lblDisplay.Text = "Being Annoying!"
         lblDisplay.ForeColor = Color.Coral
    
         ''to open disk tray
         'mciSendString("open " & drive & ": type CDAudio alias drive" & drive, Nothing, 0, 0)
         'mciSendString("set drive" & drive & " door open", Nothing, 0, 0)
    
         'changed to
         mciSendString("open " & drive & ": type CDAudio alias drive" & drive, Nothing, 0, CType(0, IntPtr))
         mciSendString("set drive" & drive & " door open", Nothing, 0, CType(0, IntPtr))
    
         'Starting the timer
         Timer1.Start()
    
       End If
    
      End Sub
    
      Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
    
       'to close disk tray
       'mciSendString("open " & drive & ": type CDAudio alias drive" & drive, Nothing, 0, 0)
       'mciSendString("set drive" & drive & " door closed", Nothing, 0, 0)
    
       'changed to
       Timer1.Stop()
       mciSendString("open " & drive & ": type CDAudio alias drive" & drive, Nothing, 0, CType(0, IntPtr))
       mciSendString("set drive" & drive & " door closed", Nothing, 0, CType(0, IntPtr))
      End Sub
    
    End Class
    
    

    Beware, if you open/close the cd tray, in a continuous loop, you risk breaking your CD player (or that of your cousin) :-)

    Sunday, June 20, 2010 11:18 AM
  • Hello Jai.Brown,

    this works for me (follow 'changed to')

    Public Class Form1
    
     Const drive As String = "D" 'letter must be capitalized
    
     'Declare Function mciSendString Lib "winmm.dll" Alias "mciSendStringA" _
     '(ByVal lpCommandString As String, ByVal lpReturnString As String, _
     'ByVal uReturnLength As Long, ByVal hwndCallback As Long) As Long
    
     'changed to
     Declare Function mciSendString Lib "winmm.dll" Alias "mciSendStringA" (ByVal command As String, ByVal buffer As String, ByVal bufferSize As Int32, ByVal hwndCallback As IntPtr) As Int32
    
     Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
    
      If nmInterval.Value = 0 Then
    
       MessageBox.Show("Please select a number using the box on your left!", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error)
       Exit Sub
    
      ElseIf nmInterval.Value >= 1 Then
       Timer1.Interval = CInt(nmInterval.Value * 1000)
    
       'Setting the properties of lblDisplay
       lblDisplay.Text = "Being Annoying!"
       lblDisplay.ForeColor = Color.Coral
    
       ''to open disk tray
       'mciSendString("open " & drive & ": type CDAudio alias drive" & drive, Nothing, 0, 0)
       'mciSendString("set drive" & drive & " door open", Nothing, 0, 0)
    
       'changed to
       mciSendString("open " & drive & ": type CDAudio alias drive" & drive, Nothing, 0, CType(0, IntPtr))
       mciSendString("set drive" & drive & " door open", Nothing, 0, CType(0, IntPtr))
    
       'Starting the timer
       Timer1.Start()
    
      End If
    
     End Sub
    
     Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
    
      'to close disk tray
      'mciSendString("open " & drive & ": type CDAudio alias drive" & drive, Nothing, 0, 0)
      'mciSendString("set drive" & drive & " door closed", Nothing, 0, 0)
    
      'changed to
      Timer1.Stop()
      mciSendString("open " & drive & ": type CDAudio alias drive" & drive, Nothing, 0, CType(0, IntPtr))
      mciSendString("set drive" & drive & " door closed", Nothing, 0, CType(0, IntPtr))
     End Sub
    
    End Class
    
    
    

    Beware, if you open/close the cd tray, in a continuous loop, you risk breaking your CD player (or that of your cousin) :-)

    Well we both have laptops but that is why I wanted add a timer in between opening and closing the disk tray.

     

    I am using part of the code from John Wein now so it is working but I just want to use the timers to make it run on a continuous loop with a few seconds in the between.

    Sunday, June 20, 2010 11:38 AM
  • I am using part of the code from John Wein now so it is working but I just want to use the timers to make it run on a continuous loop with a few seconds in the between.


    Hello Jai.Brown,

    on the topic of current thread, it was shown that [both Java and] Vb.Net can use the APIs.

    As suggested by JohnWein, you can always add two separate Button (although I prefer not install additional DLLs if I can obtain in another way what I need).

    Sunday, June 20, 2010 1:06 PM
  • See I don't understand what an API is.

    Is it just an archive that the IDE accesses to retrieve information about a certain block of code?

     

    And I understand about the dll's but if you add them to resources any other person should be able to run the application without having to download it right?

     

    Sorry if all these questions are annoying in any way but I try to get as much information from my threads as possible.

     

    Also one off topic question...

     

    How can I find if a file exists on my computer? 

    Lets say on my desktop for example?

    I would like to make it so when I have made a program that is worth while I can have it delete my original and replace it with mine as an update kind of thing as I am going to make myself a tool kit which allows me to run my AV and Malwarebytes etc so I don't have to select them separately. I used to do it with a batch file that creates a vb script to activate the programs and then send the enter key. I am kind of lazy and like to make little applications like this :)

    Sunday, June 20, 2010 11:50 PM