1

Тема: JScript: Идентификатор процесса (процессов), открывшего файл

Добрый день, Уважаемые гуру!

Буду рад если Вы подскажете идею решения следующей задачи:

Дано: Полное имя файла.
Надо: Определить список процессов открывших данный файл.

Подробнее: Необходимо запустить программу ассоциированную с данным файлом.
Сделать это достаточно просто:

   oWshShell.Run('"' + sFileFullName + '"',  1)

Однако если с файлом ассоциировано "не хитрое" приложение (не такое как Word или Excel, а например Notepad), то будет открыто ровно столько приложений, сколько запусков файла вы осуществили. А вот именно этого и хотелось бы избежать. А именно: посмотреть если файл уже используется каким либо процессом, то получить Id процесса и активизировать его вызовом

  oWshShell.AppActivate( nProcessId );

Косвенное решение данной проблемы я имею. Суть идеи состоит в том, чтобы анализировать командную строку запуска процесса, с выявлением - передан ли файл в качестве аргумента командной строки. Если имя файла есть в аргументах командной строки, то можно с большой уверенностью сказать, что данный файл используется процессом приложения. Однако уверенность не 100 процентная. Ниже код скрипта для описанного анализа:

//
//  Поиск процесса 
//
function Lib_SysDoc_FindSysDocProcessId( sFileFullName )
{
 var oWMIService, oProcItems, oEnumItems, nProcessId;

   nProcessId = 0;
   try
   {
     oWMIService = GetObject("winmgmts:\\\\.\\root\\CIMV2");
     oProcItems = oWMIService.ExecQuery("SELECT * FROM Win32_Process WHERE name LIKE '%.exe%' OR name LIKE '%.com%'", 'WQL');
     
     // Ишем ProcessId  
     oEnumItems = new Enumerator(oProcItems);
     for (; !oEnumItems.atEnd(); oEnumItems.moveNext()) 
     {
       with ( oEnumItems.item() )
       {
         if ( CommandLine == null )
           continue;
         if ( CommandLine.indexOf( sFileFullName ) >= 0 )
         {
           nProcessId = ProcessId;
           break;
         }
       }
     }
   }
   catch(e)
   {
     nProcessId = 0
   }
   if ( oWMIService != null )
     ReleaseObject(oWMIService);

   return( nProcessId )
}

Повторюсь - Буду признателен если Вы подскажете идею решения изложенной выше задачи.

2

Re: JScript: Идентификатор процесса (процессов), открывшего файл

Что-то я вообще сомневаюсь в 100%. Приложение может открыть файл, считать его в буфер и закрыть. В результате файл даже и не открыт, хотя "используется", т.к. его содержимое отображается в окне. Этот-то случай как определить? Даже в заголовке окна скорее всего не полное имя файла будет. Залезать в память процесса и шарить там в поисках пути отображаемого файла?

3 (изменено: Large Null, 2007-12-19 16:46:07)

Re: JScript: Идентификатор процесса (процессов), открывшего файл

4

Re: JScript: Идентификатор процесса (процессов), открывшего файл

YMP пишет:

Что-то я вообще сомневаюсь в 100%. Приложение может открыть файл, считать его в буфер и закрыть. В результате файл даже и не открыт, хотя "используется", т.к. его содержимое отображается в окне. Этот-то случай как определить? Даже в заголовке окна скорее всего не полное имя файла будет. Залезать в память процесса и шарить там в поисках пути отображаемого файла?

Конечно, такой случай может быть, однако давайте не будем его рассматривать.

5

Re: JScript: Идентификатор процесса (процессов), открывшего файл

Что это за страусиная политика? Так скоро смотреть некуда станет.
Думаю, не "может быть", а обычное дело. Сейчас я это пишу в текстовом редакторе, где загружено 95 файлов. Все они открывались только для считывания содержимого и тут же закрывались. Знаю точно, т.к. сам его и написал. Зачем держать их открытыми-то, какой смысл? И Блокнот, думаю, тоже именно так и работает. Например, "открытый" им файл удаляется без шума и пыли. Тогда как если файл на самом деле открыт каким-то процессом, получаем вот что:

---------------------------
Ошибка при удалении файла или папки
---------------------------
Не удается удалить test. Объект используется другим пользователем или программой.

Закройте все программы, которые могут использовать этот файл и повторите попытку.
---------------------------
ОК   
---------------------------

Т.е. файл используется очень короткое время, пока считывается. После этого используется его копия в памяти. А файл уже закрыт и не используется.

Но это всё так, мысли вокруг да около. WMI для меня тёмный лес, кто его знает, может, там есть волшебный приём на этот случай. Хотя знатоки его пока хранят загадочное молчание.

6

Re: JScript: Идентификатор процесса (процессов), открывшего файл

Вам нужно узнать, каким процессом/приложением открыт и заблокирован файл?

7 (изменено: alexii, 2007-12-19 22:40:47)

Re: JScript: Идентификатор процесса (процессов), открывшего файл

Судя по описаниям из открытых источников (NirSoft, Sysinternals & etc), как происходит процесс поиска открытых файлов — напрямую вряд ли получится. Самый простой вариант — использовать консольный Handle и разбирать его вывод, дабы получить PID процесса. Пример работы Handle:

C:\ShellExecute Demonstration>
. "C:\Install\Sysinternals.com\Handle\Handle 3.30\handle.exe" Sample.xls

Handle v3.3
Copyright (C) 1997-2007 Mark Russinovich
Sysinternals - www.sysinternals.com

EXCEL.EXE          pid: 3612    290: C:\ShellExecute Demonstration\Sample.xls


C:\ShellExecute Demonstration>
.

P.S. По поводу же неблокированных файлов YMP уже правильно сказал. Общего метода решения не существует. Для каждого приложения нужен будет свой метод.