Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,27 @@

## Changelog
```
--- 2.6 ---
[Change] Lan::getAdapters() - теперь выдаёт и Wlan адаптеры

--- 2.5 ---
[Fix] Lan::getActiveAdapter() - Больше не выдаёт как активные адаптеры виртуальных локальных сетей
[Fix] Bundle для DevelNext снова корректно собирается

--- 2.4 ---
[Change] Windows::createShortcut() - Теперь поддерживает кастомный путь до иконки и аргументы командной строки
[Change] Автором бандла поставил себя, т.к. TsSaltan явно забросил пакет
[Change] Иконка Windows 7 заменена на Windows 11

--- 2.3 ---
[Fix] Windows::runAsAdmin() - Теперь нормально работает, если аргументов нет. Если их нет, для Start-Process не передается -ArgumentList
[Fix] Windows::requireAdmin() - Нормально перезапускает программу, если ей не передано аргументов и она скомпилирована в .exe
[Fix] Lan::getActiveAdapter() - Проверяет активен ли адаптер через isConnected(), а не несуществующий isActive(). Больше не вызывает исключения

--- 2.2 ---
[Add] Windows::print()
[Add] Windows::getFileMeta()

--- 2.1.1 ---
[Add] Windows::getSystemDrive()
Migrate to jppm
Expand Down Expand Up @@ -95,4 +116,4 @@ jppm add windows@git+https://github.com/TsSaltan/jphp-windows-ext
## Build bundle
```
jppm bundle:build
```
```
6 changes: 3 additions & 3 deletions package.php.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: windows
version: 2.2
version: 2.6
description: Пакет для взаимодействия с API Windows

plugins:
Expand Down Expand Up @@ -36,10 +36,10 @@ config:
- /gradlew.**

develnext-bundle:
version: 2.2
version: 2.6
name: windows
description: Плагин для взаимодействия с API Windows
author: Ts.Saltan
author: queinu
icon: "develnext/bundle/windows/windows32.png"
group: "system"
class: "develnext\\bundle\\windows\\WindowsBundle"
Binary file modified src-bundle/.data/img/develnext/bundle/windows/windows32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php
namespace bundle\windows;

use bundle\windows\result\comItem;
use bundle\windows\WindowsScriptHost as WSH;
use php\util\Regex;

/**
* Класс для работы с COM-портами
* @packages windows
*/
class COM
{
/**
* --RU--
* Получить список портов
* @return comItem[]
*/
public static function getList(){
$com = [];
$reg = Registry::of('HKEY_LOCAL_MACHINE\Hardware\DeviceMap\SerialComm')->readFully();
foreach($reg as $r){
foreach($r as $v){
$com[$v->value] = new comItem($v->value, array_merge(self::getParams($v->value), ['path' => $v->key]));
}
}

return $com;
}

/**
* --RU--
* Получить список параметров порта
* @param string $port Имя порта (от COM1 до COM255)
* @return array
*/
public static function getParams($port){
$r = WSH::WMIC('path Win32_PnPEntity WHERE "Caption like \'%' . $port . '%\'" get');
return isset($r[0]) ? $r[0] : [];
}

/**
* --RU--
* Ищет устройство по имени
* @param string $search Строка поиска
* @param array $searchFields=['Caption','Description','Name','Service'] Поля, по ктоторым осуществляется поиск
* @return comItem[]
*/
public static function searchDevice($search, $searchFields = ['Caption', 'Description', 'Name', 'Service']){
$searchCOM = ['Caption', 'Name']; // Поля, в которых фигурирует номер COM порта

// Формирование SQL запроса
$searchQuery = [];
foreach($searchFields as $field){
$searchQuery[] = $field . ' like \'%' . $search . '%\'';
}
$search = implode(' OR ', $searchQuery);
$r = WSH::WMIC('path Win32_PnPEntity WHERE "'.$search.'" get');

$ports = [];
foreach ($r as $v) {
$string = ''; // Делаем конкатенацию полей, где может фигурировать номер COM порта
foreach ($searchCOM as $field){
$string .= $v[$field];
}
$regex = Regex::of('(COM[0-9]+)', Regex::CASE_INSENSITIVE + Regex::UNICODE_CASE)->with($string);
if ($regex->find()){ // Если удалось определить номер com порта
$ports[$regex->group(1)] = new comItem($regex->group(1), $v);
}
}

return $ports;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<?php
namespace bundle\windows;


use bundle\windows\WindowsScriptHost as WSH;
use bundle\windows\Windows;
use php\lib\str;
use php\util\Regex;
use bundle\windows\result\lanAdapter;
use php\util\Scanner;

/**
* Local Area Network
* @packages windows
*/
class Lan
{
/**
* Получить список адаптеров
* @return array
*/
public static function getAdapters() : array {
$adapters = [];
$adaptersObj = [];
$adapterName = false;

// ipconfig возвращает в 866, независимо от указанной кодировки
$cmd = WSH::cmd('ipconfig /all', [], 'utf-8', 'cp866');
$nic = WSH::WMIC('nic get');

$scanner = (new Scanner($cmd))->useDelimiter(Regex::of('\n', Regex::MULTILINE));
while($scanner->hasNextLine()){
$scanner->next();
$line = $scanner->current();

$regAdapter = Regex::of('Ethernet adapter ([^\n\r]+):', Regex::MULTILINE)->with($line);
$isfind = $regAdapter->find();

if (!($isfind)){
$regAdapter = Regex::of('Wireless LAN adapter ([^\n\r]+):', Regex::MULTILINE)->with($line);
$isfind = $regAdapter->find();}
if($isfind){
$adapterName = $regAdapter->group(1);
} elseif($adapterName != false){
$regParam = Regex::of('\s+([^\.]+)[\.\s]+:([^\n]+)', Regex::MULTILINE)->with($line);
if($regParam->find()){
$key = trim($regParam->group(1));
if(isset($adapters[$adapterName][$key])) $adapterName = false;
else $adapters[$adapterName][$key] = trim($regParam->group(2));
}
}
}

foreach($nic as $k => $v){
if(!isset($v['NetConnectionID'])) continue;
if(!isset($adapters[$v['NetConnectionID']])){
$adapters[$v['NetConnectionID']] = [
'Description' => $v['Description'],
'Physical Address' => $v['MACAddress'],
];
}

$adapters[$v['NetConnectionID']]['Speed'] = $v['Speed'] ?? 0;
$adapters[$v['NetConnectionID']]['Manufacturer'] = $v['Manufacturer'] ?? '';
$adapters[$v['NetConnectionID']]['Manufacturer'] = $v['Manufacturer'] ?? '';
$adapters[$v['NetConnectionID']]['NetEnabled'] = isset($v['NetEnabled']) && $v['NetEnabled'] == 'TRUE';
}

foreach ($adapters as $name => $params) {
$adaptersObj[] = new lanAdapter($name, $params);
}
return $adaptersObj;
}

/**
* Получить используемый по умолчанию адаптер
* @return lanAdapter
*/
public static function getActiveAdapter() : lanAdapter{
$adapters = self::getAdapters();
foreach ($adapters as $adapter) {
$device = $adapter->getDevice();
if(str::contains($device,'Radmin') or str::contains($device,'Hamachi') or str::contains($device,'ZeroTier'))
continue;

if($adapter->isConnected())
return $adapter;

}

return null;
}

/**
* Есть ли оборудование для работы с проводными сетями
* @return boolean
*/
public static function isSupported() : bool {
return sizeof(self::getAdapters()) > 0;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php
namespace bundle\windows;

use bundle\windows\WindowsScriptHost as WSH;
use php\io\File;
use php\lib\str;
use php\util\Regex;
use php\util\Scanner;

/**
* @packages windows
*/
class Metadata
{
/**
* @var File
*/
protected $file;

/**
* @param File|string $file
*/
public function __construct($file){
$this->file = ($file instanceof File) ? $file : File::of($file) ;
}

public function readData(int $items = 300){
$title_query = '
$objShell = New-Object -ComObject Shell.Application
$objFolder = $objShell.namespace(":path")
0..:items | Foreach-Object { \'{0} = {1}\' -f $_, $objFolder.GetDetailsOf($null, $_) }
';

$data_query = '
$objShell = New-Object -ComObject Shell.Application
$objFolder = $objShell.namespace(":path")
$objFile = $objFolder.parsename(":file")
0..:items | Foreach-Object { \'{0} = {1}\' -f $_, $objFolder.GetDetailsOf($objFile, $_) }
';

$title_items = WindowsScriptHost::PowerShell($title_query, ['file' => $this->file->getName(), 'path' => dirname($this->file->getAbsolutePath()), 'items' => $items]);
$data_items = WindowsScriptHost::PowerShell($data_query, ['file' => $this->file->getName(), 'path' => dirname($this->file->getAbsolutePath()), 'items' => $items]);

$title = $this->parse($title_items);
$data = $this->parse($data_items);

$array = array_combine($title, $data);
foreach ($array as $k=>$v){
if(strlen($k) == 0 || strlen($v) == 0){
unset($array[$k]);
}
}

return $array;
}


protected function parse($lines){
$scanner = new Scanner($lines, 'UTF-8');
$data = [];

while ($scanner->hasNextLine()) {
$line = $scanner->nextLine();
list($key, $value) = str::split($line, '=', 2);
$key = intval(str::trim($key));
$value = str::trim($value);

$data[$key] = $value;

}

return $data;
}
}
Loading