Für Joe, Allgemeine Fragen :)

Hallo Joe,

Ich konzipiere es so. Das der Client je nach Einstellung und Bedarf, bei sich auf dem Rechner einen Scan durchführt und seine Daten ermittelt. Diese schickt er dann zum Server. Der Server vergleicht die Daten und sagt dem Clienten, die und die Datei musst du laden.

Soweit richtig ?

Aber nungut. Fangen wir mit dem Server an!
Ich mache hier mal mehrere Antworten auf. Im Titel zum Bsp. Modul XYZ steht dann der Source zu dem Modul. Wenn du da Fragen hast, dann antworte einfach auf das Thema immer :smile: So sollten wir eine Übersicht behalten, denn es ist wie gesagt ne menge Source. Sehen tust du vorerst nichts. Da das alles nur Routinen sind, die wir frueher oder später brauchen werden :smile:

MfG Alex

Project Server, Die Applikation!
Hallo Joe,

erstelle mal ein neues Project. Vergebe ihr einen eindeutigen Namen. Diesen Namen brauchen wir dann später :smile:
Als Start Object setzt du mal die Sub Main!
An Verweisen setzt du vorerst erst einmal folgende!

Visual Basic for Applikations
Visual Basic Runtime Objects and Procedures
Visual Basic Objects and Procedures
OLE Automation
Microsoft ActiveX Data Objects Recordsets Libary
Microsoft ADO Ext. 2.8 for DDL and Security
Microsoft ActiveX Data Objects Libary

Diesem Project fügst du vorerst (es kommt noch mehr) folgende Sachen hinzu!

2 Klassenmodule
4 Module

Klassenmodule

Name : WaitCursor
Name : cFindFile

Module

Name : Allgemein 
Name : Datenbank
Name : Registry
Name : Declarationen

So mehr mache vorerst, erstmal nichts :wink:

MfG Alex

Klassenmodul WaitCursor
Hallo Joe,

kopiere dir den folgenden Source einfach in das Klassenmodul WaitCursor.
Dieses dient dazu, den Mauszeiger auf die SandUhr zu stellen :wink:
Du musst dann aber die Sub Show als Default prozedure festlegen!
Das machst du indem du in das Klassenmodul wechselt. Dann klicke mal im Menu auf „Extras“ -> „Prozedure Attribute“.
In dem sich öffnenden Fenster sollte Unter Name eigentlich gleich Show stehen. Wenn nicht dann stelle ihn dort ein :smile:Danach klicke mal auf Optionen. Du siehst nun das das Fenster ein wenig erweitert wird!
Unter anderem findest du dort ein Punkt Prozedure - ID.
In der Combobox direkt darunter, sollte eigentlich „Keins“ ausgewaehlt sein. Ändere diesen Wert mal in Voreinstellung. Danach mit OK bestaetigen . Das Fenster sollte sich schliessen und die Sub Show ist als Default definiert. Das bedeutet, sowie du eine Instanz von WaitCursor aufrufst, reicht es wenn du den InstanzNamen dann schreibst. Er ruft dann automatisch die Sub Show auf :smile:

Achja, das einstellen kannst du erst, wenn du den Source reinkopiert hast :wink: Ist ja logisch :smile:

So nun aber der Source :smile:

Option Explicit

Private mPrevMousePointer As Long

Private Sub Class\_Initialize()
 mPrevMousePointer = vbDefault
End Sub

Public Sub Show()
 With Screen
 mPrevMousePointer = .MousePointer
 .MousePointer = vbHourglass
 End With
End Sub

Private Sub Class\_Terminate()
 Screen.MousePointer = mPrevMousePointer
End Sub

MfG Alex

Klassenmodul cFindFile
Hallo Joe,

anbei der Souce für das Klassenmodul. Diese Klasse, wird später mal die Suche nach den Dateien vornehmen :smile:

Du musst sie einfach nur kopieren :smile:
Ist aber nen bissl viel Source geworden :s

Option Explicit

Private Declare Function FindFirstFile Lib "kernel32" Alias "FindFirstFileA" (ByVal lpFileName As String, lpFindFileData As WIN32\_FIND\_DATA) As Long
Private Declare Function FindNextFile Lib "kernel32" Alias "FindNextFileA" (ByVal hFindFile As Long, lpFindFileData As WIN32\_FIND\_DATA) As Long
Private Declare Function FindClose Lib "kernel32" (ByVal hFindFile As Long) As Long
Private Declare Function FileTimeToSystemTime Lib "kernel32" (lpFileTime As FILETIME, lpSystemTime As SYSTEMTIME) As Long


Private Const INVALID\_HANDLE\_VALUE = -1
Private Const MAXDWORD = &HFFFF
Private Const MyUnhandledError = 9999

Private mvarsSearchpath As String
Private mvarsFileToFind As String
Private mvarsInclSubfolders As Boolean
Private mvarsFileFlag As FileFlag

Private Type SYSTEMTIME
 wYear As Integer
 wMonth As Integer
 wDayOfWeek As Integer
 wDay As Integer
 wHour As Integer
 wMinute As Integer
 wSecond As Integer
 wMilliseconds As Integer
End Type

Private Type FILETIME
 dwLowDateTime As Long
 dwHighDateTime As Long
End Type

Private Type WIN32\_FIND\_DATA
 dwFileAttributes As Long
 ftCreationTime As FILETIME
 ftLastAccessTime As FILETIME
 ftLastWriteTime As FILETIME
 nFileSizeHigh As Long
 nFileSizeLow As Long
 dwReserved0 As Long
 dwReserved1 As Long
 cFileName As String \* 260
 cAlternate As String \* 14
End Type


Public Event MatchFound(ByVal sFilename As String, ByVal sFilePath As String, ByVal sFiledate As Date, ByVal sFilesize As Long, ByVal sLastAccess As Date, ByVal sLastWrite As Date, ByVal sShortName As String)
Public Event StopSearch(Cancel As Boolean)
Public Event ChangeFolder(Folder As String)

Private Sub Class\_Initialize()
 sFileFlag = FILE\_ATTRIBUTE\_ALLTYPES
 sInclSubfolders = True
End Sub

Public Sub sStartSearch()
Dim lFileToFind As String, lSearchpath As String, Filename As String
Dim ShortName As String, DirName As String, DirNames() As String
Dim DirCount As Integer, nDir As Integer, Cont As Integer, I As Integer
Dim Filesize As Long, hSearch As Long
Dim Filedate As Date, LastAccess As Date, LastWrite As Date
Dim lInclSubfolders As Boolean, bCancel As Boolean
Dim sDate As SYSTEMTIME
Dim lFileFlag As FileFlag
Dim WFD As WIN32\_FIND\_DATA
On Error GoTo sStartSearchErr
 lFileToFind = sFileToFind
 lFileFlag = sFileFlag
 lSearchpath = sSearchpath
 lInclSubfolders = sInclSubfolders
 If Right(lSearchpath, 1) "\" Then lSearchpath = lSearchpath & "\"
 nDir = 0
 DirCount = 0
 ReDim DirNames(nDir)
 Cont = True
 bCancel = False
 hSearch = FindFirstFile(lSearchpath & "\*", WFD)
 RaiseEvent ChangeFolder(lSearchpath)
 If hSearch INVALID\_HANDLE\_VALUE Then
 Do While Cont
 DirName = Left$(WFD.cFileName, InStr(WFD.cFileName, vbNullChar) - 1)
 If (DirName ".") And (DirName "..") Then
 If (WFD.dwFileAttributes And vbDirectory) = FileFlag.FILE\_ATTRIBUTE\_DIRECTORY Then
 DirNames(nDir) = DirName
 DirCount = DirCount + 1
 nDir = nDir + 1
 ReDim Preserve DirNames(nDir)
 End If
 End If
 Cont = FindNextFile(hSearch, WFD)
 DoEvents
 Loop
 Cont = FindClose(hSearch)
 End If
 hSearch = FindFirstFile(lSearchpath & lFileToFind, WFD)
 Cont = True
 If hSearch INVALID\_HANDLE\_VALUE Then
 While Cont
 Filename = Left$(WFD.cFileName, InStr(WFD.cFileName, vbNullChar) - 1)
 If (Filename ".") And (Filename "..") Then
 If (WFD.dwFileAttributes Or lFileFlag) = lFileFlag Then
 Filesize = (WFD.nFileSizeHigh \* MAXDWORD) + WFD.nFileSizeLow
 FileTimeToSystemTime WFD.ftCreationTime, sDate
 With sDate
 Filedate = CDate(.wDay & "." & .wMonth & "." & .wYear & " " & .wHour & ":" & .wMinute & ":" & .wSecond)
 End With
 FileTimeToSystemTime WFD.ftLastAccessTime, sDate
 With sDate
 LastAccess = CDate(.wDay & "." & .wMonth & "." & .wYear & " " & .wHour & ":" & .wMinute & ":" & .wSecond)
 End With
 FileTimeToSystemTime WFD.ftLastWriteTime, sDate
 With sDate
 LastWrite = CDate(.wDay & "." & .wMonth & "." & .wYear & " " & .wHour & ":" & .wMinute & ":" & .wSecond)
 End With
 ShortName = Left$(WFD.cAlternate, InStr(WFD.cAlternate, vbNullChar) - 1)
 RaiseEvent MatchFound(Filename, lSearchpath, Filedate, Filesize, LastAccess, LastWrite, ShortName)
 End If
 End If
 Cont = FindNextFile(hSearch, WFD)
 DoEvents
 Wend
 Cont = FindClose(hSearch)
 End If
 If lInclSubfolders Then
 If nDir \> 0 Then
 For I = 0 To nDir - 1
 RaiseEvent StopSearch(bCancel)
 If bCancel Then Exit Sub
 sSearchpath = lSearchpath & DirNames(I)
 RaiseEvent ChangeFolder(sSearchpath)
 sStartSearch
 Next I
 End If
 End If
Exit Sub
sStartSearchErr:
 RaiseError MyUnhandledError, "cFindFile:sStartSearch Method", "Fehler bei sStartSearch"
End Sub

Public Property Let sFileFlag(ByVal vData As FileFlag)
On Error GoTo sFileFlagLetErr
 mvarsFileFlag = vData
 Exit Property
sFileFlagLetErr:
 RaiseError MyUnhandledError, "cFindFile:sFileFlag Property Let", "Fehler bei sFileFlag Property Let"
End Property

Public Property Get sFileFlag() As FileFlag
On Error GoTo sFileFlagGetErr
 sFileFlag = mvarsFileFlag
 Exit Property
sFileFlagGetErr:
 RaiseError MyUnhandledError, "cFindFile:sFileFlag Property Get", "Fehler bei sFileFlag Property Get"
End Property

Public Property Let sInclSubfolders(ByVal vData As Boolean)
On Error GoTo sInclSubfoldersLetErr
 mvarsInclSubfolders = vData
 Exit Property
sInclSubfoldersLetErr:
 RaiseError MyUnhandledError, "cFindFile:sInclSubfolders Property Let", "Fehler bei sInclSubfolders Property Let"
End Property

Public Property Get sInclSubfolders() As Boolean
On Error GoTo sInclSubfoldersGetErr
 sInclSubfolders = mvarsInclSubfolders
 Exit Property
sInclSubfoldersGetErr:
 RaiseError MyUnhandledError, "cFindFile:sInclSubfolders Property Get", "Fehler bei sInclSubfolders Property Get"
End Property

Public Property Let sFileToFind(ByVal vData As String)
On Error GoTo sFileToFindLetErr
 mvarsFileToFind = vData
 Exit Property
sFileToFindLetErr:
 RaiseError MyUnhandledError, "cFindFile:sFileToFind Property Let", "Fehler bei sFileToFind Property Let"
End Property

Public Property Get sFileToFind() As String
On Error GoTo sFileToFindGetErr
 sFileToFind = mvarsFileToFind
 Exit Property
sFileToFindGetErr:
 RaiseError MyUnhandledError, "cFindFile:sFileToFind Property Get", "Fehler bei sFileToFind Property Get"
End Property

Public Property Let sSearchpath(ByVal vData As String)
On Error GoTo sSearchpathLetErr
 mvarsSearchpath = vData
 Exit Property
sSearchpathLetErr:
 RaiseError MyUnhandledError, "cFindFile:sSearchpath Property Let", "Fehler bei sSearchpath Property Let"
End Property

Public Property Get sSearchpath() As String
On Error GoTo sSearchpathGetErr
 sSearchpath = mvarsSearchpath
 Exit Property
sSearchpathGetErr:
 RaiseError MyUnhandledError, "cFindFile:sSearchpath Property Get", "Fehler bei sSearchpath Property Get"
End Property

Private Sub RaiseError(ErrorNumber As Long, Source As String, strErrorText As String)
 Err.Raise ErrorNumber, Source, strErrorText
End Sub

MfG Alex

Modul Allgemein
Hallo Joe,

anbei das Modul Allgemein. Dieses Modul stellt die Sub Main zur Verfügung und desweiteren andere Functionen / Sub’s die wir mal benötigen werden :smile:
Das Modul wird aber sicherlich noch erweitert :wink:

Einfach den Source reinkopieren :smile:

 Option Explicit

Private Declare Function GetDiskFreeSpaceExA Lib "kernel32" (ByVal lpDirectoryName As String, lpFreeBytesAvailable As Currency, lpNumberOfBytes As Currency, lpNumberOfFreeBytes As Currency) As Long

Private Const MB As Long = 1024& \* 1024

Sub main()
 'In dieser Sub wird alles gestartet :smile:
End Sub

Public Function Diskfree(pfad As String, Grösse As Single) As Boolean
Dim Drive As String \* 2
Dim Size As Currency
 Drive = Left(pfad, 2)
 GetDiskFreeSpaceExA Drive, Size, 0, 0
 Size = (Size \* 10000) / MB 'Angabe in MB
 Diskfree = CBool(Size \>= Grösse)
End Function

Public Function FileExists(Path As String) As Boolean
On Error Resume Next
 Const NotFile = vbDirectory Or vbVolume
 FileExists = (GetAttr(Path) And NotFile) = 0
On Error GoTo 0
End Function

So sicherlich willst du mal sehen wie das mit der DB funktioniert :smile:

Wenn du das mal testen möchtest, so aendere mal die Sub Main, wiefolgt ab!

Sub Main
'Datenbank erstellen, mit dem PW "XYZ". 
' Das PW ist optional und kann weg gelassen werden :wink: 
' Sie wird auf dem Laufwerk c unter dem Namen test.Mdb angelegt.
' Bei Bedarf kannst du den Pfad aendern :wink:
 CreateDB "c:\Test.mdb", [JET4X = 5], "XYZ" 
'Wir öffnen mal die DB
 OpenDatabase "c:\test.mdb", "XYZ"
'Wir öffnen das recordset 
 OpenRecordsets
End Sub

MfG Alex

Modul Declaration
Hallo Joe,

in diesem Modul schreiben wir Nur declarationen rein, die wir von überall aus brauchen :wink:
Ist besser wegen der Übersichtlichkeit :smile:
Einfach den Source in das Modul kopieren :smile:

Option Explicit

'Variablen die wir später unter Einstellungen festlegen koennen!

'Die kommen noch :smile:

'Allgemeine Declarationen

Public Enum Jet\_EngineV 'Datenbank Format
 [JET10 = 1] = 1
 [JET11= 2] = 2
 [JET20 = 3] = 3
 [JET3X = 4] = 4
 [JET4X = 5] = 5
End Enum

Public Enum RegistryData 'Registry
 zBYTE = 1
 zDWORD = 2
 zSTRING = 3
End Enum

Public Enum FileFlag 'Welche Files sollen gesucht werden
 FILE\_ATTRIBUTE\_READONLY = &H1
 FILE\_ATTRIBUTE\_HIDDEN = &H2
 FILE\_ATTRIBUTE\_SYSTEM = &H4
 FILE\_ATTRIBUTE\_DIRECTORY = &H10
 FILE\_ATTRIBUTE\_ARCHIVE = &H20
 FILE\_ATTRIBUTE\_NORMAL = &H80
 FILE\_ATTRIBUTE\_TEMPORARY = &H100
 FILE\_ATTRIBUTE\_ALLTYPES = &H1B7
 FILE\_ATTRIBUTE\_ALLTYPES\_WITHOUT\_DIR = &H1A7
End Enum

Public Const HKEY\_CURRENT\_USER = &H80000001

Public Rs As New ADODB.Recordset 'Recordsets
Public Con As New ADODB.Connection 'Connection
Public CatADO As New ADOX.Catalog 'ADOX Catalog
Public DBISOpen As Boolean 'Ist eine Datenbank geöffnet
Public Regkey As String 'Wo in der Registry?

MfG Alex

Modul Datenbank
Hallo Joe,

hier stehen alle Routinen drinnen, die für den Zugriff auf die Datenbank von nöten sind. Ich habe aber vieles aus „alten“ Projecten von mir kopiert. Deswegen wird sicher auch die ein oder andere Function vorhanden sein, die wir nicht brauchen werden, wie zum Bsp. Ein Recordset lokal zu speichern und zu laden. Ist aber net weiter tragisch :smile:

Kopiere einfach den Source in das Modul

Option Explicit

'Datenbank erstellen (Ohne Tabellen und Felder)
Private Function CreateDatabase(sFile As String, Optional JetVersion As Jet\_EngineV = [JET4X = 5], Optional PWD As String = "") As Boolean
On Error GoTo ErrHandler
If Con.State = adStateOpen Then Con.Close
If FileExists(sFile) Then Kill (sFile)
Con = "Provider=Microsoft.Jet.OLEDB.4.0;"
Con = Con & "Data Source=" & sFile & ";"
Con = Con & "Jet OLEDB:Engine Type=" & JetVersion & ";"
If PWD "" Then Con = Con & "Jet OLEDB:smiley:atabase Password=" & PWD & ";"
CatADO.Create Con
CreateDatabase = True
Exit Function
ErrHandler:
 Call fAdoErr("fCreateDB")
End Function

'Datenbank Öffnen
Public Function OpenDatabase(sFile As String, Optional PWD As String = "") As Boolean
On Error GoTo ErrHandler
Dim AdoErr As ADODB.Error
If Con.State = adStateOpen Then Exit Function
If Not (FileExists(sFile)) Then Exit Function
With Con
 .CursorLocation = adUseClient
 .Mode = adModeShareDenyNone 'adModeReadWrite
 .Provider = "Microsoft.Jet.OLEDB.4.0"
 .Properties("Data Source") = sFile
 If Len(PWD) 0 Then .Properties("Jet OLEDB:smiley:atabase Password") = PWD
 .Open
 OpenDatabase = CBool(Con.State = adStateOpen)
End With
Exit Function
ErrHandler:
 Call fAdoErr("fConnectDB")
End Function

'Recordset öffnen
Public Function OpenRecordsets() As Boolean
Dim SQL As String
 SQL = "Select \* From FileData;": If Not (RunSql(SQL, Rs)) Then Exit Function
 DBISOpen = True
 OpenRecordsets = True
End Function

'Fehlerbehandlung
Private Sub fAdoErr(actSub As String) 'Fehlerbehandlung
Dim ErrNo() As Long
Dim ErrADO As ADODB.Error
Dim I As Integer
Dim strMsg As String
Dim bOnlyADO As Boolean
If Con.Errors.Count 0 Then
 ReDim ErrNo(Con.Errors.Count - 1)
 For Each ErrADO In Con.Errors
 strMsg = strMsg & "ADO-Error: " & ErrADO.Number & vbCrLf & "SQL-Error: " & ErrADO.SQLState & vbCrLf & ErrADO.Description
 ErrNo(I) = ErrADO.Number
 If Err.Number = ErrADO.Number Then bOnlyADO = True
 Next ErrADO
End If
If Not bOnlyADO Then
 strMsg = strMsg & vbCrLf & vbCrLf & "Fehler : " & Err.Number & vbCrLf & Err.Description
End If
MsgBox strMsg, vbExclamation, actSub
Con.Errors.Clear
Err.Clear
End Sub

'Recordset & Connection schliessen
Public Function CloseDB() As Boolean
On Error GoTo ErrHandler
If Rs.State = adStateOpen Then Rs.Close
If Con.State = adStateOpen Then Con.Close
Set Rs = Nothing
Set Con = Nothing
CloseDB = True
DBISOpen = False
Exit Function
ErrHandler:
 Call fAdoErr("fCloseConRs")
End Function

'Datenbank lokal speichern
Public Sub SaveLokal(sFile As String, Rs As ADODB.Recordset)
On Error GoTo ErrHandler
 If FileExists(sFile) Then Kill (sFile)
 If Rs.State = adStateClosed Then
 MsgBox "Es ist kein Datensatz geladen!", vbCritical
 Exit Sub
 End If
 Rs.Save sFile
 Exit Sub
ErrHandler:
 Call fAdoErr("fSaveLokal")
End Sub

'Daten Lokal laden
Public Sub LoadLokal(sFile As String, Rs As ADODB.Recordset)
On Error GoTo ErrHandler
 If Not (FileExists(sFile)) Then
 MsgBox "Lokale Daten wurden nicht gefunden!", vbCritical
 Exit Sub
 End If
 If Rs.State = adStateOpen Then Rs.Close
 If Rs.ActiveConnection Is Nothing Then Set Rs.ActiveConnection = Nothing
 Rs.Open sFile
 Exit Sub
ErrHandler:
 Call fAdoErr("fLoadLokal")
End Sub

'Tabelle anlegen
Private Function CreateTable(sName As String) As Boolean
Dim TblADO As New ADOX.Table
On Error GoTo ErrHandler
CatADO.ActiveConnection = Con
TblADO.Name = sName
CatADO.Tables.Append TblADO
ExitErr:
Set CatADO = Nothing
CreateTable = True
Exit Function
ErrHandler:
 Call fAdoErr("fCreateTableADOX")
End Function

'Feld anlegen
Private Function CreateField(TableName As String, ColumnName As String, ColumnType As ADODB.DataTypeEnum, Optional ColSize As Integer = 255, Optional AutoIncrement As Boolean = False, Optional Default As Variant = Empty, Optional AllowZeroLength As Boolean = True) As Boolean
On Error GoTo ErrHandler
Dim ColADO As New ADOX.Column
CatADO.ActiveConnection = Con
With ColADO
 Set .ParentCatalog = CatADO
 .Name = ColumnName
 .Type = ColumnType
 If .Type = adVarWChar Then .DefinedSize = ColSize
 If .Type = adInteger Then
 If AutoIncrement Then .Properties("AutoIncrement") = True
 End If
 If Not IsMissing(Default) Then .Properties("Default") = Default
 If AllowZeroLength Then .Properties("Jet OLEDB:Allow Zero Length") = True
End With
CatADO.Tables(TableName).Columns.Append ColADO
Set CatADO = Nothing
CreateField = True
Exit Function
ErrHandler:
 Call fAdoErr("fCrateField")
End Function

'Alle Tabellen wiedergeben
Public Function GetTable() As Variant
On Error GoTo ErrHandler
Dim sName() As String
Dim TBL As ADOX.Table
Dim C As Long
CatADO.ActiveConnection = Con
C = 0
For Each TBL In CatADO.Tables
 If TBL.Type "SYSTEM TABLE" Then
 If C = 0 Then
 ReDim Preserve sName(0)
 sName(0) = TBL.Name
 C = 1
 Else
 C = UBound(sName) + 1
 ReDim Preserve sName(C)
 sName(C) = TBL.Name
 End If
 End If
Next
GetTable = sName
Exit Function
ErrHandler:
 Call fAdoErr("fGetTable")
End Function

'SQL Abfrage
Public Function RunSql(Statement As String, Rs As ADODB.Recordset) As Boolean
On Error GoTo ErrHandler
 If Rs.State = adStateOpen Then Rs.Close
 Rs.Open Statement, Con, adOpenDynamic, adLockPessimistic
 RunSql = True
 Exit Function
ErrHandler:
 Call fAdoErr("fRunSql")
End Function

'Datenbank erstellen
Public Function CreateDB(sFile As String, Optional JetVersion As Jet\_EngineV = [JET4X = 5], Optional PWD As String = "") As Boolean
On Error GoTo ErrHandler
Dim cursor As New WaitCursor
 cursor
 If Not (Diskfree(sFile, 0.5)) Then '0.5 minimaler Speicherplatz! Den kannst du anpassen!
 MsgBox "Auf den Datenträger ist nicht genuegend Speicherplatz vorhanden, zum anlegen der Datenbank!" & vbNewLine & "Es werden mindstens 500 KByte Speicherplatz benötigt!", vbCritical
 Exit Function
 End If
 If Not (CreateDatabase(sFile, JetVersion, PWD)) Then Call DeleteDB(sFile)
 If Not (OpenDatabase(sFile, PWD)) Then Call DeleteDB(sFile)
 'Tabellen erstellen
 If Not (CreateTable("FileData")) Then Err.Raise 13
 'Felder erstellen
 If Not (CreateField("FileData", "ID", adInteger, , True, , True)) Then Err.Raise 13 'Einen Index zur Indifizierung
 If Not (CreateField("FileData", "File", adVarWChar, , , "", False)) Then Err.Raise 13
 If Not (CreateField("FileData", "Path", adVarWChar, , , "", False)) Then Err.Raise 13
 If Not (CreateField("FileData", "Size", adInteger, , False, , False)) Then Err.Raise 13
 If Not (CreateField("FileData", "Create", adDate, , , , False)) Then Err.Raise 13
 If Not (CreateField("FileData", "Change", adDate, , , , False)) Then Err.Raise 13
 CreateDB = True
 Exit Function
ErrHandler:
 Call DeleteDB(sFile)
End Function

'Datenbank löschen
Private Sub DeleteDB(sFile As String)
On Error Resume Next
If Rs.State = adStateOpen Then Rs.Close
If Con.State = adStateOpen Then Con.Close
On Error GoTo 0
 Set Rs = Nothing
 Set Con = Nothing
 If FileExists(sFile) Then Kill (sFile)
 On Error GoTo 0
End Sub

'Alle Felder aus der Tabelle zurueckliefern
Public Function GetFields(Tabelle As ADODB.Recordset) As Variant
Dim I As Integer
Dim vRet As Variant
 ReDim vRet(Tabelle.Fields.Count - 1)
 For I = 0 To Tabelle.Fields.Count - 1
 vRet(I) = Tabelle.Fields(I).Name
 Next I
 GetFields = vRet
 vRet = Empty
End Function

'Speichert die Daten in der DB!
Public Sub SaveDataInDB(Filename As String, Path As String, Size As Long, CreateDate As Date, ChangeDate As Date)
 If DBISOpen Then
 Rs.AddNew
 Rs.Fields("File").Value = Filename
 Rs.Fields("Path").Value = Path
 Rs.Fields("Size").Value = Size
 Rs.Fields("Create").Value = CreateDate
 Rs.Fields("Change").Value = ChangeDate
 Rs.Update
 End If
End Sub

Mfg Alex

Modul Registry
Hallo Joe,

in diesem Modul findest du die Functionen die zum Zugriff auf die registry dienen! Ich denke ja mal das wir gewisse Einstellungen auch speichern werden :wink:

Kopiere einfach den Source in das Modul :smile:

Option Explicit

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
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 RegDeleteValue Lib "advapi32.dll" Alias "RegDeleteValueA" (ByVal hKey As Long, ByVal lpValueName As String) As Long
Private Declare Function RegDeleteKey Lib "advapi32.dll" Alias "RegDeleteKeyA" (ByVal hKey As Long, ByVal lpSubKey As String) As Long

Private Const REG\_SZ = 1
Private Const REG\_BINARY = 3
Private Const REG\_DWORD = 4

Public Function SetValue(Key As String, Field As String, vData As Variant, Typ As RegistryData) As Boolean
On Error GoTo ErrHandler
 Dim tmp As String
 Dim tmp1 As Byte
 Dim tmp2 As Long
 Select Case Typ
 Case 1 'Byte
 tmp1 = CByte(vData)
 SetValue = StringSpeichernByte(HKEY\_CURRENT\_USER, Key, Field, CStr(tmp1))
 Case 2 'DWORD
 tmp2 = CLng(vData)
 SetValue = StringSpeichernLong(HKEY\_CURRENT\_USER, Key, Field, tmp2)
 Case 3 'STRING
 tmp = CStr(vData)
 SetValue = StringSpeichern(HKEY\_CURRENT\_USER, Key, Field, tmp)
 End Select
ErrHandler:
End Function

Private Function StringSpeichern(hKey As Long, sPath As String, sValue As String, iData As String) As Boolean
On Error GoTo ErrHandler
Dim vRet As Variant
 RegCreateKey hKey, sPath, vRet
 RegSetValueEx vRet, sValue, 0, REG\_SZ, ByVal iData, Len(iData)
 RegCloseKey vRet
 StringSpeichern = True
ErrHandler:
End Function

Private Function StringSpeichernByte(hKey As Long, sPath As String, sValue As String, iData As String) As Boolean
On Error GoTo ErrHandler
Dim vRet As Variant
 RegCreateKey hKey, sPath, vRet
 RegSetValueEx vRet, sValue, 0, REG\_BINARY, CByte(iData), 4
 RegCloseKey vRet
 StringSpeichernByte = True
ErrHandler:
End Function

Private Function StringSpeichernLong(hKey As Long, sPath As String, sValue As String, iData As Long) As Boolean
On Error GoTo ErrHandler
Dim vRet As Variant
Dim lResult As Long
 RegCreateKey hKey, sPath, vRet
 lResult = RegSetValueEx(vRet, sValue, 0, REG\_DWORD, iData, 4)
 RegCloseKey vRet
 StringSpeichernLong = True
ErrHandler:
End Function

Public Function WertLesen(hKey As Long, sPath As String, sValue As Variant, Default As Variant) As Boolean
On Error GoTo ErrHandler
Dim vRet As Variant
 RegOpenKey hKey, sPath, vRet
 sValue = fRegAbfrageWert(vRet, CStr(sValue))
 If IsEmpty(sValue) Then sValue = Default
 RegCloseKey vRet
 WertLesen = True
ErrHandler:
End Function

Private Function fRegAbfrageWert(ByVal hKey As Long, ByVal sValueName As String) As Variant
On Error GoTo ErrHandler
Dim sBuffer As String
Dim lRes As Long
Dim lTypeValue As Long
Dim lBufferSizeData As Long
Dim iData As Integer
Dim LongData As Long
 lRes = RegQueryValueEx(hKey, sValueName, 0, lTypeValue, ByVal 0, lBufferSizeData)
 If lRes = 0 Then
 If lTypeValue = REG\_SZ Then
 sBuffer = String(lBufferSizeData, Chr$(0))
 lRes = RegQueryValueEx(hKey, sValueName, 0, 0, ByVal sBuffer, lBufferSizeData)
 If lRes = 0 Then fRegAbfrageWert = Left$(sBuffer, InStr(1, sBuffer, Chr$(0)) - 1)
 ElseIf lTypeValue = REG\_BINARY Then
 lRes = RegQueryValueEx(hKey, sValueName, 0, 0, iData, lBufferSizeData)
 If lRes = 0 Then fRegAbfrageWert = iData
 ElseIf lTypeValue = REG\_DWORD Then
 lBufferSizeData = 4
 lRes = RegQueryValueEx(hKey, sValueName, 0&, REG\_DWORD, LongData, lBufferSizeData)
 If lRes = 0 Then fRegAbfrageWert = LongData
 End If
 End If
 Exit Function
ErrHandler:
 fRegAbfrageWert = ""
End Function

Public Function WerteLoeschen(sPath As String, sValue As String) As Boolean
On Error GoTo ErrHandler
Dim vRet As Variant
 RegCreateKey HKEY\_CURRENT\_USER, sPath, vRet
 RegDeleteValue vRet, sValue
 RegCloseKey vRet
 WerteLoeschen = True
ErrHandler:
End Function

Public Function DeleteAutoRun(sValueName As String) As Boolean
On Error GoTo ErrHandler
Dim hKey As Long
 RegOpenKey HKEY\_CURRENT\_USER, "software\microsoft\windows\currentversion\run", hKey
 RegDeleteValue hKey, sValueName
 RegCloseKey hKey
 DeleteAutoRun = True
ErrHandler:
End Function

Public Function DeleteAutoRunOnce(sValueName As String) As Boolean
On Error GoTo ErrHandler
Dim hKey As Long
 RegOpenKey HKEY\_CURRENT\_USER, "software\microsoft\windows\currentversion\runonce", hKey
 RegDeleteValue hKey, sValueName
 RegCloseKey hKey
 DeleteAutoRunOnce = True
ErrHandler:
End Function

Public Function SetAutoRun(sValueName As String, sValue As String) As Boolean
On Error GoTo ErrHandler
Dim hKey As Long
 RegOpenKey HKEY\_CURRENT\_USER, "software\microsoft\windows\currentversion\run", hKey
 RegSetValueEx hKey, sValueName, 0, REG\_SZ, ByVal sValue, Len(sValue)
 RegCloseKey hKey
 SetAutoRun = True
ErrHandler:
End Function

Public Function SetAutoRunOnce(sValueName As String, sValue As String) As Boolean
On Error GoTo ErrHandler
Dim hKey As Long
 RegOpenKey HKEY\_CURRENT\_USER, "software\microsoft\windows\currentversion\runonce", hKey
 RegSetValueEx hKey, sValueName, 0, REG\_SZ, ByVal sValue, Len(sValue)
 RegCloseKey hKey
 SetAutoRunOnce = True
ErrHandler:
End Function

Public Function DeleteKey(Key As String) As Boolean
On Error GoTo ErrHandler
Dim lReturn As Long
lReturn = RegDeleteKey(HKEY\_CURRENT\_USER, Key)
DeleteKey = CBool(lReturn = 0)
ErrHandler:
End Function

MfG Alex

Hi Alex,
Habe das Projekt soweit zusammen kopiert. Ich muss nur mal nachfragen wie du das mit dem Start Objekt meinst?
Mein erster Gedanke war die Main über

Private Sub Form_Load()
Main
End Sub

zu starten, aber das meinst du sicherlich nicht.

Als Start Object setzt du mal die Sub Main!

Hallo Joe,

Hallo Alex, ich schreibe hier mal zwischen die Zeilen :stuck_out_tongue:

Ich konzipiere es so. Das der Client je nach Einstellung und
Bedarf, bei sich auf dem Rechner einen Scan durchführt und
seine Daten ermittelt. Diese schickt er dann zum Server.

Ich habe gerade zum testen den Ordner mit der Rekuriven Suche die ich mal von VB-Net hatte gescannt und musste ca 1 Min für den Scanvorgang warten. Das ist nicht lange, aber mein Gedanke war das der Server weiss welche Daten auf dem Client liegen und anhand dieser Liste den Abgleich mit den Neuen Daten macht. DH. Beim der ersten Verbindung mit dem Server wird alles Kopiert oder verglichen und ein Index aller Datein auf dem Clienten X in der Datenbank auf dem Server geschrieben.
Nun macht der Server alle 3 Stunden einen vergleich der Netzlaufwerke mit seinem Index der Netzlaufwerke und gleicht die Daten bei Änderungen an. Danach vergleicht er nun den „Master“ index mit dem Index der Clienten und schreibt die diverenz in einen „Kopierauftrag“ in die Datenbank oder in ein Txt File. in diesem File steht nur der Pfad zu den Neuen Daten die der Client benötigt. Der Client ließt die Datei beim Verbinden,kopiert die files vom netzlaufwerk und schickt nach dem abgleich ein OK an den Server damit er diese Files in die Index Liste des Clienten aufnimmt. Somit spart man die Zeit der Datenanalyse.

ich hoffe du steigst da durch :stuck_out_tongue:

Aber nungut. Fangen wir mit dem Server an!
Ich mache hier mal mehrere Antworten auf. Im Titel zum Bsp.
Modul XYZ steht dann der Source zu dem Modul. Wenn du da
Fragen hast, dann antworte einfach auf das Thema immer :smile: So
sollten wir eine Übersicht behalten, denn es ist wie gesagt ne
menge Source. Sehen tust du vorerst nichts. Da das alles nur
Routinen sind, die wir frueher oder später brauchen werden :smile:

MfG Alex

Jo. ich bin echt beindruckt. Danke! Du hast Nachtschicht ? oder kommst du so spät von der arbeit ? ich werde mir mal angewöhnen morgens das FOrum zu lesen und abends länger wach zu bleiben.

bis später mfg jonny

Hallo Joe,

Hallo Alex, ich schreibe hier mal zwischen die Zeilen :stuck_out_tongue:

So soll es auch sein. Denn somit behalten wir den Ueberblick :wink:

Ich konzipiere es so. Das der Client je nach Einstellung und
Bedarf, bei sich auf dem Rechner einen Scan durchführt und
seine Daten ermittelt. Diese schickt er dann zum Server.

Ich habe gerade zum testen den Ordner mit der Rekuriven Suche
die ich mal von VB-Net hatte gescannt und musste ca 1 Min für
den Scanvorgang warten. Das ist nicht lange, aber mein Gedanke
war das der Server weiss welche Daten auf dem Client liegen
und anhand dieser Liste den Abgleich mit den Neuen Daten
macht. DH. Beim der ersten Verbindung mit dem Server wird
alles Kopiert oder verglichen und ein Index aller Datein auf
dem Clienten X in der Datenbank auf dem Server geschrieben.
Nun macht der Server alle 3 Stunden einen vergleich der
Netzlaufwerke mit seinem Index der Netzlaufwerke und gleicht
die Daten bei Änderungen an. Danach vergleicht er nun den
„Master“ index mit dem Index der Clienten und schreibt die
diverenz in einen „Kopierauftrag“ in die Datenbank oder in ein
Txt File. in diesem File steht nur der Pfad zu den Neuen Daten
die der Client benötigt. Der Client ließt die Datei beim
Verbinden,kopiert die files vom netzlaufwerk und schickt nach
dem abgleich ein OK an den Server damit er diese Files in die
Index Liste des Clienten aufnimmt. Somit spart man die Zeit
der Datenanalyse.

ich hoffe du steigst da durch :stuck_out_tongue:

Ich denke mal schon das ich das verstanden habe!
Aber fragen wir mal anders. Die IP vom Server ist die Bekannt?
Über welchen Port soll das arbeiten?

Aber nungut. Fangen wir mit dem Server an!
Ich mache hier mal mehrere Antworten auf. Im Titel zum Bsp.
Modul XYZ steht dann der Source zu dem Modul. Wenn du da
Fragen hast, dann antworte einfach auf das Thema immer :smile: So
sollten wir eine Übersicht behalten, denn es ist wie gesagt ne
menge Source. Sehen tust du vorerst nichts. Da das alles nur
Routinen sind, die wir frueher oder später brauchen werden :smile:

MfG Alex

Jo. ich bin echt beindruckt. Danke! Du hast Nachtschicht ?
oder kommst du so spät von der arbeit ? ich werde mir mal
angewöhnen morgens das FOrum zu lesen und abends länger wach
zu bleiben.

Sagen wir mal so. Ich bin in der Elektrobranche taetig aber derzeit arg viel Stress ( 12 Stunden Tag) und das 5 oder gar 6 Tage die Woche :s
Dazu kommt jetzt noch eine akurate erkältung :frowning: Deswegen lag ich die letzten beiden Tagen flach. Aber am WE werde ich mich ueber das Proggi weiter her machen :smile:

bis später mfg jonny

MfG Alex

Hallo Joe,

Habe das Projekt soweit zusammen kopiert. Ich muss nur mal
nachfragen wie du das mit dem Start Objekt meinst?
Mein erster Gedanke war die Main über

Nein, das ist falsch. Unter VB hast du rechter Hand, relativ weit oben den Project Mappen Explorer :s Sprich dort wo du alle Module, Forms etc. siehst!
Als allererster Eintrag, sollte dein Project stehen. In der Art
Server(Server.vbp).
Auf diesen Eintrag klicke mal mit rechts drauf und dann Eigenschaften:smile:
Unter dem Reiter Allgemein, welcher selektiert sein Sollte findest du unter anderem das Startobject,den Projecttyp, Projectname etc.
Dort stellst du als Startobject „Sub Main“ ein.

Das bedeutet. Dein Proggi sucht die Sub Main und startet dort! Wieso wir das machen, das wirst du noch sehen :smile: Man kann so zum Bsp. Einen Splash Screen laden und anzeigen, waehrend dessen die Daten geladen werden und dann zum Schluss zeigen wir nur noch die nötige Form an :wink:
Die Sub Main, findest du im Modul Allgemein. Es ist dir vielleicht aufgefallen, das dort noch kein Source Code drinnen steht, sondern nur die Declaration :wink:

MfG Alex

HI Alex,

Ich denke mal schon das ich das verstanden habe!
Aber fragen wir mal anders. Die IP vom Server ist die Bekannt?
Über welchen Port soll das arbeiten?

Also der Computername ist bekannt. Mit der IP muss ich mal schauen.
Den Port brauchen wir für die Verbindung zum clienten ?
Wollen wir den Kopierauftrag in ein extra Table in dir Datenbank schreiben oder einfach ein TXT File erstellen welches sich der client auf normalen Wege von einem Freigegebenen Ordner kopiert? allerdings gibt es so keine Möglichkeit ein OK oder Fertig zurück zu schicken.
Ich befürchte wenn ich einen Port Scanner laufen lasse bekomme ich ne Abmahnung.
hmpf

mfg joe

Hi Joe,

Also der Computername ist bekannt. Mit der IP muss ich mal
schauen.

die findet VB mir dem Namen.

Den Port brauchen wir für die Verbindung zum clienten ?

Client und Server sollen sich unterhalten.

Wollen wir den Kopierauftrag in ein extra Table in dir
Datenbank schreiben oder einfach ein TXT File erstellen
welches sich der client auf normalen Wege von einem
Freigegebenen Ordner kopiert?

Txt schon gar nicht und die Programme sollen auch nicht voneinander unabhängig auf etwas zugreifen. Das kann insatbil sein, da hat Alex recht.

Der Server wartet auf den Cient, der meldet sich am Server an und bekommt die Daten, die er braucht.

allerdings gibt es so keine
Möglichkeit ein OK oder Fertig zurück zu schicken.

Wenn die sich unterhalten schon. Stabiler geht es nicht.

Ich befürchte wenn ich einen Port Scanner laufen lasse bekomme
ich ne Abmahnung.

*gg* Keine Sorge, kein Portscan. :smile: Ein suberer Zugriff, der nur mit dem Clienten kommuniziert. Kein Sicherheitsrisiko.

Macht schön langsam, eventuell bau ich die Kommunikation, ich kann aber nichts versprechen weil … weißt Du ja. Das war schon mal fertig, für einen Muliuser-Chat im Netz, ein Schachprogramm für zwei Spieler über Netzwerk … Ist alles im Image und wartet auf die neue Festplatte.

Gruß Rainer

Hallo Joe,

Also der Computername ist bekannt. Mit der IP muss ich mal
schauen.

Hmm, ich muesste mich ma hinsetzen und etwas probieren. Vlt. bekomme ich anhand des Computernamen’s die IP heraus. Versprechen kann ich es aber nicht.

Den Port brauchen wir für die Verbindung zum clienten ?

Sagen wir es mal so. Stell dir folgendes vor.
Die IP Adresse ist die Anschrift. Der Port der Raum. Nun willst du etwas senden. Sprich du schreibst einen Brief. Schreibst darauf den Empfaenger. Den Brief gibst du den Postboten. Der kann dann zu der Anschrift fahren ( mit seinem Auto). Er Klingelt und ihm wird die Tür geöffnet. Der Postbote betritt das Haus! Nur wo soll er da hingehen? Ins Wohnzimmer, ins Schlafzimmer etc. Das muss er wissen!

Nun fragst du dich, was das damit zu tun hat. Stell dir einfach vor. Der Brief ist das Telegram, was du sendest. Auf dem postalischen Wege ( Also mit dem Auto vom Postboten) ist das Protokoll ( TCP/IP, UDP) und der Raum ist der Port.

Wie du nun erkennen kannst, sind folgende Dinge wichtig

IP, Port, Protokoll :wink:

Gängige Ports sind zum Bsp.

7 Echo Zurücksenden empfangener Daten
13 Daytime Übertragung von Datum und Uhrzeit
20 FTP-Data Dateitransfer (Datentransfer vom Server zum Client)
21 FTP Dateitransfer (Initiierung der Session und Senden der FTP-Steuerbefehle durch den Client)
22 SSH Secure Shell
23 Telnet Terminalemulation
25 SMTP E-Mail-Versand (siehe auch Port 465)
43 Whois Whois-Anfragen
53 DNS Auflösung von Domainnamen in IP-Adressen
67 BOOTPS BootStrap Protokoll server, auch genutzt von DHCP-Anfrage
68 BOOTPC BootStrap Protokoll client, auch genutzt von DHCP-Antwort
80 HTTP Webserver
110 POP3 Client-Zugriff für E-Mail-Server
119 NNTP Usenet (Newsgroups)
123 NTP Zeitsynchronisation zwischen Computern
143 IMAP Zugriff und Verwaltung von Mailboxen
443 HTTPS Verschlüsselte Webserver Übertragung, meist mit SSL- oder TLS-Verschlüsselung
445 Microsoft-DS Microsoft Directory Server, Windows Dateifreigabe
465 SMTPS gesicherter E-Mail-Versand
989 FTPS gesicherter Dateitransfer (File Transfer Protocol Secure)
990 FTPS Verbindungsbeginn und Steuerdaten (File Transfer Protocol Secure)
992 Telnet Secure Telnet Protokoll über TLS/SSL
993 IMAPS gesicherter Zugriff und Verwaltung von Mailboxen
994 IRCS IRC über TLS/SSL (Internet Relay Chat Secure)
995 POP3S gesicherter Client-Zugriff für E-Mail-Server
3306 MySQL Zugriff auf MySQL-Datenbanken
3389 RDP Windows Remotedesktopzugriff, Windows Terminal Services
5060 SIP IP-Telefonie
6667 IRC Chatserver

Ich hatte mir das so vorgestellt.
Wir lesen ein Flag aus der Registry und bekommen so mit ob das Proggi, das erste mal gestartet wurde.

Wenn ja:

Server - Anlegen der DB
Client - Scannen seiner Daten und senden an den Server, über ein TextFile

Wenn nein:

Client - Sendet Auftrag an Server zum Abgleich, danach aller 3 Stunden
oder wie es in den Einstellungen festgehalten ist :wink: Optional ist Manuell noch möglich :smile:

Server - Scannen seiner Daten, danach Scannen aller X Stunden, je nach
Einstellungen oder Manuell :smile:

Wollen wir den Kopierauftrag in ein extra Table in dir
Datenbank schreiben oder einfach ein TXT File erstellen
welches sich der client auf normalen Wege von einem
Freigegebenen Ordner kopiert? allerdings gibt es so keine
Möglichkeit ein OK oder Fertig zurück zu schicken.

Nach kurzem Überlegen, faellt mir ein, das die Tabellen Struktur der DB geaendert werden muss! Dort muss noch rein, welcher Client, die Daten besitzt! Aber das ändere ich dann noch im Modul um :wink: Ist kein grosser Aufwand.
Ich dachte dann an sowas in der Art wie.
Der Client möchte seine Daten aktualisiert haben! Sei es manuell oder Automatisch. Er sendet den Auftrag an den Server.
Der Server sucht die Daten heraus und schickt dem Clienten eine Liste mit den Daten. Der Client gibt sein OK.
Nun lädt der Client jedes File. Nach jedem erfolgreichen File, sendet er ein OK an den Server, das er es hat. Der Server aendert das dann in der DB. So ist sichergerstellt das nur Daten als syncronisiert eingetragen werden, die der Client auch wirklich hat! Auch ist auf diesem Wege ein vorzeitiges Abbrechen möglich :smile:

Hört sich vlt. ein wenig kompliziert oder nach nem haufen Aufwand / Transfer an, ist es aber nicht :wink:

Ich befürchte wenn ich einen Port Scanner laufen lasse bekomme
ich ne Abmahnung.
hmpf

Willst du das dann in der Firma einsetzen? Wir koennen es so machen das du den Port in den Einstellungen setzen kannst. Dann koenntest du ein wenig probieren und testen. Oder zur Not wenn dein Chef bescheid weiss und wir das Ding am laufen haben, das er dir dann einen Port für diese Zwecke freischaltet?

Aber mal was ganz anderes. Das haben wir noch garnicht angeschnitten.
Was für Info’s willst du denn auf dem Server alles sehen?

Was er gerade macht?
Mit welchen Clienten er verbunden ist?
Was für Anfragen reinkommen?
Was er sendet?
Den Transfer? (Die grösse)
Sollen die Daten verschluesselt uebertragen werden?
Soll das Proggi haben, sich in den NTA zu legen?
Was möchtest du alles in der Registry gespeichert haben?

Bisher ist nötig, folgendes zu speichern

Liegt der erste Start vor?
Startmodus ( Maximiert, Minimiert, NTA?)
IP
PORT

Soll die letzte Position des Fenster’s gespeichert werden?

MfG Alex

mfg joe

Hi Alex,

Hmm, ich muesste mich ma hinsetzen und etwas probieren. Vlt.
bekomme ich anhand des Computernamen’s die IP heraus.
Versprechen kann ich es aber nicht.

doch, 'GetIPbyName. *grummel* Wenn das hier doch kein Mac wäre …

Ich hatte mir das so vorgestellt.
Wir lesen ein Flag aus der Registry und bekommen so mit ob das
Proggi, das erste mal gestartet wurde.

Nein, nicht nötig. Der Server wartet einfach auf die Clients.
Das habe ich schon mal gebaut, war leicht.

Gruß Rainer

Hallo Rainer,

doch, 'GetIPbyName. *grummel* Wenn das hier doch kein Mac wäre

Ok, dann waere das ja simple :smile:

Ich hatte mir das so vorgestellt.
Wir lesen ein Flag aus der Registry und bekommen so mit ob das
Proggi, das erste mal gestartet wurde.

Nein, nicht nötig. Der Server wartet einfach auf die Clients.
Das habe ich schon mal gebaut, war leicht.

Richtig ist das das simple ist. Nur Rainer du musst bedenken das sich mehr wie nur 1 Client mit dem Server verbinden kann!

Aber das mit dem Flag aus der Registry
Sicher würde es auch ohne gehen. Wir koennten prüfen ob die DB vorhanden ist und wenn ja ob sie auch mit Daten gefuellt ist. Ist beides erfuellt, so lief der Server schon einmal.

Aber ich finde die Variante mit dem Flag in der Registry besser, da man so die Ueberprüfung sparen koennte. Man koennte beim ersten Start das Einstellungsfenster aufgehen lassen etc. Der Server muss die Daten (Auf dem Server)ja regelmaessig scannen und auf Aenderungen überwachen.

Spätestens beim Clienten brauchen wir dann die Info, da genau zu diesem Zeitpunkt alle Daten auf dem Clienten gescannt werden muessen und zum Server uebertragen, da dieser dann die Daten in die DB schreiben muss und einen Abgleich machen muss :wink:

MfG Alex

Hi Alex,

Richtig ist das das simple ist. Nur Rainer du musst bedenken
das sich mehr wie nur 1 Client mit dem Server verbinden kann!

wie beim Multiuser-Chat. No Problem, its easy. :smile:

Gruß Rainer

Hi Alex,

Ich hatte mir das so vorgestellt.
Wir lesen ein Flag aus der Registry und bekommen so mit ob das
Proggi, das erste mal gestartet wurde.

Wenn ja:

Server - Anlegen der DB
Client - Scannen seiner Daten und senden an den Server, über
ein TextFile

Klingt gut!!

Wenn nein:

Client - Sendet Auftrag an Server zum Abgleich, danach aller 3
Stunden

Wie gesagt die clienten sind Laptops die höchstens 6 mal pro Monat die daten mit dem Server abgleichen. Also ist hier ein einfacher Start button die Beste Lösung.

oder wie es in den Einstellungen festgehalten ist :wink: Optional
ist Manuell noch möglich :smile:

Server - Scannen seiner Daten, danach Scannen aller X Stunden,
je nach Einstellungen oder Manuell :smile:

Manuell klingt gut wobei 3 Stunden ein guter wert ist.
Es seih noch erwähnt das die Daten nicht alle im gleichen Verzeichniss liegen also müsste es die Möglichkeit geben bis zu 10 verschiedene Verzeichnisse festzulegen ://

Hört sich vlt. ein wenig kompliziert oder nach nem haufen
Aufwand / Transfer an, ist es aber nicht :wink:

^^

Willst du das dann in der Firma einsetzen? Wir koennen es so
machen das du den Port in den Einstellungen setzen kannst.
Dann koenntest du ein wenig probieren und testen. Oder zur Not
wenn dein Chef bescheid weiss und wir das Ding am laufen
haben, das er dir dann einen Port für diese Zwecke
freischaltet?

Es dürfte kein Problem sein das Alle im Büro also LAN oder über VPN läuft. Also müssen wir nicht über das Gateway richtung „Normales“ Internet. Somit sollten und alle standart Ports zur Verfügung stehen.

Aber mal was ganz anderes. Das haben wir noch garnicht
angeschnitten.
Was für Info’s willst du denn auf dem Server alles sehen?

Auf dem Server wäre eine einfache History schon Luxus. Also User X hat am so und so viele Daten kopiert.

Auf Dem Clienten wäre es nett zu sehen. Es gibt X neue Daten, Daten jetzte abgleichen.
Verschlüsselung brauchen wir nicht. Die VPN Verbindung ist schon kodiert.

Was er gerade macht?
Mit welchen Clienten er verbunden ist?
Was für Anfragen reinkommen?
Was er sendet?
Den Transfer? (Die grösse)
Sollen die Daten verschluesselt uebertragen werden?
Soll das Proggi haben, sich in den NTA zu legen?
Was möchtest du alles in der Registry gespeichert haben?

Der Server muss irgendwie die Clienten auseinander halten. Am besten wäre hier der Windows Benutzer name.

Bisher ist nötig, folgendes zu speichern

Liegt der erste Start vor?
Startmodus ( Maximiert, Minimiert, NTA?)
IP
PORT

Soll die letzte Position des Fenster’s gespeichert werden?

noe immer schön in die mitte des screens

muss fix weg, melde mich nachher nochma ausführlich
danke, mfg joe

OT @ Rainer Axel Joe
Hallöchen,
ich lese ja mit und es ist ja okay wenn ihr von Sachen sprecht die ich nicht kenne, aber für mein Selbstbewußtsein wäer es sehr gut ihr würdet nicht die Wortwahl „einfach“ sondern „relativ einfach“ benutzen.
Lieben Gruß
Reinhard, der wieder zu seinem Server äh Therapeuten eilen muß um als Client wahrgenommen zu werden :smile: