Re: Timer Problem

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



Hallo Arne!

Ich habe mich an folgende Anleitung gehalten:
http://www.codeproject.com/vb/net/WindowsServiceInstall.asp

Mein Code sieht derzeit folgendermaßen aus:

ProjectInstaller.vb:
Imports System.ComponentModel

Imports System.Configuration.Install

Imports System.Runtime.InteropServices

<RunInstaller(True)> Public Class ProjectInstaller

Inherits System.Configuration.Install.Installer

#Region " Vom Component Designer generierter Code "

Public Sub New()

MyBase.New()

' Dieser Aufruf ist für den Komponenten-Designer erforderlich.

InitializeComponent()

' Initialisierungen nach dem Aufruf InitializeComponent() hinzufügen

End Sub

'Installer überschreibt den Löschvorgang zum Bereinigen der
Komponentenliste.

Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)

If disposing Then

If Not (components Is Nothing) Then

components.Dispose()

End If

End If

MyBase.Dispose(disposing)

End Sub

' Für Komponenten-Designer erforderlich

Private components As System.ComponentModel.IContainer

'HINWEIS: Die folgende Prozedur ist für den Komponenten-Designer
erforderlich

'Sie kann mit dem Komponenten-Designer modifiziert werden.

'Verwenden Sie nicht den Code-Editor zur Bearbeitung.

Friend WithEvents ServiceProcessInstaller1 As
System.ServiceProcess.ServiceProcessInstaller

Friend WithEvents ServiceInstaller1 As
System.ServiceProcess.ServiceInstaller

<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()

Me.ServiceProcessInstaller1 = New
System.ServiceProcess.ServiceProcessInstaller

Me.ServiceInstaller1 = New System.ServiceProcess.ServiceInstaller

'

'ServiceProcessInstaller1

'

Me.ServiceProcessInstaller1.Account =
System.ServiceProcess.ServiceAccount.LocalSystem

Me.ServiceProcessInstaller1.Password = Nothing

Me.ServiceProcessInstaller1.Username = Nothing

'

'ServiceInstaller1

'

Me.ServiceInstaller1.ServiceName = "TKPlayer"

Me.ServiceInstaller1.StartType =
System.ServiceProcess.ServiceStartMode.Automatic

'

'ProjectInstaller

'

Me.Installers.AddRange(New System.Configuration.Install.Installer()
{Me.ServiceProcessInstaller1, Me.ServiceInstaller1})

End Sub

#End Region

Private Sub ProjectInstaller_AfterInstall(ByVal sender As Object, ByVal e As
System.Configuration.Install.InstallEventArgs) Handles MyBase.AfterInstall

'Our code goes in this event because it is the only one that will do

'a proper job of letting the user know that an error has occurred,

'if one indeed occurs. Installation will be rolled back if an error occurs.

Dim iSCManagerHandle As Integer

Dim iSCManagerLockHandle As Integer

Dim iServiceHandle As Integer

Dim bChangeServiceConfig As Boolean

Dim bChangeServiceConfig2 As Boolean

Dim ServiceDescription As modAPI.SERVICE_DESCRIPTION

Dim ServiceFailureActions As modAPI.SERVICE_FAILURE_ACTIONS

Dim ScActions(2) As modAPI.SC_ACTION 'There should be one element for each

'action. The Services snap-in shows 3 possible actions.

Dim bCloseService As Boolean

Dim bUnlockSCManager As Boolean

Dim bCloseSCManager As Boolean

Dim iScActionsPointer As New IntPtr

Try

'Obtain a handle to the Service Control Manager, with appropriate rights.

'This handle is used to open the relevant service.

iSCManagerHandle = modAPI.OpenSCManager(vbNullString, vbNullString,
modAPI.ServiceControlManagerType.SC_MANAGER_ALL_ACCESS)

'Check that it's open. If not throw an exception.

If iSCManagerHandle < 1 Then

Throw New Exception("Unable to open the Services Manager.")

End If

'Lock the Service Control Manager database.

iSCManagerLockHandle = modAPI.LockServiceDatabase(iSCManagerHandle)

'Check that it's locked. If not throw an exception.

If iSCManagerLockHandle < 1 Then

Throw New Exception("Unable to lock the Services Manager.")

End If

'Obtain a handle to the relevant service, with appropriate rights.

'This handle is sent along to change the settings. The second parameter

'should contain the name you assign to the service.

iServiceHandle = modAPI.OpenService(iSCManagerHandle, "ServiceTest", _

modAPI.ACCESS_TYPE.SERVICE_ALL_ACCESS)

'Check that it's open. If not throw an exception.

If iServiceHandle < 1 Then

Throw New Exception("Unable to open the Service for modification.")

End If

'Call ChangeServiceConfig to update the ServiceType

'to SERVICE_INTERACTIVE_PROCESS.

'Very important is that you do not leave out or change the other relevant

'ServiceType settings. The call will return False if you do.

'Also, only services that use the LocalSystem account can be set to

'SERVICE_INTERACTIVE_PROCESS.

bChangeServiceConfig = modAPI.ChangeServiceConfig(iServiceHandle, _

modAPI.ServiceType.SERVICE_WIN32_OWN_PROCESS + _

modAPI.ServiceType.SERVICE_INTERACTIVE_PROCESS, _

SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, vbNullString, vbNullString, _

vbNullString, vbNullString, vbNullString, vbNullString, vbNullString)

'If the call is unsuccessful, throw an exception.

If Not bChangeServiceConfig Then

Throw New Exception("Unable to change the Service settings.")

End If

'To change the description, create an instance of the SERVICE_DESCRIPTION

'structure and set the lpDescription member to your desired description.

ServiceDescription.lpDescription = "todo ..."

'Call ChangeServiceConfig2 with SERVICE_CONFIG_DESCRIPTION in the second

'parameter and the SERVICE_DESCRIPTION instance in the third parameter

'to update the description.

bChangeServiceConfig2 = modAPI.ChangeServiceConfig2(iServiceHandle, _

modAPI.InfoLevel.SERVICE_CONFIG_DESCRIPTION, ServiceDescription)

'If the update of the description is unsuccessful it is up to you to

'throw an exception or not. The fact that the description did not update

'should not impact the functionality of your service.

If Not bChangeServiceConfig2 Then

Throw New Exception("Unable to set the Service description.")

End If

'All code below this line was added on 27 November 2003

'To change the Service Failure Actions, create an instance of the

'SERVICE_FAILURE_ACTIONS structure and set the members to your

'desired values. See MSDN for detailed descriptions.

ServiceFailureActions.dwResetPeriod = 600

ServiceFailureActions.lpRebootMsg = "Service failed to start! Rebooting..."

ServiceFailureActions.lpCommand = ""

ServiceFailureActions.cActions = ScActions.Length

'The lpsaActions member of SERVICE_FAILURE_ACTIONS is a pointer to an

'array of SC_ACTION structures. This complicates matters a little,

'and although it took me a week to figure it out, the solution

'is quite simple.

'First order of business is to populate our array of SC_ACTION structures

'with appropriate values.

ScActions(0).Delay = 20000

ScActions(0).SCActionType = modAPI.SC_ACTION_TYPE.SC_ACTION_RESTART

ScActions(1).Delay = 20000

ScActions(1).SCActionType = modAPI.SC_ACTION_TYPE.SC_ACTION_RUN_COMMAND

ScActions(2).Delay = 20000

ScActions(2).SCActionType = modAPI.SC_ACTION_TYPE.SC_ACTION_REBOOT

'Once that's done, we need to obtain a pointer to a memory location

'that we can assign to lpsaActions in SERVICE_FAILURE_ACTIONS.

'We use 'Marshal.SizeOf(New modAPI.SC_ACTION) * 3' because we pass

'3 actions to our service. If you have less actions

'change the * 3 accordingly.

iScActionsPointer = Marshal.AllocHGlobal( _

Marshal.SizeOf(New modAPI.SC_ACTION) * 3)

'Once we have obtained the pointer for the memory location we need to

'fill the memory with our structure. We use the CopyMemory API function

'for this. Please have a look at it's declaration in modAPI,

'and compare it to MSDN.

modAPI.CopyMemory(iScActionsPointer, ScActions, _

Marshal.SizeOf(New modAPI.SC_ACTION) * 3)

'We set the lpsaActions member of SERVICE_FAILURE_ACTIONS to the integer

'value of our pointer.

ServiceFailureActions.lpsaActions = iScActionsPointer.ToInt32

'We call bChangeServiceConfig2 with the relevant parameters.

bChangeServiceConfig2 = modAPI.ChangeServiceConfig2(iServiceHandle, _

modAPI.InfoLevel.SERVICE_CONFIG_FAILURE_ACTIONS, ServiceFailureActions)

'If the update of the failure actions is unsuccessful it is up to you to

'throw an exception or not. The fact that the failure actions

'did not update

'should not impact the functionality of your service.

If Not bChangeServiceConfig2 Then

Throw New Exception("Unable to set the Service failure actions.")

End If

Catch ex As Exception

Throw ex

Finally

'Once you are done you should close/release the handles to the service

'and the Service Control Manager, as well as free the memory that held

'the array of SC_ACTION structures.

Marshal.FreeHGlobal(iScActionsPointer)

If iServiceHandle > 0 Then

bCloseService = modAPI.CloseServiceHandle(iServiceHandle)

End If

bUnlockSCManager = modAPI.UnlockServiceDatabase(iSCManagerLockHandle)

If iSCManagerHandle > 0 Then

bCloseSCManager = modAPI.CloseServiceHandle(iSCManagerHandle)

End If

End Try

'When installation is done go check out your handy work

'using Computer Management!

End Sub

End Class

und dazu die Service1.vb

Imports System.ServiceProcess

Public Class TKPlayer

Inherits System.ServiceProcess.ServiceBase

Dim tkp As System.Diagnostics.Process

#Region " Vom Component Designer generierter Code "

Public Sub New()

MyBase.New()

' Dieser Aufruf wird vom Komponenten-Designer benötigt.

InitializeComponent()

' Fügen Sie Initialisierungscode hinter dem InitializeComponent()-Aufruf ein

End Sub

'UserService überschreibt den Löschvorgang zum Bereinigen der
Komponentenliste.

Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)

If disposing Then

If Not (components Is Nothing) Then

components.Dispose()

End If

End If

MyBase.Dispose(disposing)

End Sub

' Der Haupteinstiegspunkt für den Vorgang

<MTAThread()> _

Shared Sub Main()

Dim ServicesToRun() As System.ServiceProcess.ServiceBase

' Innerhalb desselben Prozesses können mehrere NT-Dienste ausgeführt werden.
Um einen

' weiteren Dienst zum Prozess hinzuzufügen, änderen Sie die folgende Zeile,

' um ein zweites Dienstprojekt zu erstellen. Z.B.,

'

' ServicesToRun = New System.ServiceProcess.ServiceBase () {New Service1,
New MySecondUserService}

'

ServicesToRun = New System.ServiceProcess.ServiceBase() {New TKPlayer}

System.ServiceProcess.ServiceBase.Run(ServicesToRun)

End Sub

' Für Komponenten-Designer erforderlich

Private components As System.ComponentModel.IContainer

' HINWEIS: Die folgende Prozedur wird vom Komponenten-Designer benötigt.

' Sie kann mit dem Komponenten-Designer modifiziert werden. Verwenden Sie
nicht

' den Code-Editor zur Bearbeitung.

Friend WithEvents Timer1 As System.Timers.Timer

<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()

Me.Timer1 = New System.Timers.Timer

CType(Me.Timer1, System.ComponentModel.ISupportInitialize).BeginInit()

'

'Timer1

'

Me.Timer1.Enabled = True

'

'TKPlayer

'

Me.CanPauseAndContinue = True

Me.ServiceName = "TKPlayer"

CType(Me.Timer1, System.ComponentModel.ISupportInitialize).EndInit()

End Sub

#End Region

Protected Overrides Sub OnStart(ByVal args() As String)

' Add code here to start your service. This method should set things

' in motion so your service can do its work.

Me.LogInfo("Service test started on " & Now.ToLongDateString & " - " &
Now.ToShortTimeString)

tkp = System.Diagnostics.Process.Start("C:\Programme\TKPlayer\tkplayer.exe")

End Sub

Protected Overrides Sub OnStop()

' Add code here to perform any tear-down necessary to stop your service.

Me.LogInfo("Service test stopped on " & Now.ToLongDateString & " - " &
Now.ToShortTimeString)

tkp.CloseMainWindow()

End Sub

Protected Sub LogInfo(ByVal sMessage As String)

' Write info into the event viewer

Try

Dim oEventLog As EventLog = New EventLog("Application")

If Not oEventLog.SourceExists("NotificationService") Then

oEventLog.CreateEventSource("NotificationService", "Application")

End If

oEventLog.WriteEntry("NotificationService", sMessage,
System.Diagnostics.EventLogEntryType.Information)

Catch e As Exception

End Try

End Sub

Protected Sub LogEvent(ByVal sMessage As String)

' Write error into the event viewer

Try

Dim oEventLog As EventLog = New EventLog("Application")

If Not oEventLog.SourceExists("NotificationService") Then

oEventLog.CreateEventSource("NotificationService", "Application")

End If

oEventLog.WriteEntry("NotificationService", sMessage,
System.Diagnostics.EventLogEntryType.Error)

Catch e As Exception

End Try

End Sub

End Class



Wie dort zu sehen, nutze ich System.Timers.Timer :)

Wenn ich das Projekt installiert habe und den Dienst so starten will, kommt
folgende Fehlermeldung:

"Just-In-Time Debuggen" Eine Ausnahme 'System.InvalidCastException' ist in
tkplayer.exe aufgetreten.

Wenn ich das ganze dann Debugge kommt:

Eine nicht behandelte Ausnahme des Typs 'System.InvalidCastException' ist in
microsoft.visualbasic.dll aufgetreten.

Zusätzliche Informationen: Ungültige Konvertierung von der Zeichenfolge
'(none)' in Typ 'Integer'.



Gruß Nils

"Arne Janning" <spam-me-here.iasyncresult@xxxxxxxxx> schrieb im Newsbeitrag
news:%23A6EtatsFHA.3452@xxxxxxxxxxxxxxxxxxxxxxx
> Hallo Nils!
>
> Nils Wöhler wrote:
>> hi, also im entefekt möchte ich, dass der dienst beim systemstart
>> mitgestartet wird und ein programm "tkplayer.exe" startet welches
>> (z.B. wie auch VNC oder so) im hintergrund läuft und seine Arbeit tut.
>>
>> Vielleicht ist Timer ja auch der falsch Ansatz ...
>
> Timer ist schon OK, aber eben nicht System.Windows.Forms.Timer, sondern
> System.Threading.Timer oder System.Timers.Timer!
>
> Deswegen die Frage, welchen Timer hast Du bislang verwendet?
>
> Gruß
>
> Arne Janning
>


.



Relevant Pages