多くのリソースを exeに追加したい。いくつかのリソースに対してのみ、この方法で実行できることに気付きました。
// BeginUpdate();
// for (int i = 0; i < count; i++)
// UpdateResource();
// EndUpdate();
WinApiにバグか何かがあるらしいので。私は今、このようにしようとしています:
// for (int i = 0; i < count; i++)
// {
// BeginUpdate();
// UpdateResource();
// EndUpdate();
// }
しかし、もちろんそうはなりません。は、エラー コード 5 (アクセスが拒否されました) および 110 (指定されたデバイスまたはファイルを開けませんGetLastError()
) を返すことがあります。一部のリソースで機能し、エラー 110 がグループで発生します。また、エラー 5 だけが表示されることもあります。これらのエラーを回避するにはどうすればよいですか? 1000 以上のリソースを追加する必要があり、関数は完全に成功するか失敗するかのいずれかでなければなりません。その間には何もありません。
これは、ランダムな文字列を追加するだけの私の関数です:
[DllImport("kernel32.dll")]
public static extern uint GetLastError();
[DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
public static extern IntPtr BeginUpdateResource([MarshalAs(UnmanagedType.LPStr)] string filename, bool deleteExistingResources);
[DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
public static extern bool UpdateResource(IntPtr resource, [MarshalAs(UnmanagedType.LPStr)] string type, [MarshalAs(UnmanagedType.LPStr)] string name, ushort language, IntPtr data, uint dataSize);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool EndUpdateResource(IntPtr resource, bool discardChanges);
private static void addResources(string filename, int count)
{
// 1. delete existing resources
IntPtr handle = BeginUpdateResource(filename, true);
Console.WriteLine(EndUpdateResource(handle, false));
// 2. add resources
for (int i = 0; i < count; i++)
{
handle = BeginUpdateResource(filename, false);
string text = Utils.randomString(16);
if (!UpdateResource(handle, "TEST", "" + i, 0, Marshal.StringToHGlobalAnsi(text), (uint) text.Length))
Console.WriteLine("update error: " + GetLastError() + ", " + i);
if (!EndUpdateResource(handle, false))
Console.WriteLine("endupdate error: " + GetLastError() + ", " + i);
}
}