Benutzer mit den meisten Antworten
Zugriff auf existierendes COM-Objekt

Frage
-
Moin, moin!
Ich bin Anfänger in der Powershell-Programmierung und versuche, aus einem Powershell-Script auf eine laufende Microsoft-Access-Anwendung zuzugreifen.
Alle Beispiele, die sich auf das Powershell-comobject beziehen, legen aber mit New einen neuen Prozess an.
Das hier habe ich schon versucht, der Teil unter "MSACCESS.EXE ist aktiv" funktioniert aber nicht:
$proc = Get-Process | Where-Object {$_.ProcessName -eq "MSACCESS"}
if ($proc -imatch "MSACCESS")
{
Write-Host "MSACCESS.EXE ist aktiv"
$ShellApp = New-Object -ComObject Shell.Application
$Fenster = $ShellApp.Windows() | Where-Object { $_.LocationName -eq "Kabelüberwachung" }
$FensterDOM = $Fenster.Application
Write-Host "Ende!"
}
else
{
Write-Host 'MSACCESS.EXE ist nicht aktiv - wird gestartet'
$start = "`"C:\Program Files\Microsoft Office\Office14\msaccess.exe`" X:\MDB\Entw2010\Kabelueberwachung\Kabelueberwachung.accdb /cmd `"Cmd=K_S|IDX=11`""
& "C:\Program Files\Microsoft Office\Office14\msaccess.exe" X:\MDB\Entw2010\Kabelueberwachung\Kabelueberwachung.accdb /cmd "Cmd=K_S|IDX=11"
#$start = "Test"
Write-Host $start
#invoke-Command $start
}
read-host
Vielen Dank schon mal!
Antworten
-
Hallo Ingo!
Da Where-Object nicht das schnellste ist, sollte man in der PowerShell immer die Filter der Cmdlets benutzen bevor man zu Where-object greift!
Immer so weit rechts wie möglich Filtern!
Get-Process –Name 'MSAccess'
Ich hatte dir schon den Hinweis mit dem MainWindowTitle gegeben.
Anhand des MainWindowTitle des Prozesses, kannst du feststellen ob du den richtigen Prozess vor dir hast!
Prozesse einfach Killen ist nicht sehr elegant! Ebenso gehen ungesicherte Daten verloren!
Ich würde den User mit einem Hinweisfenster bitten Access zu schließen!
Dann kann er nochmal auf deinen Link klicken um die DB neu zu öffnen!
Alternativ kannst du Access Ordentlich schließen!
Die CloseMainWindow() Methode von dem Prozess Objekt, hat dieselbe Wirkung, als wenn der User die App von selbst schließt.
Es wird nach dem abspeichern gefragt!
Dies ist nicht so Brutal!
Get-Process –Name 'MSAccess' | ForEach-Object { If($_.MainWindowTitle –like "* Kabelueberwachung*") { # mach was hier # Poupfenster oder $_. CloseMainWindow() } }
Please click “Mark as Answer” if my post answers your question and click “Vote As Helpful” if my Post helps you.
Bitte markiere hilfreiche Beiträge von mir als “Als Hilfreich bewerten” und Beiträge die deine Frage ganz oder teilweise beantwortet haben als “Als Antwort markieren”.
My PowerShell Blog http://www.admin-source.info
[string](0..21|%{[char][int]([int]("{0:d}" -f 0x28)+('755964655967-86965747271757624-8796158066061').substring(($_*2),2))})-replace' '
German ? Come to German PowerShell Forum!- Als Antwort vorgeschlagen Peter Kriegel Mittwoch, 29. Mai 2013 14:08
- Als Antwort markiert Denniver ReiningMVP, Moderator Samstag, 1. Juni 2013 11:57
Alle Antworten
-
Moin moin Ingo,
was willst du denn mit Access machen?
Wenn du direkt das COM Objekt nutzen möchtest hilft dir sicherlich folgender Link weiter:
-
Hallo Ingo!
$ShellApp = New-Object -ComObject Shell.Application
$Fenster = $ShellApp.Windows()
Dies findet nur Explorer Fenster! Datei Explorer und Internet Explorer!
Auf eine offene Access Applikation zuzugreifen ist zwar nicht unmöglich aber doch sehr, sehr "speziell".
Dies nennt man Late-Binding (spätes binden) und ist über COM nicht üblich!
Wenn du eine Access Datenbank öffnen und steuern möchtest dann macht man das so:$Access = New-Object -ComObject Access.Application $Access.Visible = $True $Access.OpenCurrentDataBase('X:\MDB\Entw2010\Kabelueberwachung\Kabelueberwachung.accdb') # diese Befehl zeigt dir an was du mit dem Accesss Objekt machen kannst $Access | Get-Member
Du kannst mit den Get-Process Cmdlet überprüfen ob schon einen MSAccess läuft und wie der Titel der Applikation ist:
Get-Process -Name MSAccess | Select-Object MainWindowTitle
Die Windows API Funktion AccessibleObjectFromWindow kann aus einem geöffneten Fenster wieder ein COM Objekt generieren, aber da habe sich schon ganz große Programmierer die Ohren gebrochen!
http://msdn.microsoft.com/en-us/library/windows/desktop/dd317978%28v=vs.85%29.aspxVorhandene Applikationen Fern-zusteuern ist auch Sicherheitstechnisch ein Problem und nicht unbedingt gewollt! Deshalb wird das von Microsoft auch nicht gefördert!
Please click “Mark as Answer” if my post answers your question and click “Vote As Helpful” if my Post helps you.
Bitte markiere hilfreiche Beiträge von mir als “Als Hilfreich bewerten” und Beiträge die deine Frage ganz oder teilweise beantwortet haben als “Als Antwort markieren”.
My PowerShell Blog http://www.admin-source.info
[string](0..21|%{[char][int]([int]("{0:d}" -f 0x28)+('755964655967-86965747271757624-8796158066061').substring(($_*2),2))})-replace' '
German ? Come to German PowerShell Forum!
- Bearbeitet Peter Kriegel Mittwoch, 29. Mai 2013 05:58
- Als Antwort vorgeschlagen Peter Kriegel Mittwoch, 29. Mai 2013 14:08
-
>was willst du denn mit Access machen?
Der User klickt in einer (nicht veränderbaren) Anwendung auf einen Link. Dieser soll meine Access-Anwendung öffnen und einen bestimmten Datensatz anspringen. Das ist kein Problem, solange die Access-DB geschlossen ist. Wenn sie aber geöffnet ist, muss ich den Befehl, zum gewünschten Datensatz zu gehen, an die laufende Anwendung übergeben.
Das scheint aber wirklich schwierig zu sein. Der von Dir angebotene Link hilft da auch nicht weiter. Dort wird auch eine neue DB angelegt. Ich kann aber die gleiche DB auf einem Rechner nicht zweimal öffnen. Access macht das einfach nicht, es gibt auch keine Fehlermeldung.
Ingo
-
Hallo Peter!
Das funktioniert leider nicht. Wenn die DB schon geöffnet ist wird nur Access gestartet und die DB nicht noch einmal geöffnet.
Habe gerade eine andere Idee. Ich habe ja Zugriff auf den laufenden Access-Prozess
$proc = Get-Process | Where-Object {$_.ProcessName -eq "MSACCESS"}
Kann man den Prozess beenden? Das wäre zwar keine elegante Lösung, aber das könnte ja funktionieren. Das man damit versehentlich eine falsche Datenbank abschießt ist auf dem sehr speziellen Kundenrechner nicht zu befürchten.
Ingo
-
Hallo Ingo!
Da Where-Object nicht das schnellste ist, sollte man in der PowerShell immer die Filter der Cmdlets benutzen bevor man zu Where-object greift!
Immer so weit rechts wie möglich Filtern!
Get-Process –Name 'MSAccess'
Ich hatte dir schon den Hinweis mit dem MainWindowTitle gegeben.
Anhand des MainWindowTitle des Prozesses, kannst du feststellen ob du den richtigen Prozess vor dir hast!
Prozesse einfach Killen ist nicht sehr elegant! Ebenso gehen ungesicherte Daten verloren!
Ich würde den User mit einem Hinweisfenster bitten Access zu schließen!
Dann kann er nochmal auf deinen Link klicken um die DB neu zu öffnen!
Alternativ kannst du Access Ordentlich schließen!
Die CloseMainWindow() Methode von dem Prozess Objekt, hat dieselbe Wirkung, als wenn der User die App von selbst schließt.
Es wird nach dem abspeichern gefragt!
Dies ist nicht so Brutal!
Get-Process –Name 'MSAccess' | ForEach-Object { If($_.MainWindowTitle –like "* Kabelueberwachung*") { # mach was hier # Poupfenster oder $_. CloseMainWindow() } }
Please click “Mark as Answer” if my post answers your question and click “Vote As Helpful” if my Post helps you.
Bitte markiere hilfreiche Beiträge von mir als “Als Hilfreich bewerten” und Beiträge die deine Frage ganz oder teilweise beantwortet haben als “Als Antwort markieren”.
My PowerShell Blog http://www.admin-source.info
[string](0..21|%{[char][int]([int]("{0:d}" -f 0x28)+('755964655967-86965747271757624-8796158066061').substring(($_*2),2))})-replace' '
German ? Come to German PowerShell Forum!- Als Antwort vorgeschlagen Peter Kriegel Mittwoch, 29. Mai 2013 14:08
- Als Antwort markiert Denniver ReiningMVP, Moderator Samstag, 1. Juni 2013 11:57
-
Hallo Peter!
So funktioniert es, wenn auch nicht so, wie ich mir das mal vorgestellt hatte:
$proc = Get-Process | Where-Object {$_.ProcessName -eq "MSACCESS"}
if ($proc -imatch "MSACCESS")
{
$proc.CloseMainWindow()
}
& "C:\Program Files\Microsoft Office\Office14\msaccess.exe" X:\MDB\Entw2010\Kabelueberwachung\Kabelueberwachung.accdb /cmd "Cmd=K_S|IDX=11"
Da es in meinem Fall eher unwahrscheinlich ist, dass Access schon läuft, reicht das aus.
Vielen Dank noch Mal!
Ingo
-
Hallo Ingo,
wenn die Thematik geklärt ist, markiere bitte die entsprechenden Beiträge "als Antwort".
Viele Grüße,
AlexAlex Pitulice, MICROSOFT
Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip „IT-Pros helfen IT-Pros“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.