Приложения Windows

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 599
277
#1
много раз здесь поднималась тема - а вот мине нада открыть вложенный файл...
возможный ответ - ф-ция Shell
НО (лучи ненависти и освежение рта матерными выражениями), есть ряд особенностей:
-пути и русский язык (это не удивительно и для винды нормально)
-получение приложения открывшего файл (а вот это без извратов не получить)

пути (опять мат), подобрал комбинацию:
-палочки д.б. попендикулярно обратный слэш
-запуск д.б. вложенным - ибо cmd.exe чудит
выглядит все это так:
Код:
	fname=Replace(fname,{/},{\})'Windows specific
...............................
Dim res, run As String
run={cmd.exe /c "start } &fname &{"}
Print {Shell calling...}, run
res=Shell(run)
именно start, вложенный в cmd, иначе длинный путь, с русскими символами, не исполница
часть вторая развесёлая:
Код:
Sub CloseByFileName(fname As String)
On Error Goto ErrH
Dim req As String, ext As String
ext={.} & Strrightback(fname, {.})
req={Select * From Win32_Process Where CommandLine Like '%} & ext &{%'}
Print {WMI request:} &req

Dim objWMIService, strComputer As String
strComputer = "."	
Set objWMIService = GetObject( _
"winmgmts:\\" & strComputer & "\root\CIMV2")
Dim objs
Set objs = objWMIService.ExecQuery(req,,48)
If Not objs Is Nothing Then
Forall obj In objs
'			Print {*****************}
'			Print obj.CommandLine
If obj.CommandLine Like {*} &fname &{*} Then obj.Terminate
End Forall
Else
Print {Application has Not found}
End If
Quit:
Exit Sub
ErrH:
RaiseError
Resume Quit
End Sub
почему, вы спросите мя, не сразу в квери вкрячить имя файла, а я отвечу потамучта гладиолус не будет искать сцуко (у меня не искало, ненавижу эту ОС :( ) с русским языком (а возможно и длинным названием)
ну собсно все - так мона и хэндлы приложений получать
более вменяемого способа (с минимальными усилиями) я не нашёл (уж простите)
сцыкли для втупления:
http://www.codeproject.com/Articles/46390/...uage-by-Example
http://msdn.microsoft.com/en-us/library/wi...v=vs.85%29.aspx
http://scriptbox.toll.at/print.php?showcon...ile%20Query.vbs
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 599
277
#2
как это все применять - во вступлении первого поста описано, расшифрую :)
допустим сформировали файл/ы и приложили их к доку (или пока еще не приложили). Предполагается формирование отчетов, форм, договоров программными способами. Далее необходимо (в некий момент работы приложения Нотус) показать результат "труда". Можно самому искать запускающее эти файлы приложение или прописывать его жестко, но более универсальным способом - будет запуск ср-вами ОС
Запуск средствами ОС:
-Windows - cmd.exe -c "..., с оговорками выше
-Mac OS X - bash -c "open -a ..." (ЕМНИП - откроет и файл, с пом. ассоциированного приложения)
-Linux - bash -c "gvfs-open ..."

клиентов под др. ОС не знаю и их сами знаю плохо или вовсе не знаю (остались: solaris, AIX, z/OS )

ну собсно эти строки и подставляются ф-ции Shell({...})
не забываем что слэши (разделители пути в Файловой Системе) - наклонены вправо (/) как привычно их видеть в интернете!, исключением является ОС Windows (из тех - где есть Notes) - будут бэкслэш, как и следует из названия - наклонены в обратную сторону!
Это важно не забывать - когда команды отдаются на исполнение ОС, т.к. внутри Нотес это имеет меньшее значение.
Нотес транслирует пути в ОС и потому, многие команды понимают файловые пути как с прямым, так и с обратным слэшем.

Неудобство обратного слэша проявляется:
- в java - там он является символом экранирования
- в регулярных выражениях - аналогично
из чего - я предпочитаю прямые слэши (интернет - опятьже :) )

вопрос/ответ:
- зачем тогда искать приложение, открывшее файл? :) - чтобы его "убить"!
- зачем убивать? - нек. приложения имеют "вредную" особенность - лочить файл на перезапись (типично для Windows)
- а что мне с того - что залочен файл? - дык не все закрывают приложение после просмотра ;) , а повторно сгенерить с тем же путем не получится
- зачем мне тот же путь? - чтобы не плодить файлы в ФС (там и так - добра навалом), а повторно сгенерить бывает нужно
- почему не "убивать" файл? - после запуска теряем контроль над приложением, да и убить лоченный файл - тоже не получится
 

afest

Well-known member
16.06.2009
78
0
#3
ну скрипты кнеш хорошие... но я обычно сразу скриптом в фоне открываю OLE-объект (обычно Excel) и туда передаю данные, потом док открывается...
бЗЫ: зачем такие заморочки? для формирования отчетов и т.п. есть много других удобных примочек (типа Crystal Reports)
ббЗЫ: открытие файла, ессно проблематично (примерно как в Паскале работа с файлами), но лучше всего стандартно прописать Уникальное имя файла (в скриптах и т.п. имеющими с ни дело), с которого будут браться данные... Вот тогда при таких условиях не надо будет так извращаться
В общем это просто мое мнение, сам с такой проблемой сталкивался
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 599
277
#5
afest ну давайте пофантазируем :)...
есть система (на Домине), кот. на вход принимает некие шаблоны (хранятся в БД Нотеса): документы Нотес в РТ, документы ворда, файлы эхеля...
из всего этого ... делаем документ результирующий с подстановкой информации из БД нотес

результат м.б. как ПДФ (что предпочтительно для обмена), так и ОДФ, и разные МСявые форматы

внимание вопрос - для чего мне всякие КОМ объекты, если для нек форматов их просто нет? :)
да и потом... при утерянной ссылке на КОМ объект (в приложении) - как я буду его изыскивать в системе?
а если система не винда?

Уникальное имя файла (в скриптах и т.п. имеющими с ни дело), с которого будут браться данные... Вот тогда при таких условиях не надо будет так извращаться
эту ситуацию я описал - как вычищать-то? набаянили файлов, они лоченные и так весь жизненный цикл... у большинтва юзверей винда ужЕ - помойка для временных (и не только) файлов, а вы предлагаете эту ситуацию ухудшить в 10-ки раз (при активной работе приложения) !?
 

Мыш

Lotus team
12.02.2008
1 099
10
#6
Есть же ShellExecuteEx для виндов. Правда, тоже с особенностями пашет...
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 599
277
#7
здесь больше о разговор о завершении работы приложения, после "утери" контроля над ним (а так и должно быть по смыслу)
Задача запуска более гибко решается на уровне вызова командного процессора (передачей ОС зависимой строки), чем дергание нативных ф-ций
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 599
277
#9
очередные мелкомягкие подарки...
моя любвь МСВорд откинул очередной фортель..
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">"фича а не глюк типа"</div></div><div class="sp-body"><div class="sp-content">
Код:
	For ctbl=1 To worddoc.Tables.Count
'	Forall tbln In worddoc.Tables
cnt=cnt+1
Dim s As String
s={}
Set tbln=worddoc.Tables(ctbl)
On Error Resume Next
s=Ucase(tbln.Title)
On Error Goto ErrH
If Len(s)>0 Then
Set tblsObjList(s)=tbln
Print {Search table for replace:} &s
If Iselement(tblsList(s)) Then
fname=tblsList(s)
If Len(fname)>0 Then
rngS = tbln.Range.Start
tbln.Delete
Call worddoc.Range(rngS, rngS).InsertFile(fname,,False)
Print {replaced:} s {; iteration:} cnt {; Tables Count:} worddoc.Tables.Count
i=i+1
End If
End If
End If	
'	End Forall
казалось бы forall и цикл по счетчику - получаем одинаковые объекты из колекции, НО после удаления, внезапно, forall, на вордяткином объекте клинит (зацикливается) если таблицы с одинаковым title (т.е. удаление и вставка - нарушает итерацию forall)

ну и в дополнение - процедура убиения процесса по имени файла
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">"допиленный код"</div></div><div class="sp-body"><div class="sp-content">
Код:
Sub CloseByFileName(fname As String)
On Error Goto ErrH
Dim req As String, ext As String
ext={.} & Strrightback(fname, {.})
req={Select * From Win32_Process Where CommandLine Like '%} & ext &{%'}
'Print {WMI request:} &req

Dim objWMIService, strComputer As String
strComputer = "."	
Set objWMIService = GetObject( _
"winmgmts:\\" & strComputer & "\root\CIMV2")
Dim objs
Set objs = objWMIService.ExecQuery(req,,48)
If Not objs Is Nothing Then
Forall obj In objs
'			Print {*****************}
'			Print obj.CommandLine
If obj.CommandLine Like {*} &fname &{*} Then obj.Terminate
Dim i As Single, procID As String
procID=obj.ProcessId
Print {Process ID:}procID
'Ищем просесс и ждем его завершения
For i=1 To 5
Dim ProcessList
Set ProcessList=objWMIService.ExecQuery("Select * from Win32_Process Where ProcessID = " &procID &"")
If ProcessList.count>0 Then Sleep(0.2)
Next
End Forall
Else
Print {Application has Not found}
End If
Quit:
Exit Sub
ErrH:
RaiseError
Resume Quit
End Sub
обращу внимание "Select * from Win32_Process Where ProcessID = " &procID &"" эзиз
без последних кавычек у меня выкидывает ошибку - неправильный запрос типа ("Select * from Win32_Process Where ProcessID = " &procID)