Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   [решено] Узнать, MBR или GPT? (http://forum.oszone.net/showthread.php?t=259331)

m0nkrus 24-04-2013 19:10 2139028

Узнать, MBR или GPT?
 
Нужно получить данные, какой формат имеет диск С, MBR или GPT и исходя из этой инфы задать флаговую переменную как 0 или 1.

zion87 24-04-2013 20:36 2139051

Код:

@Echo Off
Set Sys=MBR
@Echo  List Disk|Diskpart|Find /I  "Gpt" && Set Sys=GPT


m0nkrus 24-04-2013 23:45 2139127

zion87, ну вы бы хоть посмотрели, как команда List Disk в Diskpart отображает наличие GPT... Там столбец GPT, он всегда есть. Соответственно результат работы вашего скрипта будет всегда одинаков. А если раздел GPT, то это обозначается наличием звездочки в соответствующем столбце.

Вот так это выглядит:


Но бывает и такой вариант, так что ориентироваться ТОЛЬКО НА НАЛИЧИЕ ЗВЕЗДОЧКИ нельзя:

Iska 25-04-2013 02:42 2139170

m0nkrus, используйте такой подход:
Detect GPT and MBR partitions with Powershell - Stack Overflow
GPT oder MBR: Partitionierungsschema auslesen mit diskpart, wmic, PowerShell | WindowsPro

P.S. У меня нет GPT под рукой, проверять и отлаживать пакетный файл не на чем.

m0nkrus 25-04-2013 02:59 2139173

Цитата:

Цитата Iska
У меня нет GPT под рукой, проверять и отлаживать пакетный файл не на чем. »

Дык та же фигня... Приходится тестировщиков подключать, у кого оно есть.

За ссылки спасибо - гляну.

Iska 25-04-2013 04:58 2139177

Посмотрите. Если делаете на сторону — может проще будет использовать как раз WSH, або PoSH.

m0nkrus 25-04-2013 07:46 2139203

Iska, мне нужно эту выборку задействовать в SetupComplete.cmd автоустановки семерки. Так что CMD и только CMD.

P.S. Боюсь для решения моей проблемы по приведенным выше ссылкам инфы не наблюдается...

m0nkrus 25-04-2013 09:42 2139231

Прикинул, покумекал... По логике, так как при выводе через DISKPART столбец GPT последний, а под элементы, даже если они отсутствуют, место резервируется, то таким образом видоизмененный вариант скрипта zion87 должен работать:
Код:

@Echo Off
Set Sys=MBR
@Echo List Disk | Diskpart | Findstr /R /C:"\*$" && Set Sys=GPT

Но этот скрипт показывает лишь наличие или отсутствие в системе GPT-дисков. А мне бы хотелось узнать не является ли системный диск (диск С) GPT-диском. Ведь может быть и такое:

Iska 25-04-2013 11:22 2139281

На WSH:
Код:

Option Explicit

Dim strComputer
Dim objSWbemObjectEx
Dim strSystemDrive


strComputer = "."

With WScript.CreateObject("WbemScripting.SWbemLocator").ConnectServer(strComputer, "root\cimv2")
        For Each objSWbemObjectEx In .ExecQuery("SELECT * FROM Win32_OperatingSystem")
                strSystemDrive = objSWbemObjectEx.SystemDrive
               
                Exit For
        Next
       
        For Each objSWbemObjectEx In .ExecQuery("ASSOCIATORS OF {Win32_LogicalDisk.DeviceID='" & .Get("Win32_LogicalDisk.DeviceID='" & strSystemDrive & "'").DeviceID & "'} WHERE ResultClass = Win32_DiskPartition")
                WScript.Echo "System drive:", strSystemDrive
                WScript.Echo "Partition:  ", objSWbemObjectEx.DeviceID
                WScript.Echo "Type:        ", objSWbemObjectEx.Type
               
                If UCase(Left(objSWbemObjectEx.Type, 3)) = "GPT" Then
                        WScript.Echo "GPT"
                Else
                        WScript.Echo "Not GPT"
                End If
        Next
End With

WScript.Quit 0


m0nkrus 25-04-2013 11:25 2139284

Iska, ну я же сказал, что на WSH мне не пойдет...

Iska 25-04-2013 11:51 2139297

Цитата:

Цитата m0nkrus
Iska, ну я же сказал, что на WSH мне не пойдет... »

читать дальше »
— Рэбе, куры сдохли…
— Ну, вот, а у меня ещё столько плодотворных идей было ;)
А я Вам PoSH приготовил:
Код:

$sComputerName = "."

Get-WmiObject -ComputerName $sComputerName -Query "ASSOCIATORS OF {Win32_LogicalDisk.DeviceID='$((Get-WmiObject -ComputerName $sComputerName -Query "SELECT * FROM Win32_LogicalDisk WHERE DeviceID = '$((Get-WmiObject -ComputerName $sComputerName -Query "SELECT * FROM Win32_OperatingSystem").SystemDrive)'").DeviceID)'} WHERE ResultClass = Win32_DiskPartition" |`
    Select-Object DiskIndex, @{Name="GPT";Expression={$_.Type.StartsWith("GPT")}}


Если серьёзно — я не видел последующей правки:
Цитата:

Цитата m0nkrus
Iska, мне нужно эту выборку задействовать в SetupComplete.cmd автоустановки семерки. Так что CMD и только CMD. »

На этом этапе WSH не доступен? Или Wbem не работает?

Vadikan 25-04-2013 13:17 2139327

powershell.exe можно вызвать из SetupComplete

m0nkrus 25-04-2013 15:02 2139392

Цитата:

Цитата Iska
На этом этапе WSH не доступен? Или Wbem не работает? »

Вот чего не знаю, того не знаю. Но даже если работает, как из PowerShell передать обратно в CMD результат отработки вашего скрипта? Через вывод результатов во внешний файл?

Iska 25-04-2013 15:22 2139407

Цитата:

Цитата m0nkrus
как из PowerShell передать обратно в CMD результат отработки вашего скрипта? »

Код:

$sComputerName = "."

If((Get-WmiObject -ComputerName $sComputerName -Query "ASSOCIATORS OF {Win32_LogicalDisk.DeviceID='$((Get-WmiObject -ComputerName $sComputerName -Query "SELECT * FROM Win32_LogicalDisk WHERE DeviceID = '$((Get-WmiObject -ComputerName $sComputerName -Query "SELECT * FROM Win32_OperatingSystem").SystemDrive)'").DeviceID)'} WHERE ResultClass = Win32_DiskPartition").Type.StartsWith("GPT")) {
    Exit 0
} Else {
    Exit 1
}

(или «Return»; что правильнее — не знаю).
Код:

@echo off
setlocal enableextensions enabledelayedexpansion

.\БезИмени1.ps1

if %errorlevel% equ 0 (
        echo GPT
) else (
        echo Not GPT
)

endlocal
exit /b 0

P.S. Для верности, конечно, корректнее будет брать не 0 и 1, а какие-либо большие величины, заведомо превышающие те, которые может возвращать сам powershell.exe (например, в случае ошибок).

m0nkrus 25-04-2013 15:29 2139412

Iska, спасибо, потестирую.

m0nkrus 25-04-2013 20:58 2139627

Iska, так, что-то я уперся...

Я так понимаю, в прошлом вашем посте первое - это скрипт для PowerShell, который должен быть помещен в файл БезИмени1.ps1, так? Второе - cmd-файл, который и обращается к скрипту PowerShell и получает от него результат, так?

Так вот, не работает. Если оставить расширение ps1, то cmd-шник просто открывает ps1 блокнотом. А если расширение заменить на пауэршелловское psc1, то cmd просто вылетает на этой команде. Тот же эффект при замене строки .\БезИмени1.ps1 на PowerShell -PSConsoleFile БезИмени1.psс1

Что я делаю не так?


У меня, между тем, разработка скрипта на основе diskpart вышла на финишную прямую. Вот до чего я дошел:
Код:

CD /d %~dp0
ECHO LIST DISK | DISKPART | FINDSTR /r /c:"\*$" > disks.txt
FOR /f "tokens=2" %%i IN (disks.txt) DO ECHO select disk %%i >> diskpart.txt && ECHO detail disk >> diskpart.txt
DISKPART /s diskpart.txt | FINDSTR /e "Boot Загрузоч"
IF ERRORLEVEL 1 (
    ECHO Загрузочный том размещен на MBR-разделе
) ELSE (
    ECHO Загрузочный том размещен на GPT-разделе
)

Что скажете? Хорошо бы оптимизировать.

Iska 25-04-2013 23:25 2139715

Цитата:

Цитата m0nkrus
Так вот, не работает. Если оставить расширение ps1, то cmd-шник просто открывает ps1 блокнотом. А если расширение заменить на пауэршелловское psc1, то cmd просто вылетает на этой команде. Тот же эффект при замене строки .\БезИмени1.ps1 на PowerShell -PSConsoleFile БезИмени1.psс1
Что я делаю не так? »

Что-то с безопасностью. Вообще — хоть какие-либо скрипты PowerShell'а работают? Посмотрите это: Running Windows PowerShell Scripts — как разрешить исполнение неподписанных локальных скриптов, и почему требуется указывать путь к скрипту.

Цитата:

Цитата m0nkrus
Что скажете? »

У меня, например, не «Boot Загрузоч», а «Системны». Windows XP Professional, SP,3 RU.
Стоп. У Вас логика с errorlevel — мне не понятная. Словами опишите.

m0nkrus 26-04-2013 10:11 2139821

Iska, с PowerShell посмотрю позже.

Логика с errorlevel простая: если в файле найдена ключевая строка, информирующая, что на ней размещен загрузочный диск (он в системе один), то ошибки нет и это GPT, если такой строки ни на одном из GTP-дисков не обнаружено, то, и поиск не дал результата - ошибка - значит по остаточному признаку загрузочным диском считать MBR.

Мы рассматриваем случай для семерки, не забыли? Случай с ХР - это за пределами ТЗ.

Iska 26-04-2013 10:56 2139835

m0nkrus, спасибо, теперь ясно.

Цитата:

Цитата m0nkrus
Мы рассматриваем случай для семерки, не забыли? Случай с ХР - это за пределами ТЗ. »

Ну, тогда сам бог велел PowerShell пользовать.

Ксеноинженер 26-04-2013 19:52 2140171

m0nkrus, на тему оптимизации: логично было бы вместо detail disk использовать uniqueid disk, и если ID содержит "{" - то диск имеет GUID, и следовательно GPT.
Код:

@echo off
CD /d %~dp0
for /f "tokens=2" %%I IN ('Echo List Disk ^| Diskpart ^| Findstr /e "Boot Загрузоч"') do echo Select Disk ^%%I > diskpart.txt && echo uniqueid disk >> diskpart.txt
for /f "tokens=*" %%J IN ('Diskpart /s diskpart.txt ^| find "{"') DO (
    if errorlevel==0 ( echo Загрузочный диск GPT
                      Set Sys=GPT
    ) else (
                      echo Загрузочный диск MBR
                      Set Sys=MBR
    )
)
pause


m0nkrus 26-04-2013 23:47 2140262

Ксеноинженер, вы пробовали проверять свою конструкцию в деле? У меня совмещение двух строк без промежуточного помещения результатов в файл disks.txt:
Код:

ECHO LIST DISK | DISKPART | FINDSTR /r /c:"\*$" > disks.txt
FOR /f "tokens=2" %%i IN (disks.txt) DO ECHO select disk %%i >> diskpart.txt && ECHO detail disk >> diskpart.txt

...в аналог вашего кода:
Код:

for /f "tokens=2" %%I IN ('Echo List Disk ^| Diskpart ^| Findstr /e "Boot Загрузоч"') do echo Select Disk ^%%I > diskpart.txt && echo uniqueid disk >> diskpart.txt
...не проходило - ругается то на команду echo, то на знак |. При помощи ^ вы экранировали символы |, но остаются ли последние после этого работоспособными? Кстати, при применениии конструкции "echo Select Disk ^%%I > diskpart.txt" вы получите перезапись старых значений новыми, а не накопление оных. Это не говоря уже о том, что искать подстроки "Boot Загрузоч" в результатах срабатывания команды List Disk бесполезно - их там нет.

Поиск "{" через команду uniqueid disk действительно может помочь в определении GPT-раздела. Только тут надо каждый раздел подключать и проверять поочередно, а я с помощью команды List Disk нахожу их все одним махом. Да и ничуть uniqueid disk не поможет в определении, есть ли среди GPT-дисков загрузочный, для чего я и использую detail disk.

Если честно, в вашем скрипте столько ошибок и логических нестыковок, что он в таком виде не заработает совершенно точно. Это я могу сказать даже без тестирования.

Ксеноинженер 27-04-2013 03:14 2140299

m0nkrus, Вы были корректны. Моё недоразумение в данном случае.
Возвращаюсь к Вашему, правильному, скрипту.
Обойтись одним внешним файлом всё же можно (проверил, работает на GPT и MBR)
каретки "^" обеспечивают целостность строки echo, не разрывая цикл символами "|".
Код:

CD /d %~dp0
for /f "tokens=2" %%I IN ('echo List Disk ^| Diskpart ^| Findstr /r /c:"\*$"') do echo Select Disk %%I >> diskpart.txt && echo detail disk >> diskpart.txt
Diskpart /s diskpart.txt | findstr /e "Boot Загрузоч"
IF ERRORLEVEL 1 (
        ECHO Загрузочный том размещен на MBR-разделе
        ) ELSE (
        ECHO Загрузочный том размещен на GPT-разделе
        )
)
del /q diskpart.txt
pause

Цитата:

остаются ли последние после этого работоспособными?
да, остаются, это как с двойным %% для переменной работает
Цитата:

перезапись старых значений новыми
Не подумал о нескольких gpt дисках в системе, был не прав :)
Цитата:

он в таком виде не заработает совершенно точно.
Что ж, с этим я смирюсь как-нибудь. Важно другое, мастер лучших в рунете сборок Windows Vista/7/8 - это Вы, уважаемый m0nkrus. Дело мастера боится.
Одно пока мне неясно, как скрыть сообщение о найденном GPT диске. @echo off почему-то не сработал?

Iska 27-04-2013 08:33 2140339

Нагляднее (не проверялось):
Код:

for /f "tokens=2" %%I IN ('echo List Disk ^| Diskpart ^| Findstr /r /c:"\*$"') do (
    > diskpart.txt (echo Select Disk %%I
    echo detail disk)
)

Также можно использовать такую методику работы с diskpart.exe:
Код:

(echo select disk 0 & echo list volume) | diskpart.exe
т.е. (также не проверялось) наподобие:
Код:

for /f "tokens=2" %%I IN ('echo List Disk ^| Diskpart ^| Findstr /r /c:"\*$"') do (
        (echo Select Disk %%I
        echo detail disk) |
diskpart.exe | findstr.exe /e "Boot Загрузоч"
        IF ERRORLEVEL 1 (
                ECHO Загрузочный том размещен на MBR-разделе
        ) ELSE (
                ECHO Загрузочный том размещен на GPT-разделе
        )
)


m0nkrus 27-04-2013 10:18 2140375

Цитата:

Цитата Ксеноинженер
да, остаются, это как с двойным %% для переменной работает »

Это действительно полезная оптимизация.
Цитата:

Цитата Ксеноинженер
Одно пока мне неясно, как скрыть сообщение о найденном GPT диске. @echo off почему-то не сработал? »

Это-то как раз просто. В конце команды добавить "> nul". Но в моем конкретном случае это несущественно.

Iska
Спасибо, посмотрю ваши наработки. Потестирую. Оптимально, конечно, совсем отказаться от внешних файлов.

m0nkrus 27-04-2013 10:33 2140377

Iska, первая конструкция рабочая, за исключением маленького нюанса. Она у вас тоже предусматривает наличие только одного GPT раздела. Надо так:
Код:

for /f "tokens=2" %%I IN ('echo List Disk ^| Diskpart ^| Findstr /r /c:"\*$"') do (
    >> diskpart.txt (echo Select Disk %%I
    echo detail disk)
)

Вторая конструкция тоже рабочая. Команды вы правда подобрали бессистемно. Команде, начинающейся с list без разницы, какой диск выбран. Но сама идея конструкта интересна.

Третий код снова не учитывает наличия нескольких GPT-разделов. Если их два и система размещена на первом, то на выходе скрипта мы получим, что система у нас, якобы на MBR.

Iska 27-04-2013 10:44 2140379

Цитата:

Цитата m0nkrus
Она у вас тоже предусматривает наличие только одного GPT раздела. »

m0nkrus, у меня и одного-то нет :lol:. Я потому и писал — «не проверялось». Я просто брал код из чужого поста и на его основе «лопатил». «Отлопаченное» выделял цветом.

Цитата:

Цитата m0nkrus
Команды вы правда подобрали бессистемно. Команде, начинающейся с list без разницы, какой диск выбран. »

Второй пример — просто иллюстрация возможности передачи двух (и более) строк по конвейеру на вход «diskpart.exe».

Ежели сделаете на «отлопаченном» проверенный рабочий вариант — поместите его в тему.

m0nkrus 27-04-2013 11:18 2140389

Цитата:

Цитата Iska
m0nkrus, у меня и одного-то нет . Я потому и писал — «не проверялось» »

Дык, у меня тоже нет. Для проверки я просто меняю код "\*$" на "\ $" и в качестве подопытных выступают MBR-разделы.
Цитата:

Цитата Iska
Ежели сделаете на «отлопаченном» проверенный рабочий вариант — поместите его в тему. »

Пока, на мой взгляд, оптимальный рабочий вариант, это тот, что на основе моего сделал Ксеноинженер.

m0nkrus 27-04-2013 12:03 2140405

Iska, хотя можно тоже кое-что и из ваших наработок позаимствовать, немного оптимизировав:
Код:

@ECHO OFF
CD /d %~dp0
FOR /f "tokens=2" %%i IN ('ECHO LIST DISK ^| DISKPART ^| FINDSTR /r /c:"\*$"') DO (>> diskpart.txt (ECHO select disk %%i && ECHO detail disk))
DISKPART /s "diskpart.txt" | FINDSTR /e "Boot Загрузоч" > nul
IF ERRORLEVEL 1 (
    ECHO Загрузочный том размещен на MBR-разделе
) ELSE (
    ECHO Загрузочный том размещен на GPT-разделе
)
PAUSE

Только не знаю, можно ли считать замену конструкции:
Код:

ECHO select disk %%i >> diskpart.txt && ECHO detail disk >> diskpart.txt
... на эту:
Код:

(>> diskpart.txt (ECHO select disk %%i && ECHO detail disk))
...оптимизацией. Если бы команд на каждом витке цикла было больше, то да, это бы подсократило код, но всего с двумя элементами особой разницы нет.

Iska 27-04-2013 13:46 2140428

Добавил иллюстрацию
 
Цитата:

Цитата m0nkrus
можно ли считать »

m0nkrus, если рассуждать теоретически,
читать дальше »
при большом количестве «echo» — можно: насколько я понимаю (замерял, но не проверял, например, в отладчике), при группировке вывода:
Код:

> Out.txt ( echo …
echo …

echo …)

открытие/закрытие файла происходит один раз в отличие от типичного:
Код:

echo …> Out.txt
echo …>> Out.txt

echo …>> Out.txt

Иллюстрация…

0001.cmd
Код:

@echo off
setlocal enableextensions enabledelayedexpansion

echo %time%

>"%~n0.txt" (
        for /l %%i in (1, 1, 10000) do (
                echo %%i
        )
)

echo %time%

endlocal
exit /b 0

0002.cmd
Код:

@echo off
setlocal enableextensions enabledelayedexpansion

echo %time%

for /l %%i in (1, 1, 10000) do (
        >>"%~n0.txt" echo %%i
)

echo %time%

endlocal
exit /b 0

Результат:
Код:

E:\Песочница\0244>0001.cmd
14:10:02.20
14:10:02.56

E:\Песочница\0244>0002.cmd
14:10:05.06
14:10:14.06


m0nkrus 27-04-2013 14:06 2140434

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

Iska 27-04-2013 14:27 2140443

Код:

@echo off
setlocal enableextensions enabledelayedexpansion

cd /d %~dp0

<nul set /p sVar=Загрузочный том размещен на

for /f "tokens=2" %%i in (
        'echo list disk ^| diskpart.exe ^| findstr.exe /r /c:"\*$"'
) do set sDisk=%%i

if defined sDisk (
        (
                echo select disk !sDisk!
                echo detail disk
        ) | diskpart.exe | findstr.exe /e "Boot Загрузоч" >nul && echo GPT-разделе || echo MBR-разделе
) else echo MBR-разделе

endlocal
exit /b 0

Как это будет работать при множественных GPT?

Всё равно мне не нравится такой путь.

m0nkrus 27-04-2013 18:15 2140567

Цитата:

Цитата Iska
Как это будет работать при множественных GPT? »

Хреново будет работать. Переменная sDisk по окончании цикла будет иметь инфу только о последнем GPT-диске из всего списка найденных. Тут массив нужен, а не переменная. Мы его и создаем во внешнем файле. Можно попытаться как-то воспользоваться идеей массива из этого топика: http://forum.oszone.net/post-1886306.html Там, кстати, и ваша благодарность прописана - вы его читали! Или, вот, альтернативная идея написания массива со стороннего сайта:
Код:

@echo off
setlocal enabledelayedexpansion

:: инициализировать 10 переменных вида arr.X случайными числами
for /l %%i in ( 0, 1, 9 ) do (
    set /a arr.%%i=!RANDOM!
)
set arr

endlocal

Я вам уже говорил, временно замените "\*$" на "\ $" и прогоните таким образом скрипт на своих MBR-разделах. Скрипт станет принимать MBR за GPT и наоборот. Если на компе больше одного физического диска, и система стоит не на последнем, то это будет весьма наглядно.

Iska 28-04-2013 05:28 2140926

Цитата:

Цитата m0nkrus
Я вам уже говорил, временно замените "\*$" на "\ $" и прогоните таким образом скрипт на своих MBR-разделах. Скрипт станет принимать MBR за GPT и наоборот. Если на компе больше одного физического диска, и система стоит не на последнем, то это будет весьма наглядно. »

В том-то и дело:

1. Заменил «\*$» на «\ $».
2. Четыре физических диска, два из них в RAID. Логических, соответственно, три. Везде MBR.
3. Операционная система установлена на первом диске в его первом разделе.
4. Запустил код.

Получил следующее:
Цитата:

Загрузочный том размещен на MBR-разделе
А у Вас что получается при такой замене и на таком коде?

m0nkrus, я выше писал, что данный подход мне не нравится. Моя идея (реализацию которой я приводил выше на WSH и PoSH) — «танцевать вперёд», а не «пятится назад»: определить, какой раздел системный, получить его букву, по разделу получить содержащий его диск, и только потом смотреть, каков этот диск — MBR или GPT.

m0nkrus 28-04-2013 07:45 2140937

Цитата:

Цитата Iska
А у Вас что получается при такой замене и на таком коде? »

У меня при такой замене НА МОЕМ КОДЕ получается "Загрузочный том размещен на GPT-разделе". НА ВАШЕМ - то же самое, что и у вас - MBR. Как я уже говорил, переменная sDisk передает инфу только о последнем физическом диске в списке. Большинство людей подключают диск, предназначенный под систему, к порту с наименьшим номером. Ни вы, ни я не исключение. Посему на выдаче sDisk мы получаем не системный диск, а тот, который скорее всего используется под файлопомойку. Как результат, ключ "Boot Загрузоч" на нем не находится и скрипт считает, что системный диск размещен на разделе другого формата.
Цитата:

Цитата Iska
Моя идея (реализацию которой я приводил выше на WSH и PoSH) — «танцевать вперёд», а не «пятится назад»: определить, какой раздел системный, получить его букву, по разделу получить содержащий его диск, и только потом смотреть, каков этот диск — MBR или GPT. »

Объясню, почему я отдаю предпочтение CMD перед PowerShell: с языком CMD я достаточно знаком, чтобы понять, разобрать, найти ошибки и оптимизировать скрипт, в то время как с языком PowerShell я не знаком абсолютно. Вот вы (не в обиду) раз за разом наступаете на одни и те же грабли с переменной в CMD вместо массива - это я могу просечь и пресечь. А если вы мне предложите скрипт на WSH или PoSH с аналогичной или любой другой ошибкой, то я ее уже не смогу распознать! К тому же, я не знаю, корректно ли отработает ваш скрипт, запущенный из SetupComplete.cmd. Недавно, к примеру, столкнулся с тем, что скрипт, помещенный в аналогичный установочный файл oobe.cmd не воспринимает путь "%~dp0" - пришлось городить сложную конструкцию, чтобы определить путь запуска... И как вы себе представляете, что я буду вылавливать подобные проблемы без знания языка и не имея GPT-раздела под рукой? В остальном, согласен, что «танцевать вперёд» - более предпочтительный метод, на реализацию которого, по логике, должно затрачиваться куда меньше ресурсов.

Iska 28-04-2013 10:39 2141019

m0nkrus, вот потому я и предлагаю другой путь — от буквы системного раздела к дисковому устройству (насчёт порта с наименьшим номером — немало раз видел иное: как недосборщику в голову взбредёт — так и будет; в любом случае, обоснованием корректности алгоритма сие не должно служить).

m0nkrus 28-04-2013 11:21 2141030

Цитата:

Цитата Iska
вот потому я и предлагаю другой путь — от буквы системного раздела к дисковому устройству »

Без проблем. Предложите его в CMD-формате и я с удовольствием им воспользуюсь. Если вы не заметили, то топик имеет пометку "CMD/BAT", а отнюдь не "PowerShell" или "Любой язык".
Цитата:

Цитата Iska
насчёт порта с наименьшим номером — немало раз видел иное: как недосборщику в голову взбредёт — так и будет; в любом случае, обоснованием корректности алгоритма сие не должно служить »

А кто обосновывает этим корректность алгоритма? Мой алгоритм работает без привязки к тому, каким по счету идет системный GPT-раздел. А вот предложенный вами алгоритм может сработать только либо в случае наличия всего одного GPT-раздела, либо если система при наличии нескольких таких разделов, находится на последнем в очереди GPT-диске.

Вас уже куда-то не туда заносит, вам не кажется? Уже какие-то наезды непонятные пошли. Если вы не в состоянии понять, почему вариант с массивом работает, а с переменной нет, или почему я не хочу использовать PowerShell-скрипт при наличии альтернативы в виде CMD-скрипта, то это не повод на меня наскакивать.

Iska 28-04-2013 15:01 2141125

Цитата:

Цитата m0nkrus

Мы столько наплодили, что по предыдущему Вашему сообщению:
Цитата:

Цитата m0nkrus
У меня при такой замене НА МОЕМ КОДЕ »

мне было не совсем ясно, о каком коде именно идёт речь. Теперь понятно.

Цитата:

Цитата m0nkrus
…работает без привязки к тому, каким по счету идет системный GPT-раздел. А вот предложенный вами алгоритм может сработать только либо в случае наличия всего одного GPT-раздела, либо если система при наличии нескольких таких разделов, находится на последнем в очереди GPT-диске. »

Принимается.

Цитата:

Цитата m0nkrus
Вас уже куда-то не туда заносит, вам не кажется? Уже какие-то наезды непонятные пошли. Если вы не в состоянии понять, почему вариант с массивом работает, а с переменной нет, или почему я не хочу использовать PowerShell-скрипт при наличии альтернативы в виде CMD-скрипта, то это не повод на меня наскакивать. »

Вам почудилось. Не обижайтесь и не воспринимайте сие в таком ракурсе. Подобного не было. Мне просто тоже было интересно разобраться. Разобрался (см. ниже).


Ваш код у меня не работал. И при использовании «обратки» (смена «\*$» на «\ $») — тоже (кстати, и мой, сделанный по Вашему коду, в этой части — тоже не работал). Суть оказалась в том,
читать дальше »
что «diskpart.exe», идущий в комплекте с Windows XP, делает при перенаправлении вывод строк в формате Unix — не «CtLf», а только «Lf». «findstr.exe», идущий в комплекте с той же ОС, сопоставляет что параметр «/e», что символ «$» в регулярке «/r /c:"$"» только с «CrLf», но не сопоставляет с «Lf». Посему, при использовании параметра или «$», под Windows XP «findstr.exe» находит в выводе «diskpart.exe» одну b исключительно одну подходящую строку — завершающую:
Код:

DISKPART>
да и то лишь потому, что в конце её и вовсе нет никаких символов конца строки.

m0nkrus 28-04-2013 19:25 2141252

Цитата:

Цитата Iska
мне было не совсем ясно, о каком коде именно идёт речь. »

Что этот вариант, что этот, что этот с точки зрения отсутствия привязки к тому, каким по счету идет системный GPT-раздел, работают идентично.

Iska 28-04-2013 21:12 2141322

m0nkrus, ну, так мне до этого нужно было ещё «дойти» ;).

ITDemon 30-04-2013 01:00 2142006

На загрузочных GPT-дисках обязательно присутствует EFI в качестве 1-го системного раздела и MSR для 2-го. Информация об этом дается командой list partition. Поэтому принадлежность диска к GPT легко определить по типам раздела на диске.

Ксеноинженер 30-04-2013 02:13 2142026

m0nkrus, Iska, ITDemon, всё гениальное просто! Если не ошибаюсь, каждая копия Windows считает место хранения своего загрузочного тома не иначе как "диском 0", Вы проверьте :) Если загрузочный том всегда на диске 0, то:
Код:

@echo off
CD /d %~dp0
echo Select Disk 0 >> diskpart.txt && echo detail disk >> diskpart.txt
Diskpart /s diskpart.txt | Findstr /c:"{"
IF ERRORLEVEL 1 (
        ECHO Загрузочный том размещен на MBR-диске
        ) ELSE (
        ECHO Загрузочный том размещен на GPT-диске
        )
del /q diskpart.txt
pause

Ключ логики - имеет ли "диск 0" GUID вида {...} (GPT), или ИД Диска 0 имеет другой вид (MBR).
На MBR WinXP и GPT Win8 проверил - работает корректно, подозреваю на остальных версиях тоже ;)

Iska 30-04-2013 03:17 2142037

Ксеноинженер, сейчас проверить уже не могу: под рукой не осталось машин, где ОС была бы установлена не на первый накопитель. Тем более — с GPT ;).

m0nkrus 03-05-2013 14:12 2143696

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

Хоть я и не могу сказать, работает ли ваша конструкция, но оптимизировать код, избавившись от внешнего файла, думаю, смогу. Ваше:
Код:

echo Select Disk 0 >> diskpart.txt && echo detail disk >> diskpart.txt
Diskpart /s diskpart.txt | Findstr /c:"{"

Замена:
Код:

((echo select disk 0 && echo detail disk) ^| diskpart.exe) | findstr /c:"{"

Ксеноинженер 03-05-2013 19:08 2143844

Добавил вывод ИД диска, для наглядности принятия решения скриптом.
Код:

@echo off
CD /d %~dp0
((echo select disk 0 && echo detail disk) ^| diskpart.exe) | findstr /c:"ИД диска" & ((echo select disk 0 && echo detail disk) ^| diskpart.exe) | findstr /c:"{">nul
IF ERRORLEVEL 1 (
        ECHO Загрузочный том размещён на MBR-диске
        ) ELSE (
        ECHO Загрузочный том размещён на GPT-диске
        )
pause

Взять к примеру "тяжёлый случай", когда загрузчик на одном диске, а Windows на другом. Ведь для работы скрипта это не важно: Логический диск "с букавкай С:" может быть на диске 0,1, 2, 3, 4... . Пусть будет!
Тем не менее, место хранения Загрузчика ОС есть Диск 0 всегда! В противном случае данная копия Windows "не загружабельна" без правки:
любого имеющегося на Диске 0 загрузчика или BIOS, если загрузчика, на Диске 0, нет.
Какой из SATA портов будет Диском 0 определяет первая строка в "Boot Sequence" в BIOS.
Чтива полно на "железных" конференциях forum.oszone.net, ixbt.com.

m0nkrus, оптимизация хороша, пригодится и для других задач тоже!

m0nkrus 03-05-2013 19:45 2143875

Ксеноинженер, вот честно, не могу с уверенностью сказать, что мне нужно найти, где находится системный диск (скрытая 100-метровка) или загрузочный диск (диск С). Для первого случая ваш вариант подходит, для второго - не факт. Тут нужно тестировать, тестировать и еще раз тестировать. А не на чем...

Идея такой комплектации команд изначально не моя, а Iska.

Ксеноинженер 05-05-2013 22:29 2145038

Цитата:

Цитата m0nkrus
Тут нужно тестировать, тестировать и еще раз тестировать. А не на чем... »

Что ж, VMWare или VirtualBox в помощь. В EFI режиме с загрузочным GPT диском обе работают, в отличие от Hyper-V.

m0nkrus 05-05-2013 22:36 2145045

Ксеноинженер, я пробовал запустить установку винды на VirtualBox в UEFI-режиме - хрен вам!..

Ксеноинженер 06-05-2013 00:25 2145096

m0nkrus, действительно, не стоит с VirualBox связываться, ведь конкурент субъективно стабильнее. Моя тестовая платформа "GPT EFI Boot":
  1. Установил VMWare Player . Создал новую машину.
  2. Добавил в конфигурацию *.vmx машины строку блокнотом.
    Код:

    firmware = "efi"
  3. Включил машину, загрузился с MSDN образа, установил Windows.
Для копирования скрипта на виртуальную машину может пригодиться Утилита монтирования *.vmdk образов

Ксеноинженер 06-05-2013 15:13 2145345

Цитата:

Зачем вам сейчас вдруг понадобилось таким "оригинальным" способом самоутверждаться, мне совершенно непонятно.
Действительно, топик не место для этого. Прошу прощения за своё ребячество.

Однако,
m0nkrus, как можно, не тестируя, серьёзно говорить про работу скрипта в предложенных Вами экзотичных вариантах системы?
Краткая схема моих тестов:
  1. BIOS
    диск 0 MBR, "Системный раздел"
    диск N GPT, "Загрузочный раздел", Цель установки
  2. EFI
    диск 0 GPT, "Системный раздел"
    диск N MBR, "Загрузочный раздел", Цель установки
где N =1,2,3...

Результат: В обоих случаях после стандартной установки и диск 0 под "Системным разделом" и диск N под "Загрузочным разделом" имеют один и тот же формат. Подозреваю, установщик Windows конвертирует чистый Диск 0 в формат диска под загрузочным разделом, выбранным во время установки, А если Диск 0 занят, то ошибка установки.
Вывод: в "загружабельных" системах тип диска 0 и тип диска N под загрузочным разделом один и тот же, всегда.
Какие ещё вопросы по теме топика? На практике наш с вами скрипт исправно работает, пусть и по косвенному признаку: ID Диска 0.

m0nkrus 07-05-2013 01:30 2145776

Цитата:

Цитата Ксеноинженер
Вывод: в "загружабельных" системах тип диска 0 и тип диска N под загрузочным разделом один и тот же, всегда. »

Поверьте моему богатому опыту - не всегда. Иначе я бы не зацикливался так на этом.

Ксеноинженер 30-05-2013 23:59 2159630

Цитата:

Цитата m0nkrus
Поверьте моему богатому опыту - не всегда. »

Верю и проверил.
Действительно схема нумерации дисков установщика Windows не привязана к BIOS и к номеру SATA порта.
Сама MS здесь лукавит:
when you install Windows Server 2012, Windows Server 2008 R2, Windows 8, or Windows 7, the installation creates a system partition alongside the Windows partition by default. The system partition is created to accommodate a Bitlocker requirement. Bitlocker requires that the boot files and Windows files are located on separate partitions. If the preselected default hard disk is not changed, the system partition is created on the disk that is detected as Disk 0.
http://support.microsoft.com/kb/937251
http://support.microsoft.com/kb/937252
Пока это так, устанавливать ОС в MBR-системе на один из двух физ.дисков - играть в угадай-Ку.
В MBR системе одно можно сделать с уверенностью -- на время установки ОС стОит отключать в BIOS/физически SATA-порты со всеми ПЗУ, кроме "системного"; вот тогда и скрипт будет работать исправно.
В EFI системе такая привязка нумерации дисков к ОС Есть, и в случае установки ПервойОС на диск 0 всё чётко при любом количестве физ. дисков. Но тем не менее в EFI при установке ВторойОС на диск 1-N (первая на диске 0) рекомендую тоже отключать все ПЗУ, кроме "системного", (целиком логические диски не в счёт). Почему рекомендую? Да очень просто, чтобы загрузиться с первой или второй системы, достаточно будет сменить последовательность дисков в BIOS/EFI. Без шаманства с bootsect.

В общем-то, привести в порядок свои диски в BIOS/EFI и устанавливать систему всегда на диск 0 - это элементарные правила!

P.S. Правила есть в любой игре. ;)

m0nkrus 01-06-2013 21:56 2160558

Ксеноинженер, предпочитаю скрипт, работающий всегда над скриптом, работающим по правилам.

AnTaL 10-06-2013 12:46 2165281

Iska, m0nkrus,

а вы не пробовали для поиска системного диска применить DISKPART с параметром SEL DISK SYSTEM,
а потом проверить GPT ?

Iska 10-06-2013 13:51 2165303

AnTaL, не пробовал. Свой вариант определения, который считаю наиболее корректным и универсальным, я озвучивал выше в #9 и в #11. У автора же достаточно специфичные требования на ТЗ, он нашёл свой вариант решения, вполне рабочий и, главное — его самого более чем устраивающий.

m0nkrus 11-06-2013 11:39 2165768

AnTaL, тут есть нюанс. Из справки по этой команде:
Цитата:

На компьютерах с BIOS фокус получает диск с номером 0 в BIOS.
На компьютерах с EFI фокус получает диск, содержащий раздел
ESP, используемый для текущей загрузки.
На компьютерах с EFI, если ESP отсутствует, есть несколько ESP
или компьютер загружается из среды предустановки Windows,
команда завершится сбоем.

Albatross 13-11-2013 10:57 2253495

Цитата:

Цитата m0nkrus
Нужно получить данные, какой формат имеет диск С, MBR или GPT и исходя из этой инфы задать флаговую переменную как 0 или 1. »


m0nkrus 13-11-2013 11:24 2253513

Albatross, родной, ты так, на секундочку, посмотри, в каком подфоруме ты пишешь...


Время: 02:06.

Время: 02:06.
© OSzone.net 2001-