public static void ReadCache(ArrayList alAssems, String name, uint nFlag) { IAssemblyEnum aEnum = null; IApplicationContext AppCtx = null; IAssemblyName aName = null; IAssemblyName pNameEnum = null; int hr; if (name != null) { hr = CreateAssemblyNameObject(out pNameEnum, name, CANOF.PARSE_DISPLAY_NAME, 0); if (hr != 0) { return; } } hr = CreateAssemblyEnum(out aEnum, null, pNameEnum, nFlag, 0); while (hr == 0) { hr = aEnum.GetNextAssembly(out AppCtx, out aName, 0); if (hr == 0) { uint iLen = 0; IntPtr pDisplayName = (IntPtr)0; // Get the length of the string we need aName.GetDisplayName((IntPtr)0, ref iLen, 0); if (iLen > 0) { // Do some yucky memory allocating here // We need to assume that a wide character is 2 bytes. pDisplayName = Marshal.AllocHGlobal(((int)iLen + 1) * 2); aName.GetDisplayName(pDisplayName, ref iLen, 0); String sDisplayName = Marshal.PtrToStringUni(pDisplayName); Marshal.FreeHGlobal(pDisplayName); // Our info is in a comma seperated list. Let's pull it out String[] sFields = sDisplayName.Split(new char[] { ',' }); AssemblyInformation newguy = new AssemblyInformation(); newguy.FullName = sDisplayName; newguy.Name = sFields[0]; // The version string is represented as Version=###### // Let's take out the 'Version=' newguy.Version = sFields[1].Substring(sFields[1].IndexOf('=') + 1); // Same goes for the locale newguy.Locale = sFields[2].Substring(sFields[2].IndexOf('=') + 1); // And the key token sFields[3] = sFields[3].Substring(sFields[3].IndexOf('=') + 1); if (sFields[3].Equals("null")) { sFields[3] = "null"; } newguy.PublicKeyToken = sFields[3]; alAssems.Add(newguy); } } } }
/// <summary> /// Gets the names of all assemblies in the GAC. /// </summary> public static IEnumerable <AssemblyNameInfo> GetGacAssemblyFullNames() { IApplicationContext applicationContext = null; IAssemblyEnum assemblyEnum = null; IAssemblyName assemblyName = null; Fusion.CreateAssemblyEnum(out assemblyEnum, null, null, 2, 0); while (assemblyEnum.GetNextAssembly(out applicationContext, out assemblyName, 0) == 0) { uint nChars = 0; assemblyName.GetDisplayName(null, ref nChars, 0); StringBuilder name = new StringBuilder((int)nChars); assemblyName.GetDisplayName(name, ref nChars, 0); AssemblyNameInfo r = null; try { r = new AssemblyNameInfo(name.ToString()); } catch (ArgumentException) { } catch (FormatException) { } catch (OverflowException) { } if (r != null) { yield return(r); } } }
internal static unsafe string GetDisplayName(IAssemblyName nameObject, ASM_DISPLAYF displayFlags) { int hr; uint characterCountIncludingTerminator = 0; hr = nameObject.GetDisplayName(null, ref characterCountIncludingTerminator, displayFlags); if (hr == 0) { return(String.Empty); } if (hr != ERROR_INSUFFICIENT_BUFFER) { throw Marshal.GetExceptionForHR(hr); } byte[] data = new byte[(int)characterCountIncludingTerminator * 2]; fixed(byte *p = data) { hr = nameObject.GetDisplayName(p, ref characterCountIncludingTerminator, displayFlags); if (hr != 0) { throw Marshal.GetExceptionForHR(hr); } return(Marshal.PtrToStringUni((IntPtr)p, (int)characterCountIncludingTerminator - 1)); } }
/// <summary> /// Initializes a new instance of the <see cref="AssemblyDescription"/> class. /// </summary> /// <param name="assemblyName">Name of the assembly.</param> public AssemblyDescription(IAssemblyName assemblyName) { if (assemblyName == null) { return; } // Get the qualified name. var stringBuilder = new StringBuilder(10000); var iLen = 10000; var hr = assemblyName.GetDisplayName(stringBuilder, ref iLen, ASM_DISPLAY_FLAGS.ASM_DISPLAYF_VERSION | ASM_DISPLAY_FLAGS.ASM_DISPLAYF_CULTURE | ASM_DISPLAY_FLAGS.ASM_DISPLAYF_PUBLIC_KEY_TOKEN | ASM_DISPLAY_FLAGS.ASM_DISPLAYF_PROCESSORARCHITECTURE); if (hr < 0) { Marshal.ThrowExceptionForHR(hr); } var displayName = stringBuilder.ToString(); // Load properties from the display name. LoadPropertiesFromDisplayName(displayName); // We have the assembly name, so we can use the optimised version to load the fusion properties. _lazyFusionProperties = new Lazy <AssemblyFusionProperties>(DoLoadFusionProperties); _lazyReflectionProperties = new Lazy <AssemblyReflectionProperties>(DoLoadReflectionProperties); }
static String GetDisplayName(IAssemblyName name, ASM_DISPLAY_FLAGS which) { uint bufferSize = 255; StringBuilder buffer = new StringBuilder((int)bufferSize); name.GetDisplayName(buffer, ref bufferSize, which); return(buffer.ToString()); }
private static string GetDisplayName(this IAssemblyName name, DisplayNameFlags which) { uint bufferSize = 255; var buffer = new StringBuilder((int)bufferSize); name.GetDisplayName(buffer, ref bufferSize, which); return(buffer.ToString()); }
public static string GetDisplayName([NotNull] IAssemblyName name, AsmDisplayFlags which) { uint bufferSize = 255; StringBuilder buffer = new StringBuilder((int)bufferSize); name.GetDisplayName(buffer, ref bufferSize, which); return(buffer.ToString()); }
private static string GetFullName(IAssemblyName fusionAsmName) { StringBuilder pDisplayName = new StringBuilder(1024); int pccDisplayName = 1024; Marshal.ThrowExceptionForHR(fusionAsmName.GetDisplayName(pDisplayName, ref pccDisplayName, 167)); return(((object)pDisplayName).ToString()); }
string GetFullName(IAssemblyName asmName) { StringBuilder fullName = new StringBuilder(1024); int iLen = fullName.Capacity; COM.CheckHR(asmName.GetDisplayName(fullName, ref iLen, (int)AssemblyNameDisplayFlags.ALL)); return(fullName.ToString()); }
IEnumerable <DomAssemblyName> GetGacAssemblyFullNames() { IApplicationContext applicationContext = null; IAssemblyEnum assemblyEnum = null; IAssemblyName assemblyName = null; Fusion.CreateAssemblyEnum(out assemblyEnum, null, null, 2, 0); while (assemblyEnum.GetNextAssembly(out applicationContext, out assemblyName, 0) == 0) { uint nChars = 0; assemblyName.GetDisplayName(null, ref nChars, 0); StringBuilder name = new StringBuilder((int)nChars); assemblyName.GetDisplayName(name, ref nChars, 0); yield return(new DomAssemblyName(name.ToString())); } }
private static unsafe string GetDisplayName(IAssemblyName aName, uint dwDisplayFlags) { uint pccDisplayName = 0; string str = (string)null; aName.GetDisplayName((IntPtr)0, ref pccDisplayName, dwDisplayFlags); if (pccDisplayName > 0U) { IntPtr num = (IntPtr)0; fixed(byte *numPtr = new byte[((int)pccDisplayName + 1) * 2]) { num = new IntPtr((void *)numPtr); aName.GetDisplayName(num, ref pccDisplayName, dwDisplayFlags); str = Marshal.PtrToStringUni(num); } } return(str); }
private static unsafe string GetDisplayName(IAssemblyName aName, uint dwDisplayFlags) { uint pccDisplayName = 0; string str = null; aName.GetDisplayName(IntPtr.Zero, ref pccDisplayName, dwDisplayFlags); if (pccDisplayName > 0) { IntPtr zero = IntPtr.Zero; byte[] buffer = new byte[(pccDisplayName + 1) * 2]; fixed(byte *numRef = buffer) { zero = new IntPtr((void *)numRef); aName.GetDisplayName(zero, ref pccDisplayName, dwDisplayFlags); str = Marshal.PtrToStringUni(zero); } } return(str); }
protected string getDisplayName(ASM_DISPLAY_FLAGS flags) { uint len = 0; int hr = _name.GetDisplayName(null, ref len, flags); if (hr == ComUtil.ERROR_INSUFFICIENT_BUFFER && len > 0) { StringBuilder displayName = new StringBuilder((int)len); ComUtil.ComCheck(_name.GetDisplayName(displayName, ref len, flags)); return(displayName.ToString()); } else { return(""); } }
private static string GetDisplayName(IAssemblyName assemblyName) { var bufferSize = 1024; var buffer = new StringBuilder(bufferSize); var hResult = assemblyName.GetDisplayName(buffer, ref bufferSize, AssemblyNameDisplayFlags.Full); if ((uint)hResult == 0x8007007A) // ERROR_INSUFFICIENT_BUFFER { buffer = new StringBuilder(bufferSize); ComCheck(assemblyName.GetDisplayName(buffer, ref bufferSize, AssemblyNameDisplayFlags.Full)); } else { ComCheck(hResult); } return(buffer.ToString()); }
private unsafe static string GetDisplayName(IAssemblyName aName, uint dwDisplayFlags) { uint num = 0U; string result = null; aName.GetDisplayName((IntPtr)0, ref num, dwDisplayFlags); if (num > 0U) { IntPtr intPtr = (IntPtr)0; byte[] array = new byte[(num + 1U) * 2U]; fixed(byte *ptr = array) { intPtr = new IntPtr((void *)ptr); aName.GetDisplayName(intPtr, ref num, dwDisplayFlags); result = Marshal.PtrToStringUni(intPtr); } } return(result); }
public static List <DomAssemblyName> GetAssemblyList() { IApplicationContext applicationContext = null; IAssemblyEnum assemblyEnum = null; IAssemblyName assemblyName = null; List <DomAssemblyName> l = new List <DomAssemblyName>(); Fusion.CreateAssemblyEnum(out assemblyEnum, null, null, 2, 0); while (assemblyEnum.GetNextAssembly(out applicationContext, out assemblyName, 0) == 0) { uint nChars = 0; assemblyName.GetDisplayName(null, ref nChars, 0); StringBuilder sb = new StringBuilder((int)nChars); assemblyName.GetDisplayName(sb, ref nChars, 0); l.Add(new DomAssemblyName(sb.ToString())); } return(l); }
private static string GetFullName(IAssemblyName fusionAsmName) { int capacity = 0x400; StringBuilder pDisplayName = new StringBuilder(capacity); int errorCode = fusionAsmName.GetDisplayName(pDisplayName, ref capacity, 0xa7); if (errorCode < 0) { Marshal.ThrowExceptionForHR(errorCode); } return(pDisplayName.ToString()); }
private String GetFullName(IAssemblyName fusionAsmName) { StringBuilder sDisplayName = new StringBuilder(1024); int iLen = 1024; int hr = fusionAsmName.GetDisplayName(sDisplayName, ref iLen, (int)AssemblyNameDisplayFlags.ALL); if (hr < 0) { Marshal.ThrowExceptionForHR(hr); } return sDisplayName.ToString(); }
/// <summary> /// Gets the names of all assemblies in the GAC. /// </summary> public static IEnumerable <AssemblyNameInfo> GetGacAssemblyFullNames() { IApplicationContext applicationContext = null; IAssemblyEnum assemblyEnum = null; IAssemblyName assemblyName = null; Fusion.CreateAssemblyEnum(out assemblyEnum, null, null, 2, 0); while (assemblyEnum.GetNextAssembly(out applicationContext, out assemblyName, 0) == 0) { uint nChars = 0; assemblyName.GetDisplayName(null, ref nChars, 0); StringBuilder name = new StringBuilder((int)nChars); assemblyName.GetDisplayName(name, ref nChars, 0); var r = new AssemblyNameInfo(name.ToString()); if (r.Version != null) { yield return(r); } } }
/// <summary> /// Gets the names of all assemblies in the GAC. /// </summary> public static IEnumerable <AssemblyNameReference> GetGacAssemblyFullNames() { IApplicationContext applicationContext = null; IAssemblyEnum assemblyEnum = null; IAssemblyName assemblyName = null; uint result = unchecked ((uint)Fusion.CreateAssemblyEnum(out assemblyEnum, null, null, 2, 0)); if (result == 0x80070005) { MessageBox.Show($"Cannot access GAC, please restart with elevated privileges! (HRESULT 0x{result:X})", "ILSpy", MessageBoxButton.OK, MessageBoxImage.Error); yield break; } while (assemblyEnum.GetNextAssembly(out applicationContext, out assemblyName, 0) == 0) { if (assemblyName == null) { continue; } uint nChars = 0; assemblyName.GetDisplayName(null, ref nChars, 0); StringBuilder name = new StringBuilder((int)nChars); assemblyName.GetDisplayName(name, ref nChars, 0); AssemblyNameReference r = null; try { r = AssemblyNameReference.Parse(name.ToString()); } catch (ArgumentException) { } catch (FormatException) { } catch (OverflowException) { } if (r != null) { yield return(r); } } }
private String GetFullName(IAssemblyName fusionAsmName) { StringBuilder sDisplayName = new StringBuilder(1024); int iLen = 1024; int hr = fusionAsmName.GetDisplayName(sDisplayName, ref iLen, (int)AssemblyNameDisplayFlags.ALL); if (hr < 0) { Marshal.ThrowExceptionForHR(hr); } return(sDisplayName.ToString()); }
[System.Security.SecuritySafeCritical] // auto-generated static unsafe String GetDisplayName(IAssemblyName aName, uint dwDisplayFlags) { uint iLen = 0; String sDisplayName = null; aName.GetDisplayName((IntPtr)0, ref iLen, dwDisplayFlags); if (iLen > 0) { IntPtr pDisplayName = (IntPtr)0; // Do some memory allocating here // We need to assume that a wide character is 2 bytes. byte[] data = new byte[((int)iLen + 1) * 2]; fixed(byte *dataptr = data) { pDisplayName = new IntPtr((void *)dataptr); aName.GetDisplayName(pDisplayName, ref iLen, dwDisplayFlags); sDisplayName = Marshal.PtrToStringUni(pDisplayName); } } return(sDisplayName); }
static IEnumerable <Mono.Cecil.AssemblyNameReference> _loadGAC(uint dwFlags) { IApplicationContext applicationContext = null; IAssemblyEnum assemblyEnum = null; IAssemblyName assemblyName = null; Fusion.CreateAssemblyEnum(out assemblyEnum, null, null, dwFlags, 0); while (assemblyEnum.GetNextAssembly(out applicationContext, out assemblyName, 0) == 0) { uint nChars = 0; assemblyName.GetDisplayName(null, ref nChars, 0); StringBuilder name = new StringBuilder((int)nChars); assemblyName.GetDisplayName(name, ref nChars, 0); Mono.Cecil.AssemblyNameReference r = null; try { r = Mono.Cecil.AssemblyNameReference.Parse(name.ToString()); } catch (ArgumentException) { } catch (FormatException) { } catch (OverflowException) { } if (r != null) { yield return(r); } } }
static GAC() { assemblies = new ArrayList(); IAssemblyEnum assemblyEnum = null; IAssemblyName assemblyName = null; Fusion.CreateAssemblyEnum(out assemblyEnum, null, null, (uint)Fusion.AssemblyCacheFlags.GAC, IntPtr.Zero); assemblyEnum.GetNextAssembly(IntPtr.Zero, out assemblyName, 0); while (assemblyName != null) { uint ccbuf = 1024; StringBuilder sb = new StringBuilder((int)ccbuf); assemblyName.GetDisplayName(sb, ref ccbuf, (uint)Fusion.AssemblyNameDisplayFlags.ALL); assemblies.Add(new AssemblyName(sb.ToString())); assemblyEnum.GetNextAssembly(IntPtr.Zero, out assemblyName, 0); } }
private static string GetDisplayName(IAssemblyName native) { int bufferSize = 1024; StringBuilder buffer = new StringBuilder(bufferSize); AssemblyDisplayFlags dwDisplayFlags = AssemblyDisplayFlags.ProcessorArchitecture | AssemblyDisplayFlags.PublicKeyToken | AssemblyDisplayFlags.LanguageId | AssemblyDisplayFlags.Culture | AssemblyDisplayFlags.Version; if (NativeMethods.SUCCESS == native.GetDisplayName(buffer, ref bufferSize, dwDisplayFlags)) { return buffer.ToString(); } return null; }
private static string GetDisplayName(IAssemblyName native) { int bufferSize = 1024; StringBuilder buffer = new StringBuilder(bufferSize); AssemblyDisplayFlags dwDisplayFlags = AssemblyDisplayFlags.ProcessorArchitecture | AssemblyDisplayFlags.PublicKeyToken | AssemblyDisplayFlags.LanguageId | AssemblyDisplayFlags.Culture | AssemblyDisplayFlags.Version; if (NativeMethods.SUCCESS == native.GetDisplayName(buffer, ref bufferSize, dwDisplayFlags)) { return(buffer.ToString()); } return(null); }
/// <summary> /// Initializes a new instance of the <see cref="AssemblyDescription"/> class. /// </summary> /// <param name="assemblyName">Name of the assembly.</param> public AssemblyDescription(IAssemblyName assemblyName) { // Get the qualified name. var stringBuilder = new StringBuilder(10000); var iLen = 10000; var hr = assemblyName.GetDisplayName(stringBuilder, ref iLen, ASM_DISPLAY_FLAGS.ASM_DISPLAYF_VERSION | ASM_DISPLAY_FLAGS.ASM_DISPLAYF_CULTURE | ASM_DISPLAY_FLAGS.ASM_DISPLAYF_PUBLIC_KEY_TOKEN | ASM_DISPLAY_FLAGS.ASM_DISPLAYF_PROCESSORARCHITECTURE); if (hr < 0) Marshal.ThrowExceptionForHR(hr); var displayName = stringBuilder.ToString(); // Load properties from the display name. LoadPropertiesFromDisplayName(displayName); // We have the assembly name, so we can use the optimised version to load the fusion properties. lazyFusionProperties = new Lazy<AssemblyFusionProperties>(DoLoadFusionProperties); lazyReflectionProperties = new Lazy<AssemblyReflectionProperties>(DoLoadReflectionProperties); }
/// <summary> /// Converts the value of this instance to its equivalent <see cref="AssemblyName"/>. /// </summary> /// <param name="assemblyName"></param> /// <returns></returns> public static AssemblyName ToAssemblyName(this IAssemblyName assemblyName) { var result = new AssemblyName(); result.Name = assemblyName.GetName(); result.Version = assemblyName.GetVersion(); result.CultureInfo = new CultureInfo(assemblyName.GetProperty <string>(AssemblyNamePropertyId.Culture)); result.CodeBase = assemblyName.GetProperty <string>(AssemblyNamePropertyId.CodebaseUrl); result.SetPublicKey(assemblyName.GetProperty <byte[]>(AssemblyNamePropertyId.PublicKey)); result.SetPublicKeyToken(assemblyName.GetProperty <byte[]>(AssemblyNamePropertyId.PublicKeyToken)); // Bug: The following line will always return null, why? And how to fix this? // assemblyName.GetProperty<object>(AssemblyNamePropertyId.ProcessorIdArray); // A workaround is available by using the displayname of the IAssemblyName var tmp = assemblyName.GetDisplayName(DisplayNameFlags.ProcessArchitecture); tmp = tmp.Substring(tmp.LastIndexOf('=') + 1); if (Enum.IsDefined(typeof(ProcessorArchitecture), tmp)) { result.ProcessorArchitecture = (ProcessorArchitecture)Enum.Parse(typeof(ProcessorArchitecture), tmp); } return(result); }
[System.Security.SecuritySafeCritical] // auto-generated static unsafe String GetDisplayName(IAssemblyName aName, uint dwDisplayFlags) { uint iLen=0; String sDisplayName = null; aName.GetDisplayName((IntPtr)0, ref iLen, dwDisplayFlags); if (iLen > 0) { IntPtr pDisplayName=(IntPtr)0; // Do some memory allocating here // We need to assume that a wide character is 2 bytes. byte[] data = new byte[((int)iLen+1)*2]; fixed (byte *dataptr = data) { pDisplayName = new IntPtr((void *) dataptr); aName.GetDisplayName(pDisplayName, ref iLen, dwDisplayFlags); sDisplayName = Marshal.PtrToStringUni(pDisplayName); } } return sDisplayName; }
}// ReadFusionCache private static void ReadCache(ArrayList alAssems, uint nFlag) { IAssemblyEnum aEnum = null; IApplicationContext AppCtx = null; IAssemblyName aName = null; int hr = CreateAssemblyEnum(out aEnum, null, null, nFlag, 0); while (hr == HRESULT.S_OK) { hr = aEnum.GetNextAssembly(out AppCtx, out aName, 0); if (hr == HRESULT.S_OK) { uint iLen = 0; IntPtr pDisplayName = (IntPtr)0; // Get the length of the string we need aName.GetDisplayName((IntPtr)0, ref iLen, 0); if (iLen > 0) { // Do some yucky memory allocating here // We need to assume that a wide character is 2 bytes. pDisplayName = Marshal.AllocHGlobal(((int)iLen + 1) * 2); aName.GetDisplayName(pDisplayName, ref iLen, 0); String sDisplayName = Marshal.PtrToStringUni(pDisplayName); Marshal.FreeHGlobal(pDisplayName); AssemInfo newguy = new AssemInfo(); newguy.sFusionName = sDisplayName; // Our info is in a comma seperated list. Let's pull it out String[] sFields = sDisplayName.Split(new char[] { ',' }); newguy.Name = sFields[0]; // The version string is represented as Version=###### // Let's take out the 'Version=' newguy.Version = sFields[1].Substring(sFields[1].IndexOf('=') + 1); // Same goes for the locale newguy.Locale = sFields[2].Substring(sFields[2].IndexOf('=') + 1); // And the internal key token sFields[3] = sFields[3].Substring(sFields[3].IndexOf('=') + 1); if (sFields[3].Equals("null")) { sFields[3] = CResourceStore.GetString("None"); } newguy.PublicKeyToken = sFields[3]; // Now get some more stuff we can't get from a 'GetDisplayName' call newguy.PublicKey = GetFusionString(aName, ASM_NAME.PUBLIC_KEY); newguy.Codebase = GetFusionString(aName, ASM_NAME.CODEBASE_URL); // newguy.Modified = GetFusionString(aName, ASM_NAME.CODEBASE_LASTMOD); // Currently, there's a fusion bug which prevents us from getting this information // We'll go out to the file system and get the data right now. newguy.Modified = ""; try { if (newguy.Codebase != null && newguy.Codebase.Length > 0) { Uri uCodebase = new Uri(newguy.Codebase); String sAbsolutePath = uCodebase.AbsolutePath; if (File.Exists(sAbsolutePath)) { newguy.Modified = File.GetLastWriteTime(sAbsolutePath).ToString(); } } } catch (Exception) { } newguy.ProcType = GetFusionString(aName, ASM_NAME.PROCESSOR_ID_ARRAY); newguy.OSType = GetFusionString(aName, ASM_NAME.OSINFO_ARRAY); newguy.OSVersion = ""; // We'll need to munge the OSINFO_ARRAY a bit // This will grab the ZAP signature newguy.sCustom = GetFusionString(aName, ASM_NAME.CUSTOM); newguy.nCacheType = nFlag; alAssems.Add(newguy); } } } }// ReadFusionCache
private string GetFullName(IAssemblyName asmName) { StringBuilder fullName = new StringBuilder(1024); int iLen = fullName.Capacity; COM.CheckHR(asmName.GetDisplayName(fullName, ref iLen, (int) AssemblyNameDisplayFlags.ALL)); return fullName.ToString(); }
internal static unsafe string GetDisplayName(IAssemblyName nameObject, ASM_DISPLAYF displayFlags) { int hr; uint characterCountIncludingTerminator = 0; hr = nameObject.GetDisplayName(null, ref characterCountIncludingTerminator, displayFlags); if (hr == 0) { return String.Empty; } if (hr != ERROR_INSUFFICIENT_BUFFER) { throw Marshal.GetExceptionForHR(hr); } byte[] data = new byte[(int)characterCountIncludingTerminator * 2]; fixed (byte* p = data) { hr = nameObject.GetDisplayName(p, ref characterCountIncludingTerminator, displayFlags); if (hr != 0) { throw Marshal.GetExceptionForHR(hr); } return Marshal.PtrToStringUni((IntPtr)p, (int)characterCountIncludingTerminator - 1); } }
/// <summary> /// Gets the display name. /// </summary> /// <param name="name">The name.</param> /// <param name="which">The which.</param> /// <returns></returns> public static String GetDisplayName(IAssemblyName name, ASM_DISPLAY_FLAGS which) { uint bufferSize = 255; var buffer = new StringBuilder((int) bufferSize); name.GetDisplayName(buffer, ref bufferSize, which); return buffer.ToString(); }