public bool UpdateResources(string filename, BuildResults results) { bool returnValue = true; int beginUpdateRetries = 20; // Number of retries const int beginUpdateRetryInterval = 100; // In milliseconds bool endUpdate = false; // Only call EndUpdateResource() if this is true // Directory.GetCurrentDirectory() has previously been set to the project location string filePath = System.IO.Path.Combine(Directory.GetCurrentDirectory(), filename); if (_stringResources.Count == 0 && _fileResources.Count == 0) { return(true); } IntPtr hUpdate = IntPtr.Zero; try { hUpdate = NativeMethods.BeginUpdateResourceW(filePath, false); while (IntPtr.Zero == hUpdate && Marshal.GetHRForLastWin32Error() == ResourceUpdater.ERROR_SHARING_VIOLATION && beginUpdateRetries > 0) // If it equals 0x80070020 (ERROR_SHARING_VIOLATION), sleep & retry { // This warning can be useful for debugging, but shouldn't be displayed to an actual user // results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Warning, "GenerateBootstrapper.General", String.Format("Unable to begin updating resource for {0} with error {1:X}, trying again after short sleep", filename, Marshal.GetHRForLastWin32Error()))); hUpdate = NativeMethods.BeginUpdateResourceW(filePath, false); beginUpdateRetries--; Thread.Sleep(beginUpdateRetryInterval); } // If after all that we still failed, throw a build error if (IntPtr.Zero == hUpdate) { results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", String.Format("Unable to begin updating resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error()))); return(false); } endUpdate = true; if (hUpdate != IntPtr.Zero) { foreach (StringResource resource in _stringResources) { byte[] data = StringToByteArray(resource.Data); if (!NativeMethods.UpdateResourceW(hUpdate, (IntPtr)resource.Type, resource.Name, 0, data, data.Length)) { results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", String.Format("Unable to update resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error()))); return(false); } } if (_fileResources.Count > 0) { int index = 0; byte[] countArray = StringToByteArray(_fileResources.Count.ToString("G", CultureInfo.InvariantCulture)); if (!NativeMethods.UpdateResourceW(hUpdate, (IntPtr)42, "COUNT", 0, countArray, countArray.Length)) { results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", String.Format("Unable to update count resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error()))); return(false); } foreach (FileResource resource in _fileResources) { // Read in the file data int fileLength = 0; byte[] fileContent = null; using (FileStream fs = System.IO.File.OpenRead(resource.Filename)) { fileLength = (int)fs.Length; fileContent = new byte[fileLength]; fs.Read(fileContent, 0, fileLength); } // Update the resources to include this file's data string dataName = string.Format(CultureInfo.InvariantCulture, "FILEDATA{0}", index); if (!NativeMethods.UpdateResourceW(hUpdate, (IntPtr)42, dataName, 0, fileContent, fileLength)) { results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", String.Format("Unable to update data resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error()))); return(false); } // Add this file's key to the resources string keyName = string.Format(CultureInfo.InvariantCulture, "FILEKEY{0}", index); byte[] data = StringToByteArray(resource.Key); if (!NativeMethods.UpdateResourceW(hUpdate, (IntPtr)42, keyName, 0, data, data.Length)) { results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", String.Format("Unable to update key resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error()))); return(false); } index++; } } } } finally { if (endUpdate && !NativeMethods.EndUpdateResource(hUpdate, false)) { results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", String.Format("Unable to finish updating resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error()))); returnValue = false; } } return(returnValue); }
internal void AddMessage(BuildMessage message) { this.messages.Add(message); }
internal void AddMessage(BuildMessage message) { this.messages.Add(message); }
public bool UpdateResources(string filename, BuildResults results) { bool flag = true; int num = 20; bool flag2 = false; if ((this.stringResources.Count == 0) && (this.fileResources.Count == 0)) { return(true); } IntPtr zero = IntPtr.Zero; try { zero = Microsoft.Build.Tasks.Deployment.Bootstrapper.NativeMethods.BeginUpdateResourceW(filename, false); while (((IntPtr.Zero == zero) && (Marshal.GetHRForLastWin32Error() == -2147024864)) && (num > 0)) { zero = Microsoft.Build.Tasks.Deployment.Bootstrapper.NativeMethods.BeginUpdateResourceW(filename, false); num--; Thread.Sleep(100); } if (IntPtr.Zero == zero) { results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", new object[] { string.Format("Unable to begin updating resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error()) })); return(false); } flag2 = true; if (!(zero != IntPtr.Zero)) { return(flag); } foreach (StringResource resource in this.stringResources) { byte[] buffer = this.StringToByteArray(resource.Data); if (!Microsoft.Build.Tasks.Deployment.Bootstrapper.NativeMethods.UpdateResourceW(zero, (IntPtr)resource.Type, resource.Name, 0, buffer, buffer.Length)) { results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", new object[] { string.Format("Unable to update resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error()) })); return(false); } } if (this.fileResources.Count <= 0) { return(flag); } int num2 = 0; byte[] data = this.StringToByteArray(this.fileResources.Count.ToString("G", CultureInfo.InvariantCulture)); if (!Microsoft.Build.Tasks.Deployment.Bootstrapper.NativeMethods.UpdateResourceW(zero, (IntPtr)0x2a, "COUNT", 0, data, data.Length)) { results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", new object[] { string.Format("Unable to update count resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error()) })); return(false); } foreach (FileResource resource2 in this.fileResources) { int count = 0; byte[] buffer3 = null; using (FileStream stream = File.OpenRead(resource2.Filename)) { count = (int)stream.Length; buffer3 = new byte[count]; stream.Read(buffer3, 0, count); } string lpName = string.Format(CultureInfo.InvariantCulture, "FILEDATA{0}", new object[] { num2 }); if (!Microsoft.Build.Tasks.Deployment.Bootstrapper.NativeMethods.UpdateResourceW(zero, (IntPtr)0x2a, lpName, 0, buffer3, count)) { results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", new object[] { string.Format("Unable to update data resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error()) })); return(false); } string str2 = string.Format(CultureInfo.InvariantCulture, "FILEKEY{0}", new object[] { num2 }); byte[] buffer4 = this.StringToByteArray(resource2.Key); if (!Microsoft.Build.Tasks.Deployment.Bootstrapper.NativeMethods.UpdateResourceW(zero, (IntPtr)0x2a, str2, 0, buffer4, buffer4.Length)) { results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", new object[] { string.Format("Unable to update key resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error()) })); return(false); } num2++; } } finally { if (flag2 && !Microsoft.Build.Tasks.Deployment.Bootstrapper.NativeMethods.EndUpdateResource(zero, false)) { results.AddMessage(BuildMessage.CreateMessage(BuildMessageSeverity.Error, "GenerateBootstrapper.General", new object[] { string.Format("Unable to finish updating resource for {0} with error {1:X}", filename, Marshal.GetHRForLastWin32Error()) })); flag = false; } } return(flag); }