private object GetUniqueEnumValueForProperty(TestDriverCodePack.ShellPropertyDescription propDesc, ref bool[] used) { if (propDesc.PropertyEnumTypes != null && propDesc.PropertyEnumTypes.Count > 0) { if (used == null) { used = new bool[propDesc.PropertyEnumTypes.Count]; } // Ensure that each choice is different - some enums are flags, and insist on unique values int usedSoFar = used.Where(f => f == true).Count(); int index = RandomNumber(propDesc.PropertyEnumTypes.Count - 1 - usedSoFar); index += used.Take(index + 1).Where(f => f == true).Count(); while (used[index]) { index++; } used[index] = true; // Now work out what string to use from the seleccted enum entry return(GetValueForEnumType(propDesc.PropertyEnumTypes[index])); } return(null); }
private object GetEnumValueForProperty(TestDriverCodePack.ShellPropertyDescription propDesc) { if (propDesc.PropertyEnumTypes != null && propDesc.PropertyEnumTypes.Count > 0) { int index = RandomNumber(propDesc.PropertyEnumTypes.Count - 1); // Now work out what value to use from the seleccted enum entry return(GetValueForEnumType(propDesc.PropertyEnumTypes[index])); } return(null); }
private string[] GetStringArrayValueForProperty(TestDriverCodePack.ShellPropertyDescription propDesc) { int n = random.Next(2, 5); string[] ss = new string[n]; bool[] used = null; for (int i = 0; i < n; i++) { object obj = GetUniqueEnumValueForProperty(propDesc, ref used); if (obj != null) { ss[i] = (string)obj; } else { ss[i] = RandomString(); } } return(ss); }
private void SetPropertyValue(string fileName, TestDriverCodePack.ShellPropertyDescription propDesc, IShellProperty prop) { Type t = propDesc.ValueType; string s; try { if (t == typeof(string)) { object obj = GetEnumValueForProperty(propDesc); if (obj != null) { s = (string)obj; } else { s = RandomString(); } savedProps.Add(new SavedProp { Name = prop.CanonicalName, Value = s }); //(prop as ShellProperty<string>).Value = s; // Workaround Code Pack bug with 1 char strings by using PropertyHandler // Have to open and release each time to avoid lock problems - still, it ups the pounding var handler = new CPropertyHandler(); handler.Initialize(fileName, 0); PropVariant value = new PropVariant(s); handler.SetValue(new TestDriverCodePack.PropertyKey(prop.PropertyKey.FormatId, prop.PropertyKey.PropertyId), value); handler.Commit(); Marshal.ReleaseComObject(handler); // preempt GC for CCW } else if (t == typeof(string[])) { string[] ss = GetStringArrayValueForProperty(propDesc); savedProps.Add(new SavedProp { Name = prop.CanonicalName, Value = ss }); //(prop as ShellProperty<string[]>).Value = ss; // Workaround Code Pack bug with 1 char strings by using PropertyHandler // Have to open and release each time to avoid lock problems - still, it ups the pounding var handler = new CPropertyHandler(); handler.Initialize(fileName, 0); PropVariant value = new PropVariant(ss); handler.SetValue(new TestDriverCodePack.PropertyKey(prop.PropertyKey.FormatId, prop.PropertyKey.PropertyId), value); handler.Commit(); Marshal.ReleaseComObject(handler); // preempt GC for CCW } else if (t == typeof(Int16?) || t == typeof(Int32?) || t == typeof(UInt16?) || t == typeof(UInt32?)) { object obj = GetEnumValueForProperty(propDesc); if (t == typeof(Int16?)) { Int16?val = obj != null ? (Int16?)obj : (Int16?)NullableRandomNumber(-max16, max16); savedProps.Add(new SavedProp { Name = prop.CanonicalName, Value = val }); (prop as ShellProperty <Int16?>).Value = val; } else if (t == typeof(Int32?)) { Int32?val = obj != null ? (Int32?)obj : (Int32?)NullableRandomNumber(-max32, max32); savedProps.Add(new SavedProp { Name = prop.CanonicalName, Value = val }); (prop as ShellProperty <Int32?>).Value = val; } else if (t == typeof(UInt16?)) { UInt16?val = obj != null ? (UInt16?)obj : (UInt16?)NullableRandomNumber(max16); savedProps.Add(new SavedProp { Name = prop.CanonicalName, Value = val }); (prop as ShellProperty <UInt16?>).Value = val; } else // UInt32? { UInt32?val = obj != null ? (UInt32?)obj : (UInt32?)NullableRandomNumber(max16); savedProps.Add(new SavedProp { Name = prop.CanonicalName, Value = val }); (prop as ShellProperty <UInt32?>).Value = val; } } else if (t == typeof(Int32[])) { Int32[] vals = new Int32[4]; for (int i = 0; i < 4; i++) { vals[i] = RandomNumber(-max32, max32); } savedProps.Add(new SavedProp { Name = prop.CanonicalName, Value = vals }); (prop as ShellProperty <Int32[]>).Value = vals; } else if (t == typeof(UInt32[])) { UInt32[] vals = new UInt32[4]; for (int i = 0; i < 4; i++) { vals[i] = (UInt32)RandomNumber(max32); } savedProps.Add(new SavedProp { Name = prop.CanonicalName, Value = vals }); (prop as ShellProperty <UInt32[]>).Value = vals; } else if (t == typeof(bool?)) { int? r = NullableRandomNumber(); bool?value = (r == null) ? (bool?)null : (r % 2 == 0); savedProps.Add(new SavedProp { Name = prop.CanonicalName, Value = value }); (prop as ShellProperty <bool?>).Value = value; } else if (t == typeof(DateTime?)) { DateTime dt = new DateTime((long)(random.NextDouble() * (maxTocks - minTicks) + minTicks)); savedProps.Add(new SavedProp { Name = prop.CanonicalName, Value = dt }); (prop as ShellProperty <DateTime?>).Value = dt; } else if (t == typeof(double?)) { // fails in Code Pack, so skip //(prop as ShellProperty<double>).Value = (double)RandomNumber(max64); } else if (t == typeof(Int64?)) { // fails in Code Pack, so skip //(prop as ShellProperty<Int64>).Value = RandomNumber(max64); } else if (t == typeof(UInt64?)) { // fails in Code Pack, so skip // (prop as ShellProperty<UInt64>).Value = (UInt64) RandomNumber(max64); } else if (t == typeof(byte?)) { // The Code Pack does not support setting these, so skip for now //(prop as ShellProperty<byte>).Value = (byte)RandomNumber(max8); } else if (t == typeof(byte[])) { // The Code Pack does not support setting these, so skip for now // Mostly 128 byte arrays e.g. System.Photo.MakerNote //byte[] bs = new byte[128]; //random.NextBytes(bs); //(prop as ShellProperty<byte[]>).Value = bs; } else if (t == typeof(object) || t == typeof(IntPtr?) || t == typeof(System.Runtime.InteropServices.ComTypes.IStream)) { // ignore these, they are system artefacts like group header props, and don't appear in settable lists } else { throw new System.Exception("Need " + t.ToString() + " for " + propDesc.CanonicalName); } } catch (System.Exception e) { throw new System.Exception(String.Format("Error setting property {0} to '{1}'", savedProps.Last().Name, ToDisplayString(savedProps.Last().Value)), e); } }