PowerShell で C# コードを使用して、Windows イメージを開発しているデバイスの画面解像度と向きを設定するスクリプトがあります。
主に画面の向きに関連するさまざまな理由により、unattend.xml の設定を使用しないことを選択しています。
いずれかのターゲット デバイスにイメージをインストールした後、デバイスを起動し、unattend.xml 応答ファイルを使用して OOBE を完了させると、スクリプトは実行されますが、要求を処理できなかったことを示す結果が返されます。
その後、完成したユニットを取得して sysprep を実行し、OOBE を再度実行するように設定すると、スクリプトは 2 回目の実行で成功します。
なぜそうなるのでしょうか?
以下は 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;
}
}
}
スクリプトを初めて実行したとき (OOBE 試行 1 中)、SetDev*Resolution() 関数の 1 つを実行すると、"ChangeResolution()" 関数は "要求を処理できません。ご不便をおかけして申し訳ございません。" を返します。これは、"ChangeDisplaySettings()" を呼び出そうとしたときに失敗したことを示しています。
このスクリプトの実行時にユーザーがいないことと関係があるのでしょうか? その場合、回避策はありますか、それとも別の方法を見つける必要がありますか?