PDA

Показать полную графическую версию : [решено] Имя и описание файла в текстовый файл


sov44
13-01-2017, 19:41
В папке имеются файлы типа lync2016-kb3118327-fullfile-x86-glb.exe, необходимо создать текстовый файл с именем KB3118327 и цифрой в зависимости от первого слова описания файла, например:

для access2016-kb2910978-fullfile-x86-glb.exe первое слово описания "Security", в текстовый файл записывается KB2910978-2
для outlfltr2016-kb3115407-fullfile-x86-glb.exe первое слово описания "Definition", в текстовый файл записывается KB3115407-3
для publisher2016-kb3114368-fullfile-x86-glb.exe первое слово описания "Update", в текстовый файл записывается KB3114368-1

Желательно с использованием сторонней утилиты+cmd или чистого vbs, должен создаваться один текстовый файл с записями в столбик.

greg zakharov
13-01-2017, 21:17
А чем PS не угодил? Например:
gci *.exe | select @{N='Name';E={([Regex]'(?i:kb\d+)').Match($_.BaseName).Value}}, @{N='Description';E={$_.VersionInfo.FileDescription[0]}} | % {"$($_.Name)-$($_.Description)"}

sov44
14-01-2017, 09:02
А чем PS не угодил? »
Пока не приходилось пользоваться PS, потому он мне не понятен. В частности создал файл 1.ps1, положил рядом с exe, повершел мелькнул, текстовый файл не создался.
Надеюсь, что найдётся вариант на vbs или на cmd+сторонняя утилита.

Iska
14-01-2017, 20:19
Пока не приходилось пользоваться PS, потому он мне не понятен. »
Запустите его «от имени администратора». Однократно выполните командлет, разрешающий исполнение локальных неподписанных скриптов (если ещё не делали этого ранее):
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned
Затем можно будет использовать скрипты, указывая их по относительному или полному пути.

greg zakharov
14-01-2017, 20:22
/* 2>nul
@echo off
setlocal enabledelayedexpansion
set "i=0"
for %%i in (%*) do set /a "i+=1"
if !i! neq 2 echo:Out of range.&goto:eof
if not exist "%~1" echo:Folder does not exist.&goto:eof
set "key=HKLM\SOFTWARE\Microsoft\.NETFramework"
for /f "tokens=3" %%i in (
'2^>nul reg query %key% /v InstallRoot'
) do set "root=%%i"
if /i "%root%" equ "" echo:.NET not found.&goto:eof
for /f %%i in ('dir /ad /b "%root%v*"') do (
set "path=%root%%%i;!path!"
)
for %%i in (csc.exe) do (
if exist "%%~$PATH:i" set "csc=%%~$PATH:i"
)
set out="%tmp%\app.exe"
set pdb="%tmp%\app.pdb"
set "arg=/nologo /t:exe /out:%out% /optimize+"
set "arg=%arg% /debug:pdbonly /define:CODE_ANALYSIS"
%csc% %arg% "%~f0"
%out% "%~1" "%~2"
del /f /q %out% %pdb%
endlocal
exit /b
*/

using System;
using System.IO;
using System.Text;
using System.Reflection;
using System.Diagnostics;
using System.Globalization;
using System.Text.RegularExpressions;

internal sealed class Program {
static void Clear() {
Console.CursorTop = Console.CursorTop - 1;
Console.Write(new String(' ', Console.BufferWidth));
Console.CursorTop = Console.CursorTop - 2;
}

static void PrintUsage() {
Console.WriteLine("Usage: {0} <directory> <log>",
typeof(Program).Assembly.GetName().Name
);
}

static void Main(String[] args) {
if (args.Length != 2) {
PrintUsage();
return;
}

Clear();
String[] files;
StringBuilder sb = new StringBuilder();

try {
files = Directory.GetFiles(args[0], "*.exe");
foreach (String file in files) {
Char c;
FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(file);
switch (fvi.FileDescription.Split(new Char[] {' '})[0]) {
case "Update": c = '1'; break;
case "Definition": c = '2'; break;
case "Security": c = '3'; break;
default: c = 'x'; break;
}
sb.Append(
String.Format(CultureInfo.InvariantCulture, "{0}-{1}\n",
new Regex(@"(?i:kb\d+)").Match(file).Value, c
));
}
File.WriteAllText(args[1], sb.ToString());
}
catch (Exception e) {
Console.WriteLine(e.Message);
}
}
}

Пример использования:
mybat.cmd E:\src E:\logs\log.txt

Запустите его «от имени администратора». Права администратора не нужны при выполнения данной операции (в случае с PowerShell). Просто влом, если честно, в который раз повторять прописные истины: как запускать, куда что писать, - словом, за какой хвост дернуть, чтобы в ответ услышать "му".

Iska
14-01-2017, 20:48
Права администратора не нужны при выполнения данной операции (в случае с PowerShell). »
Вполне возможно. Я не проверял.

greg zakharov
14-01-2017, 20:58
Вполне возможно.Если имелилось ввиду установка разрешений, то да - права адина нужны. Хотя это в общем-то условная операция, так как можно без установки разрешений обойтись.
powershell /noprofile /executionpolicy bypass /file script.ps1

sov44
14-01-2017, 22:00
greg zakharov, видимо не за тот хвост дёрнул, "му" не получилось...
Убрал проверки, напрямую прописал путь к обновлениям и файлу лога, батник в 866 кодировке (в пути есть кириллица и избавляться от неё не хотелось-бы).
Где взять файлы app.exe, app.pdb?
os - Win7x32
/* 2>nul
@echo off
setlocal enabledelayedexpansion
set "key=HKLM\SOFTWARE\Microsoft\.NETFramework"
for /f "tokens=3" %%i in (
'2^>nul reg query %key% /v InstallRoot'
) do set "root=%%i"
for /f %%i in ('dir /ad /b "%root%v*"') do (
set "path=%root%%%i;!path!"
)
for %%i in (csc.exe) do (
if exist "%%~$PATH:i" set "csc=%%~$PATH:i"
)
set out="%tmp%\app.exe"
set pbd="%tmp%\app.pdb"
set "arg=/nologo /t:exe /out:%out% /optimize+"
set "arg=%arg% /debug:pdbonly /define:CODE_ANALYSIS"
%csc% %arg% "%~f0"
%out% "d:\Декомпрессор\Updates" "d:\Декомпрессор\log.txt"
del /f /q %out% %pdb%
endlocal
pause
exit /b
*/

using System;
using System.IO;
using System.Reflection;
using System.Diagnostics;
using System.Globalization;
using System.Text.RegularExpressions;

internal sealed class Program {
static void Clear() {
Console.CursorTop = Console.CursorTop - 1;
Console.Write(new String(' ', Console.BufferWidth));
Console.CursorTop = Console.CursorTop - 2;
}

static void PrintUsage() {
Console.WriteLine("Usage: {0} <directory> <log>",
typeof(Program).Assembly.GetName().Name
);
}

static void Main(String[] args) {
if (args.Length != 2) {
PrintUsage();
return;
}

Clear();
String[] files;
StringBuilder sb = new StringBuilder();

try {
files = Directory.GetFiles(args[0], "*.exe");
foreach (String file in files) {
Char c;
FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(file);
switch (fvi.FileDescription.Split(new Char[] {' '})[0]) {
case "Update": c = '1'; break;
case "Definition": c = '2'; break;
case "Security": c = '3'; break;
default: c = 'x'; break;
}
sb.Append(
String.Format(CultureInfo.InvariantCulture, "{0}-{1}\n",
new Regex(@"(?i:kb\d+)").Match(file).Value, c
));
}
File.WriteAllText(args[1], sb.ToString());
}
catch (Exception e) {
Console.WriteLine(e.Message);
}
}
}



d:\Декомпрессор>/* 2>nul
1.cmd(54,5): error CS0246: Не удалось найти имя типа или пространства имен "StringBuilder"
(пропущена директива using или ссылка на сборку?)
1.cmd(54,28): error CS0246: Не удалось найти имя типа или пространства имен
"StringBuilder" (пропущена директива using или ссылка на сборку?)
""c:\Windows\Temp\app.exe"" не является внутренней или внешней
командой, исполняемой программой или пакетным файлом.
Не удается найти c:\Windows\Temp\app.exe
Для продолжения нажмите любую клавишу . . .

greg zakharov
14-01-2017, 22:29
sov44, app.exe и app.pdb генерируются из C# кода в представлении бата как такового, то есть бат "скармливает" копилятору csc.exe себя как исходник программы на C#, а тот создает сборку во временной папке с именем app.exe (генериацию .PDB можно в принципе отключить, удалив определенные параметры компиляции кода); после того, как app.exe отрабатывает, бат его удаляет. В 32-битной Win7 все и писалось, так что должно работать при условии, что имеются права на запись во временную папку пользователя, а вот спойлеры у на этом форуме не открываются (косяк браузера), так что ошибку посмотреть не могу.
P.S., в коде допустил опечатку:
set pbd="%tmp%\app.pdb"
...
del /f /q %out% %pdb%
Должно быть:
set pdb="%tmp%\app.pdb"
...
del /f /q %out% %pdb%

sov44
14-01-2017, 22:52
greg zakharov, исправил опечатку, всё равно ошибка

d:\Декомпрессор>/* 2>nul
1.cmd(54,5): error CS0246: Не удалось найти имя типа или пространства имен "StringBuilder"
(пропущена директива using или ссылка на сборку?)
1.cmd(54,28): error CS0246: Не удалось найти имя типа или пространства имен
"StringBuilder" (пропущена директива using или ссылка на сборку?)
""c:\Windows\Temp\app.exe"" не является внутренней или внешней
командой, исполняемой программой или пакетным файлом.
Не удается найти c:\Windows\Temp\app.exe
Для продолжения нажмите любую клавишу . . .

greg zakharov
14-01-2017, 23:31
sov44, куда-то делась директива "using System.Text;" при переносе кода на форум. Поправил (http://forum.oszone.net/post-2703598-5.html).

sov44
14-01-2017, 23:37
greg zakharov, теперь всё отработало, спасибо!




© OSzone.net 2001-2012