Na dann werte doch einfach die Texteinträge aus.
- neuer Eintrag (bekommst du ja über WM_SHELLCHANGENOTIFY) - enthält er die gesuchte Begriffe? - JA: Meldung
Beiträge von BugFix
-
-
und bei der Funktion _AgreeLicense weis ich nicht wo ich was eintragen soll
Wie gesagt, habe alles aus der Hüfte geschossen. Deshalb tritt auch mal ein Fehler auf.
An die Funktion musst du das Ergebnis der Updatezusammenstellung übergeben $oUpdates, dann sollte es auch funktionieren. -
besteht die Möglichkeit nur bestimmte Updates zu installieren ?
Verwende Listview mit Checkbox-Style, die Checkboxen verwendest du dann zur Auswahl der Updates.
Du musst dann nur beim Klick auf das Listview auswerten (in der Funktion _AgreeLicense
- die jetzige Auswertung zum Anzeigen/Bestätigen EULA
- zusätzlich: Wenn EULA abgelehnt wird darf Checkbox des Item nicht aktiviert werden/ bzw. muss wieder deaktiviert werden. Ebenfalls sollten Einträge, die User-Input erfordern (bei LICENSE-AGREE: 'requires user input') nicht aktivierbar sein. Wobei das in erster Linie ein optisches Gimmick ist. Das Update wird sowieso nur dann ausgeführt, wenn: "Checkbox aktiviert" und in License-Agree Eintrag " --" oder "agree".
Du kannst natürlich das ganze Handling verfeinern und Aktionen für Check/Uncheck berücksichtigen (z.B. wenn Uncheck, wird auch EULA zurückgesetzt), da kannst du dich austoben.
Dann musst du in der Funktion _CollectUpdates in der Schleife die Abfrage erweitern:
statt: If $sText = 'agree' Or $sText = ' --' Then $updatesToDownload.Add($searchResult.Updates.Item($i))
erweitert: If ($sText = 'agree' Or $sText = ' --') And _GUICtrlListView_GetItemChecked($hListview, $i) Then $updatesToDownload.Add($searchResult.Updates.Item($i)) -
Beim Klick auf Listview, ist es mit Checkbox wird dabei die Checkbox aktiviert und gleichzeitig (wenn erforderlich) Eula angezeigt und zum Bestätigen aufgefordert.
AutoIt
Alles anzeigenWhile 1 Switch GUIGetMsg() Case -3 Exit Case $idListview _AgreeLicense() Case ... Button 'Prüfen auf Updates' $oUpdates = _CheckAvailableUpdates() If @error Then MsgBox(0, 'Error', 'No updates available.') Else _ShowUpdatesInListview($idListview, $oUpdates) EndIf Case ... Button 'Updates durchführen' $oToUpdate = _CollectUpdates($oUpdates) If Not @error Then _RunUpdates($oToUpdate) EndSwitch WEnd -
Mal aus der Hüfte geschossen. Listview-UDF und WinAPI.au3 mußt du includieren und dann in deine GUI einbauen.
Wenn du das Listview mit Checkboxen gestaltest, kann der User damit auswählen. Mußt dann den Status der Checkboxen in der Funktion _RunUpdates abfragen und entsprechend installieren.AutoIt
Alles anzeigen; === In dein GUI einbauen ; === Listview erstellen, mit Spalte Lizenz-Akzeptieren Global $idListview = GuiCtrlCreateListView('UPDATE-TITLE|LICENSE-AGREE', ....) Global $hListview = GUICtrlGetHandle($idListview) ; Handle für UDF Global $updateSession, $oUpdates, $oToUpdate ; mach einen Button zum 'Prüfen auf Updates': $oUpdates = _CheckAvailableUpdates() If @error Then MsgBox(0, 'Error', 'No updates available.') Else _ShowUpdatesInListview($idListview, $oUpdates) EndIf ; ein Button für 'Updaten': $oToUpdate = _CollectUpdates($oUpdates) If Not @error Then _RunUpdates($oToUpdate) ; bei Event Listview: _AgreeLicense() Func _CheckAvailableUpdates() $updateSession = ObjCreate("Microsoft.Update.Session") $updateSession.ClientApplicationID = "MSDN Sample Script" Local $updateSearcher = $updateSession.CreateUpdateSearcher() ConsoleWrite('Searching for updates...' & @CRLF) Local $searchResult = $updateSearcher.Search("IsInstalled=0 and Type='Software' and IsHidden=0") ConsoleWrite('List of applicable items on the machine:' & @CRLF) Local $update For $i = 0 To $searchResult.Updates.Count-1 $update = $searchResult.Updates.Item($i) ConsoleWrite($i + 1 & "> " & $update.Title & @CRLF) Next If $searchResult.Updates.Count = 0 Then ConsoleWrite('There are no applicable updates.' & @CRLF) Return SetError(1,0,0) Else Return $searchResult EndIf EndFunc Func _ShowUpdatesInListview($idLV, $searchResult) Local $sItem, $update, $addThisUpdate For $i = 0 To $searchResult.Updates.Count-1 $update = $searchResult.Updates.Item($i) If $update.InstallationBehavior.CanRequestUserInput = True Then $sItem = $update.Title & '|requires user input' Else $sItem = $update.Title If $update.EulaAccepted = False Then $sItem &= '|click to agree' Else $sItem &= '| --' EndIf EndIf ; Item in Listview eintragen GUICtrlCreateListViewItem($sItem, $idLV) Next EndFunc Func _AgreeLicense($searchResult) Local $update, $aIndex = _GUICtrlListView_GetSelectedIndices($hListview, True) If $aIndex[0] = 0 Then Return For $i = 1 To $aIndex[0] If _GUICtrlListView_GetItemText($hListview, $aIndex[$i], 1) = 'click to agree' Then $update = $searchResult.Updates.Item($i-1) If MsgBox(36, 'License Agree', $update.EulaText) = 6 Then _GUICtrlListView_SetItemText($hListview, $aIndex[$i], 'agree', 1) _WinAPI_RedrawWindow($hListview) EndIf EndIf Next EndFunc Func _CollectUpdates($searchResult) Local $updatesToDownload = ObjCreate("Microsoft.Update.UpdateColl") Local $sText, $iCount = _GUICtrlListView_GetItemCount($hListview) If $iCount = 0 Then Return For $i = 0 To $iCount -1 $sText = _GUICtrlListView_GetItemText($hListview, $i, 1) If $sText = 'agree' Or $sText = ' --' Then $updatesToDownload.Add($searchResult.Updates.Item($i)) Next If $updatesToDownload.Count = 0 Then Return SetError(1,0,0) Else Return $updatesToDownload EndIf EndFunc Func _RunUpdates($updatesToDownload) Local $downloader = $updateSession.CreateUpdateDownloader() $downloader.Updates = $updatesToDownload $downloader.Download() Local $updatesToInstall = ObjCreate("Microsoft.Update.UpdateColl") Local $update, $rebootMayBeRequired = false ;~ ConsoleWrite("Successfully downloaded updates:" & @CRLF) For $i = 0 To $searchResult.Updates.Count-1 $update = $searchResult.Updates.Item($i) If $update.IsDownloaded = true Then ;~ ConsoleWrite($i + 1 & "> " & $update.Title & @CRLF) $updatesToInstall.Add($update) If $update.InstallationBehavior.RebootBehavior > 0 Then $rebootMayBeRequired = true EndIf Next If $updatesToInstall.Count = 0 Then Return MsgBox(48, 'Update', "No updates were successfully downloaded.") If $rebootMayBeRequired = true Then MsgBox(64,"Reboot", "Minimum one update requires a reboot.") If MsgBox(262180,"Install","Would you like to install updates now?") = 6 Then ; 'Ja' ;~ ConsoleWrite("Installing updates..." & @CRLF) Local $installer = $updateSession.CreateUpdateInstaller() $installer.Updates = $updatesToInstall $installationResult = $installer.Install() ; Output results of install ---> würde ich in ein Log schreiben ConsoleWrite("Installation Result: " & $installationResult.ResultCode & @CRLF) ConsoleWrite("Reboot Required: " & $installationResult.RebootRequired & @CRLF) ConsoleWrite("Listing of updates installed and individual installation results:" & @CRLF) For $i = 0 to $updatesToInstall.Count - 1 ConsoleWrite($i + 1 & "> " & $updatesToInstall.Item($i).Title & ": " & $installationResult.GetUpdateResult($i).ResultCode & @CRLF) Next EndIf EndFunc -
Habs mal portiert, inwiefern es funktioniert musst du testen.
AutoIt
Alles anzeigen$updateSession = ObjCreate("Microsoft.Update.Session") $updateSession.ClientApplicationID = "MSDN Sample Script" $updateSearcher = $updateSession.CreateUpdateSearcher() ConsoleWrite('Searching for updates...' & @CRLF) $searchResult = $updateSearcher.Search("IsInstalled=0 and Type='Software' and IsHidden=0") ConsoleWrite('List of applicable items on the machine:' & @CRLF) For $i = 0 To $searchResult.Updates.Count-1 $update = $searchResult.Updates.Item($i) ConsoleWrite($i + 1 & "> " & $update.Title & @CRLF) Next If $searchResult.Updates.Count = 0 Then Exit ConsoleWrite('There are no applicable updates.' & @CRLF) ConsoleWrite('Creating collection of updates to download:' & @CRLF) $updatesToDownload = ObjCreate("Microsoft.Update.UpdateColl") For $i = 0 To $searchResult.Updates.Count-1 $update = $searchResult.Updates.Item($i) $addThisUpdate = False If $update.InstallationBehavior.CanRequestUserInput = True Then ConsoleWrite($i + 1 & "> skipping: " & $update.Title & " because it requires user input" & @CRLF) Else If $update.EulaAccepted = False Then ConsoleWrite($i + 1 & "> note: " & $update.Title & " has a license agreement that must be accepted:" & @CRLF) ConsoleWrite($update.EulaText & @CRLF) If MsgBox(262180,"License","Do you accept this license agreement?") = 6 Then ; 'Ja' $update.AcceptEula() $addThisUpdate = true Else ConsoleWrite($i + 1 & "> skipping: " & $update.Title & " because the license agreement was declined" & @CRLF) EndIf Else $addThisUpdate = true EndIf EndIf If $addThisUpdate = true Then ConsoleWrite($i + 1 & "> adding: " & $update.Title & @CRLF) $updatesToDownload.Add($update) EndIf Next If $updatesToDownload.Count = 0 Then Exit ConsoleWrite("All applicable updates were skipped." & @CRLF) ConsoleWrite("Downloading updates..." & @CRLF) $downloader = $updateSession.CreateUpdateDownloader() $downloader.Updates = $updatesToDownload $downloader.Download() $updatesToInstall = ObjCreate("Microsoft.Update.UpdateColl") $rebootMayBeRequired = false ConsoleWrite("Successfully downloaded updates:" & @CRLF) For $i = 0 To $searchResult.Updates.Count-1 $update = $searchResult.Updates.Item($i) If $update.IsDownloaded = true Then ConsoleWrite($i + 1 & "> " & $update.Title & @CRLF) $updatesToInstall.Add($update) If $update.InstallationBehavior.RebootBehavior > 0 Then $rebootMayBeRequired = true EndIf Next If $updatesToInstall.Count = 0 Then Exit ConsoleWrite("No updates were successfully downloaded." & @CRLF) If $rebootMayBeRequired = true Then ConsoleWrite("These updates may require a reboot." & @CRLF) If MsgBox(262180,"Install","Would you like to install updates now?") = 6 Then ; 'Ja' ConsoleWrite("Installing updates..." & @CRLF) $installer = $updateSession.CreateUpdateInstaller() $installer.Updates = $updatesToInstall $installationResult = $installer.Install() ; Output results of install ConsoleWrite("Installation Result: " & $installationResult.ResultCode & @CRLF) ConsoleWrite("Reboot Required: " & $installationResult.RebootRequired & @CRLF) ConsoleWrite("Listing of updates installed and individual installation results:" & @CRLF) For $i = 0 to $updatesToInstall.Count - 1 ConsoleWrite($i + 1 & "> " & $updatesToInstall.Item($i).Title & ": " & $installationResult.GetUpdateResult($i).ResultCode & @CRLF) Next EndIf -
aber ist das nicht genau das was du willst:
Nicht wirklich. Das erfordert ein Booten im abgesicherten Modus. Da bin ich echt schneller, wenn ich mich per Hand durch die manuelle Aktualisierung klicke.
Wenn ein automatisierter Vorgang mehr Zeit benötigt als ein manueller, sollte man dessen Sinnhaftigkeit infrage stellen. -
Ich hatte die Frage schon direkt im Comodo-Forum gepostet, aber da kam noch keine Reaktion. Evtl. hat ja von euch jemand das Thema schon mal auf dem Schirm gehabt.
-
Zu meinem großen Erstaunen stellte ich fest, dass der Prozess nicht geschlossen wird. Bei der Fehleranalyse fiel mir auf, dass PID, ermittelt durch Run(), und die im Taskmgr ausgewiesene PID nicht identisch sind.
Das liegt daran, dass der Prozeß die "explorer.exe" ist. Das ist ein Windows-systemprozeß, der auch immer läuft. Du öffnest nur eine weitere Instanz dieses Prozesses. Mit ProcessList("explorer.exe") bekommst du ein Array mit allen PID aller Instanzen.
Für "normale" Prozesse findest du in der Regel nur eine PID.
-
Hast du die Möglichkeit mit einem Gaslötkolben zu arbeiten? Das erleichtert punktgenaues Verschmelzen der Lötenden.
Ich habe mir meine Löttinktur immer selber erstellt (Kolophonium in Spiritus aufgelöst). Damit hatte ich immer einen besseren Verlauf als mit den industriellen Mittelchen und Brückenbildung war minimiert. Auch Lötspitzen erstelle ich mir meist selbst - gerade, wenn ich Leistungen < 10W brauche. Massiver Cu-Draht wird in die entsprechende Spitzenform geschmiedet (mit einem kleinen Hämmerchen und sanften Schlägen dengeln). Kupfer verhält sich entgegengesetzt zu Eisen beim Schmieden. Will man es hart bekommen, muss es kalt geschmiedet werden. Durch Erhitzen wird die Spitze wieder weich. Man muss also ab und an nachschmieden.Vorrichtungsentwicklung/-bau ist in der Industrie kostenintensiv und zeitaufwändig. Insofern trifft dich das ebenso. Eventuell kannst du auch zwei Aluminiumbleche an den Enden einsägen (je Ader ein Schnitt), dann 90° abwinkeln, wie ein senkrecht stehender Kamm, und dann die Kabel gegenüber dort einlegen und verlöten. Nur für die letzte Lötstelle musst du dann per Hand umbiegen.
-
Ich weiß nicht, was in der *.zip alles dabei war - aber die *.au3 habe ich.
-
aber wie holst du die Rechner denn wieder hoch?
Das muß nicht automatisch gehen. Ist der Ausfall während der Arbeitszeit, wird es eh durch die Benutzer dann wieder gestartet. Ist der Ausfall nachts, spielt es auch keine große Rolle. Schlimmstenfalls wird ein Sicherungs-Job verpasst.
-
Bist du dir sicher, dass es da bei deiner USV keine Möglichkeit gibt?
Meine USV bietet keine Möglichkeit für den Einbau einer Netzwerkmanagementkarte.
Aber ich habe gerade überlegt, vielleicht kann ich auf dem PC der mit der USV verbunden ist, die Shutdown-Message verarbeiten und über Netzwerk die anderen PC herunterfahren. Mal probieren ob und wie das geht. -
Hallo,
ich überlege mir eine "Zentrale" zu basteln, die mir die Rechner bei Spannungsausfall herunterfährt. Die Soft- und Hardware der USV kann nur einen PC herunterfahren. Bei mir hängen aber mehrere dran.
Meine Überlegung:
(völlig unabhängig von der USV-Software)
- ein Pi/Uno (oder was auch immer) überwacht die Netz-Spannung
- bei Spannungsausfall > x Minuten wird an die PC ein Shutdown-Impuls geschickt (RS232?, USB? oder noch besser UDP/TCP?)
- Launcherskript auf den PC fährt diese bei Impuls herunterWas für ein Gerät wäre da empfehlenswert, was braucht man alles an Hardware, gibt es da Kommunikationsbeispiele?
Ich habe in dieser Richtung totale Glatze - also bitte schön detailliert erklären.

Eine Lösung unter Nutzung des Netzwerkes würde mir am meisten zusagen. Dann könnte ich alle PC im Netz mit einer Kurzzeit-USV ausstatten (5 min Pufferzeit reicht da völlig, die Teile gibt es für wenig Geld) und habe dann auch die User-PC bei Netzausfall geschützt. Leider kommt das im Industriegebiet relativ häufig vor (3-4 mal/Jahr). Privat dagegen kann ich mich die letzten 10 Jahre an keinen Stromausfall erinnern.
Danke schon mal für eure Ideen.
-
Hier ein einfaches Bsp. mit Inputs:
AutoIt
Alles anzeigenGlobal $GUI, $aInput[2] = [1], $btAdd $GUI = GUICreate('Test', 400, 50) $aInput[1] = GUICtrlCreateInput('', 10, 10, 300, 21) GUICtrlSetResizing(-1, 802) ; $GUI_DOCKALL $btAdd = GUICtrlCreateButton('Add Input', 320, 10, 70, 21) GUICtrlSetResizing(-1, 802) ; $GUI_DOCKALL GUISetState() While 1 Switch GUIGetMsg() Case -3 Exit Case $btAdd _NewCtrl() EndSwitch WEnd Func _NewCtrl() Local $iDiff = 31 ; == Abstand + Höhe ==> 10 + 21 Local Static $iY = 10 ; == Startwert vom ersten Ctrl $iY += $iDiff $aInput[0] += 1 ReDim $aInput[$aInput[0]+1] Local $aWin = WinGetPos($GUI) WinMove($GUI, '', $aWin[0], $aWin[1], $aWin[2], $aWin[3] + 31) $aInput[$aInput[0]] = GUICtrlCreateInput('', 10, $iY, 300, 21) GUICtrlSetResizing(-1, 802) ; $GUI_DOCKALL EndFunc -
Für kleinere Installationen verwende ich nicht extra ein Installationsskript, sondern nutze die Anwendung selbst dafür. Im Allgemeinen erstellt man ja im selben Ordner, indem die Installation gestartet wird, einen Anwendungsordner. Anschließend soll die aktuell laufende Anwendung aber sich in diesem Anwendungsordner befinden und dort ggf. dann alle weiteren erforderlichen Installationen (INI etc.) ausführen, bzw. ganz normal von dort gestartet werden. Die ursprünglich gestartete (Installations)Datei wird dann nicht mehr benötigt und gelöscht.
Es handelt sich hier nicht um eine _SelfDelete - Variante, sondern eher um ein: SelfCopy-CallCopy-DeleteCaller
Vielleicht habt ihr ja für diese Variante Verwendung.AutoIt
Alles anzeigen; ======================================================================== INSTALLATIONSORDNER ===== ; dieser Ordner wird als Unterordner im aktuellen Pfad erstellt und das Skript dorthin kopiert Global $sFolderInstall = '__Mein_Installationsordner__' ; ================================================================================================== ; ======================================================================== PRÜFT AUF PARAMETER ===== ; wenn Parameter: das kopierte Skript wird im neuen Ordner gestartet und das Original gelöscht _CheckCmdLine() ; ================================================================================================== ; ======================================================================== HAUPTSKRIPT ============= MsgBox(0, 'Skript-Kopie', 'Ich bin gestartet') ; ================================================================================================== #Region - functions ; ================================================================================================== Func _CheckCmdLine() If $CmdLine[0] Then Local $aCmd = StringRegExp($CmdLineRaw, "'(\w+)=([^']+)", 3) Local $iPID, $sPathCaller For $i = 0 To UBound($aCmd) -2 Step 2 Switch $aCmd[$i] Case 'pid' $iPID = $aCmd[$i+1] Case 'caller' $sPathCaller = $aCmd[$i+1] EndSwitch Next ; Aufruferskript beenden, wenn es noch laufen sollte If ProcessExists($iPID) Then ProcessWaitClose($iPID) ; Aufruferskript löschen FileDelete($sPathCaller) Else _Check2Move($sFolderInstall) EndIf EndFunc ;==>_CheckCmdLine Func _Check2Move($sFolderTarget) ; $sFolderTarget = Ordner in dem das Programm sein sollte ; Ordner in dem das Programm ist Local $sFolderCurrent = _GetFullPathNameDetail('.', 'folder') ; Ordnernamen vergleichen --> wenn ungleich: Zielordner als Unterordner des aktuellen Ordners erstellen, ; Skript dorthin kopieren, starten und das aufrufende Skript beenden und löschen If $sFolderCurrent <> $sFolderTarget Then Local $sFullTarget = _GetFullPathNameDetail('.') & '\' & $sFolderTarget ; Ordner erstellen If Not FileExists($sFullTarget) Then DirCreate($sFullTarget) ; Skript kopieren Local $sExe = StringTrimLeft(@ScriptFullPath, StringInStr(@ScriptFullPath, '\', 0, -1)) FileCopy(@ScriptFullPath, $sFullTarget & '\' & $sExe) Local $iPID = (ProcessList($sExe))[1][1] ; kopiertes Skript starten (eigene PID,Pfad übergeben) Local $sParam = StringFormat(" 'pid=%s' 'caller=%s'", $iPID, @ScriptFullPath) ShellExecute($sFullTarget & '\' & $sExe, $sParam) ; Skript beenden Exit EndIf EndFunc ;==>_Check2Move Func _GetFullPathNameDetail($_sFilePath, $_sSelect='full') Local $aRet = DllCall('kernel32.dll', 'dword', 'GetFullPathNameW', 'wstr', $_sFilePath, 'dword', 4096, 'wstr', '', 'ptr', 0) If @error Or Not $aRet[0] Then Return SetError(@error, @extended, '') Switch $_sSelect Case 'full' Return $aRet[3] Case 'drive' Return StringLeft($aRet[3], 2) Case 'folder' If StringLen($aRet[3]) > 3 Then Return StringTrimLeft($aRet[3], StringInStr($aRet[3], '\', 0, -1)) Else Return '' EndIf EndSwitch EndFunc ;==>_GetFullPathNameDetail ; ================================================================================================== #endregion -
Bitte (ist aber nicht 3D - sondern 2D mit 3 Spalten
) :AutoIt
Alles anzeigen$sText = 'class="adress">Rathausplatz 5<br/>90403 Nürnberg<br/><a href=" ' & @CRLF & _ 'Kontakt</h3><p class="adress">Äußere Bayreuther Str. 121<br/>90409 Nürnberg<br/><a href="' & @CRLF & _ '</span></p><h3>Kontakt</h3><p class="adress">Wallensteinstraße 28<br/>90439 Nürnberg<br/><a href="' & @CRLF & _ '</span></p><h3>Kontakt</h3><p class="adress">Glogauer Str. 30 - 38<br/>90473 Nürnberg<br/><a href="' $sPatt = '(?s)class="adress">([^<]+)<br/>(\d{5})\s([^<]+)' $aMatch = StringRegExp($sText, $sPatt, 4) Local $aResult[UBound($aMatch)][3] For $i = 0 To UBound($aMatch) -1 $aResult[$i][0] = ($aMatch[$i])[1] $aResult[$i][1] = ($aMatch[$i])[2] $aResult[$i][2] = ($aMatch[$i])[3] Next _ArrayDisplay($aResult) -
Ich möchte das ein timer die Zeit hochzählt bis ich oft genug auf ein Knopf gedrückt habe.
Außerdem das angezeigt wird wie oft ich den Knopf bereits gedrückt habe.Ich verstehe nur Bahnhof...
Stell bitte ein zumindest rudimentär funktionsfähiges Skript ein, das erklärt, was du vorhast. Aus deiner Beschreibung wird das nicht ersichtlich.
Und Sleep unterbricht dein Programm, ist also für einen Timer ungeeignet, dazu gibt es TimerInit/TimerDiff.
Eine Schleife innerhalb einer Funktion ist nur dann sinnvoll, wenn dort eine definierte Anzahl von Ereignissen abgearbeitet wird. Da in deiner Schleife aber nichts passiert ausser: <Programm Stop> - <Zähler hoch> - <Programm Stop> - <Zähler hoch> ... kannst du auch keine anderen Ereignisse berücksichtigen. -
Achso: Wenn $type = 1 ist, wird nicht negiert, wenn $type = 0 ist, dann wird negiert.
Das würde ich eigentlich genau entgegengesetzt ausführen, ist schlüssiger: '0'-kein NOT vorhanden, '1'-NOT vorhanden.
-