Почему мой скрипт не работает с первой попытки запустить OOBE (но работает на второй)?
У меня есть скрипт, который использует код C# в powershell для установки разрешения экрана и ориентации для устройств, для которых я разрабатываю образ Windows.
По разным причинам, главным образом связанным с ориентацией экрана, я предпочитаю не использовать настройки в моем файле unattend.xml.
После установки образа на любом из целевых устройств, когда я загружаю устройство и позволяю OOBE завершить работу с использованием моего файла ответов unattend.xml, мой скрипт запускается, но возвращает результат, указывающий, что он не смог обработать мой запрос.
Если я тогда возьму готовый модуль и запустлю на нем sysprep, чтобы настроить его на повторное выполнение OOBE, сценарий завершится успешно при втором запуске.
С чего бы это?
Вот код для сценария powershell/C#.
using System;
using System.Runtime.InteropServices;
namespace Resolution
{
[StructLayout(LayoutKind.Sequential)]
public struct DEVMODE
{
[MarshalAs(UnmanagedType.ByValTStr,SizeConst=32)]
public string dmDeviceName;
public short dmSpecVersion;
public short dmDriverVersion;
public short dmSize;
public short dmDriverExtra;
public int dmFields;
public int dmPositionX;
public int dmPositionY;
public int dmDisplayOrientation;
public int dmDisplayFixedOutput;
public short dmColor;
public short dmDuplex;
public short dmYResolution;
public short dmTTOption;
public short dmCollate;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string dmFormName;
public short dmLogPixels;
public short dmBitsPerPel;
public int dmPelsWidth;
public int dmPelsHeight;
public int dmDisplayFlags;
public int dmDisplayFrequency;
public int dmICMMethod;
public int dmICMIntent;
public int dmMediaType;
public int dmDitherType;
public int dmReserved1;
public int dmReserved2;
public int dmPanningWidth;
public int dmPanningHeight;
};
class NativeMethods
{
[DllImport("user32.dll")]
public static extern int EnumDisplaySettings(string deviceName, int modeNum, ref DEVMODE devMode);
[DllImport("user32.dll")]
public static extern int ChangeDisplaySettings(ref DEVMODE devMode, int flags);
public const int ENUM_CURRENT_SETTINGS = -1;
public const int CDS_UPDATEREGISTRY = 0x01;
public const int CDS_TEST = 0x02;
public const int DISP_CHANGE_SUCCESSFUL = 0;
public const int DISP_CHANGE_RESTART = 1;
public const int DISP_CHANGE_FAILED = -1;
public const int DISP_CHANGE_BADMODE = -2;
public const int DISP_CHANGE_NOTUPDATED = -3;
public const int DISP_CHANGE_BADFLAGS = -4;
public const int DISP_CHANGE_BADPARAM = -5;
public const int DISP_CHANGE_BADDUALVIEW = -6;
public const int DMDO_DEFAULT = 0;
public const int DMDO_90 = 1;
public const int DMDO_180 = 2;
public const int DMDO_270 = 3;
}
public class PrmaryScreenResolution
{
static public string SetDevAResolution() //Landscape oriented device
{
return ChangeResolution(1024, 768, NativeMethods.DMDO_DEFAULT);
}
static public string SetDevBResolution() //High resolution portrait device
{
return ChangeResolution(800, 1280, NativeMethods.DMDO_90);
}
static public string SetDevCResolution() //Portrait oriented device
{
return ChangeResolution(768, 1024, NativeMethods.DMDO_90);
}
static public string ChangeResolution(int width, int height, int orientation)
{
DEVMODE dm = GetDevMode();
if (0 != NativeMethods.EnumDisplaySettings(null, NativeMethods.ENUM_CURRENT_SETTINGS, ref dm))
{
// Set Width and heigh
dm.dmPelsHeight = height;
dm.dmPelsWidth = width;
//dm.dmLogPixels = 96;
dm.dmDisplayOrientation = orientation;
int iRet = NativeMethods.ChangeDisplaySettings(ref dm, NativeMethods.CDS_TEST);
if (iRet == NativeMethods.DISP_CHANGE_FAILED)
{
return "Unable To Process Your Request. Sorry For This Inconvenience.";
}
else
{
iRet = NativeMethods.ChangeDisplaySettings(ref dm, NativeMethods.CDS_UPDATEREGISTRY);
switch (iRet)
{
case NativeMethods.DISP_CHANGE_SUCCESSFUL:
{
return "Success";
}
case NativeMethods.DISP_CHANGE_RESTART:
{
return "You Need To Reboot For The Change To Happen.\n If You Feel Any Problem After Rebooting Your Machine\nThen Try To Change Resolution In Safe Mode.";
}
case NativeMethods.DISP_CHANGE_FAILED:
{
return "Display change failed.";
}
case NativeMethods.DISP_CHANGE_BADMODE:
{
return "Bad Mode";
}
case NativeMethods.DISP_CHANGE_NOTUPDATED:
{
return "Display not updated.";
}
case NativeMethods.DISP_CHANGE_BADFLAGS:
{
return "Bad Flags";
}
case NativeMethods.DISP_CHANGE_BADPARAM:
{
return "Bad Parameter";
}
case NativeMethods.DISP_CHANGE_BADDUALVIEW:
{
return "Bad Dual View";
}
default:
{
return "Failed To Change The Resolution (B)";
}
}
}
}
else
{
return "Failed To Change The Resolution. (A)";
}
}
private static DEVMODE GetDevMode()
{
DEVMODE dm = new DEVMODE();
dm.dmDeviceName = new String(new char[32]);
dm.dmFormName = new String(new char[32]);
dm.dmSize = (short)Marshal.SizeOf(dm);
return dm;
}
}
}
При первом запуске сценария (во время попытки 1 OOBE) я выполняю одну из функций SetDev*Resolution(), и функция "ChangeResolution()" возвращает: "Невозможно обработать ваш запрос. Приносим извинения за это неудобство". Это говорит мне, что когда я попытался вызвать "ChangeDisplaySettings()", это не удалось.
Может ли это быть как-то связано с отсутствием пользователя при запуске этого скрипта? Если это так, есть ли обходной путь, или мне нужно найти другой метод?