- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
是否可以使用反射从程序集中检索所有字符串文字值?
假设我有这个类:
public class Example
{
public void PrintName()
{
Debug.Print(@"My name is Dave");
}
}
我想使用反射来获取应用程序中的字符串列表,例如字符串“My name is Dave”。
如果字符串被分配给一个变量,但不是内联文字,我已经找到了如何做到这一点。
最佳答案
下面是一些应该可以工作的快速代码。您可以做的另一件事是通过查看 #US 元数据流来读取程序集中的所有字符串文字。我前一阵子写了一些代码,如果你有兴趣,我可以挖掘一下。
class Program
{
static void Main()
{
foreach (string literal in FindLiterals(typeof(Program).GetMethod("TestMethod1", BindingFlags.NonPublic | BindingFlags.Static)))
{
Console.WriteLine(literal);
}
Console.ReadLine();
}
private static IEnumerable<string> FindLiterals(MethodInfo method)
{
ILReader reader = new ILReader(method);
foreach (ILInstruction instruction in reader.Instructions)
{
if (instruction.Op == OpCodes.Ldstr)
{
yield return instruction.Data as string;
}
}
}
private static void TestMethod1()
{
Console.WriteLine("Abc");
Console.WriteLine("123");
}
}
public interface IILReaderProvider
{
byte[] GetMethodBody();
FieldInfo ResolveField(int metadataToken);
MemberInfo ResolveMember(int metadataToken);
MethodBase ResolveMethod(int metadataToken);
byte[] ResolveSignature(int metadataToken);
string ResolveString(int metadataToken);
Type ResolveType(int metadataToken);
}
[StructLayout(LayoutKind.Sequential)]
public struct ILInstruction
{
private readonly OpCode operationCode; // 40. 56-64. The entire structure is very big. maybe do array lookup for opcode instead.
private readonly byte[] instructionRawData;
private readonly object instructionData;
private readonly int instructionAddress;
private readonly int index;
internal ILInstruction(OpCode code, byte[] instructionRawData, int instructionAddress, object instructionData, int index)
{
this.operationCode = code;
this.instructionRawData = instructionRawData;
this.instructionAddress = instructionAddress;
this.instructionData = instructionData;
this.index = index;
}
public OpCode Op
{
get
{
return this.operationCode;
}
}
/// <summary>
/// Gets the raw data.
/// </summary>
public byte[] RawData
{
get
{
return this.instructionRawData;
}
}
/// <summary>
/// Gets the data.
/// </summary>
public object Data
{
get
{
return this.instructionData;
}
}
/// <summary>
/// Gets the address of the instruction.
/// </summary>
public int Address
{
get
{
return this.instructionAddress;
}
}
/// <summary>
/// Gets the index of the instruction.
/// </summary>
/// <value>
/// The index of the instruction.
/// </value>
public int InstructionIndex
{
get
{
return this.index;
}
}
/// <summary>
/// Gets the value as integer
/// </summary>
/// <value>The data value.</value>
public int DataValue
{
get
{
int value = 0;
if (this.Data != null)
{
if (this.Data is byte)
{
value = (byte)this.Data;
}
else if (this.Data is short)
{
value = (short)this.Data;
}
else if (this.Data is int)
{
value = (int)this.Data;
}
}
return value;
}
}
/// <summary>
/// Gets the length of the instructions and operands.
/// </summary>
/// <value>The length.</value>
public int Length
{
get
{
return this.Op.Size + (this.RawData == null ? 0 : this.RawData.Length);
}
}
/// <summary>
/// Returns a <see cref="System.String"/> that represents this instance.
/// </summary>
/// <returns>
/// A <see cref="System.String"/> that represents this instance.
/// </returns>
public override string ToString()
{
StringBuilder builder = new StringBuilder();
builder.AppendFormat("0x{0:x4} {1,-10}", this.Address, this.Op.Name);
if (this.Data != null)
{
builder.Append(this.Data.ToString());
}
if (this.RawData != null && this.RawData.Length > 0)
{
builder.Append(" [0x");
for (int i = this.RawData.Length - 1; i >= 0; i--)
{
builder.Append(this.RawData[i].ToString("x2", CultureInfo.InvariantCulture));
}
builder.Append(']');
}
return builder.ToString();
}
}
/// <summary>
/// Reads IL instructions from a byte stream.
/// </summary>
/// <remarks>Allows generated code to be viewed without debugger or enabled debug assemblies.</remarks>
public sealed class ILReader
{
/// <summary>
/// The _instruction lookup.
/// </summary>
private static readonly Lazy<Dictionary<short, OpCode>> instructionLookup = new Lazy<Dictionary<short, OpCode>>(ILReader.GetLookupTable, System.Threading.LazyThreadSafetyMode.ExecutionAndPublication);
/// <summary>
/// The IL reader provider.
/// </summary>
private IILReaderProvider intermediateLanguageProvider;
/// <summary>
/// Initializes a new instance of the <see cref="ILReader"/> class.
/// </summary>
/// <param name="method">
/// The method.
/// </param>
public ILReader(MethodInfo method)
{
if (method == null)
{
throw new ArgumentNullException("method");
}
this.intermediateLanguageProvider = ILReader.CreateILReaderProvider(method);
}
/// <summary>
/// Gets the instructions.
/// </summary>
/// <value>The instructions.</value>
public IEnumerable<ILInstruction> Instructions
{
get
{
byte[] instructionBytes = this.intermediateLanguageProvider.GetMethodBody();
int instructionIndex = 0, startAddress;
for (int position = 0; position < instructionBytes.Length; )
{
startAddress = position;
short operationData = instructionBytes[position];
if (IsInstructionPrefix(operationData))
{
operationData = (short)((operationData << 8) | instructionBytes[++position]);
}
position++;
OpCode code;
if (!instructionLookup.Value.TryGetValue(operationData, out code))
{
throw new InvalidProgramException(string.Format("0x{0:X2} is not a valid op code.", operationData));
}
int dataSize = GetSize(code.OperandType);
byte[] data = new byte[dataSize];
Buffer.BlockCopy(instructionBytes, position, data, 0, dataSize);
object objData = this.GetData(code, data);
position += dataSize;
if (code.OperandType == OperandType.InlineSwitch)
{
dataSize = (int)objData;
int[] labels = new int[dataSize];
for (int index = 0; index < labels.Length; index++)
{
labels[index] = BitConverter.ToInt32(instructionBytes, position);
position += 4;
}
objData = labels;
}
yield return new ILInstruction(code, data, startAddress, objData, instructionIndex);
instructionIndex++;
}
}
}
/// <summary>
/// Creates the IL reader provider.
/// </summary>
/// <param name="methodInfo">The MethodInfo object that represents the method to read..</param>
/// <returns>
/// The ILReader provider.
/// </returns>
private static IILReaderProvider CreateILReaderProvider(MethodInfo methodInfo)
{
IILReaderProvider reader = DynamicILReaderProvider.Create(methodInfo);
if (reader != null)
{
return reader;
}
return new ILReaderProvider(methodInfo);
}
/// <summary>
/// Checks to see if the IL instruction is a prefix indicating the length of the instruction is two bytes long.
/// </summary>
/// <param name="value">The IL instruction as a byte.</param>
/// <remarks>IL instructions can either be 1 or 2 bytes.</remarks>
/// <returns>True if this IL instruction is a prefix indicating the instruction is two bytes long.</returns>
private static bool IsInstructionPrefix(short value)
{
return ((value & OpCodes.Prefix1.Value) == OpCodes.Prefix1.Value) || ((value & OpCodes.Prefix2.Value) == OpCodes.Prefix2.Value)
|| ((value & OpCodes.Prefix3.Value) == OpCodes.Prefix3.Value) || ((value & OpCodes.Prefix4.Value) == OpCodes.Prefix4.Value)
|| ((value & OpCodes.Prefix5.Value) == OpCodes.Prefix5.Value) || ((value & OpCodes.Prefix6.Value) == OpCodes.Prefix6.Value)
|| ((value & OpCodes.Prefix7.Value) == OpCodes.Prefix7.Value) || ((value & OpCodes.Prefixref.Value) == OpCodes.Prefixref.Value);
}
/// <summary>
/// The get lookup table.
/// </summary>
/// <returns>
/// A dictionary of IL instructions.
/// </returns>
private static Dictionary<short, OpCode> GetLookupTable()
{
// Might be better to do an array lookup. Use a seperate arrary for instructions without a prefix and array for each prefix.
Dictionary<short, OpCode> lookupTable = new Dictionary<short, OpCode>();
FieldInfo[] fields = typeof(OpCodes).GetFields(BindingFlags.Static | BindingFlags.Public);
foreach (FieldInfo field in fields)
{
OpCode code = (OpCode)field.GetValue(null);
lookupTable.Add(code.Value, code);
}
return lookupTable;
}
/// <summary>
/// Gets the size of a operand.
/// </summary>
/// <param name="operandType">Defines the type of operand.</param>
/// <returns>The size in bytes of the operand type.</returns>
private static int GetSize(OperandType operandType)
{
switch (operandType)
{
case OperandType.InlineNone:
return 0;
case OperandType.ShortInlineBrTarget:
case OperandType.ShortInlineI:
case OperandType.ShortInlineVar:
return 1;
case OperandType.InlineVar:
return 2;
case OperandType.InlineBrTarget:
case OperandType.InlineField:
case OperandType.InlineI:
case OperandType.InlineMethod:
case OperandType.InlineSig:
case OperandType.InlineString:
case OperandType.InlineSwitch:
case OperandType.InlineTok:
case OperandType.InlineType:
case OperandType.ShortInlineR:
return 4;
case OperandType.InlineI8:
case OperandType.InlineR:
return 8;
default:
return 0;
}
}
private object GetData(OpCode code, byte[] rawData)
{
object data = null;
switch (code.OperandType)
{
case OperandType.InlineField:
data = this.intermediateLanguageProvider.ResolveField(BitConverter.ToInt32(rawData, 0));
break;
case OperandType.InlineSwitch:
data = BitConverter.ToInt32(rawData, 0);
break;
case OperandType.InlineBrTarget:
case OperandType.InlineI:
data = BitConverter.ToInt32(rawData, 0);
break;
case OperandType.InlineI8:
data = BitConverter.ToInt64(rawData, 0);
break;
case OperandType.InlineMethod:
data = this.intermediateLanguageProvider.ResolveMethod(BitConverter.ToInt32(rawData, 0));
break;
case OperandType.InlineR:
data = BitConverter.ToDouble(rawData, 0);
break;
case OperandType.InlineSig:
data = this.intermediateLanguageProvider.ResolveSignature(BitConverter.ToInt32(rawData, 0));
break;
case OperandType.InlineString:
data = this.intermediateLanguageProvider.ResolveString(BitConverter.ToInt32(rawData, 0));
break;
case OperandType.InlineTok:
case OperandType.InlineType:
data = this.intermediateLanguageProvider.ResolveType(BitConverter.ToInt32(rawData, 0));
break;
case OperandType.InlineVar:
data = BitConverter.ToInt16(rawData, 0);
break;
case OperandType.ShortInlineVar:
case OperandType.ShortInlineI:
case OperandType.ShortInlineBrTarget:
data = rawData[0];
break;
case OperandType.ShortInlineR:
data = BitConverter.ToSingle(rawData, 0);
break;
}
return data;
}
}
internal class DynamicILReaderProvider : IILReaderProvider
{
public const int TypeRidPrefix = 0x02000000;
public const int MethodRidPrefix = 0x06000000;
public const int FieldRidPrefix = 0x04000000;
public static readonly Type RuntimeDynamicMethodType;
private static readonly FieldInfo fileLengthField = typeof(ILGenerator).GetField("m_length", BindingFlags.NonPublic | BindingFlags.Instance);
private static readonly FieldInfo IntermediateLanguageBytesField = typeof(ILGenerator).GetField("m_ILStream", BindingFlags.NonPublic | BindingFlags.Instance);
private static readonly MethodInfo bakeByteArrayMethod = typeof(ILGenerator).GetMethod("BakeByteArray", BindingFlags.NonPublic | BindingFlags.Instance);
private static readonly PropertyInfo dynamicScopeIndexor;
private static readonly FieldInfo dynamicScopeField;
private static readonly Type genericMethodInfoType;
private static readonly FieldInfo genericMethodHandleField;
private static readonly FieldInfo genericMethodContextField;
private static readonly Type varArgMethodType;
private static readonly FieldInfo varArgMethodMethod;
private static readonly Type genericFieldInfoType;
private static readonly FieldInfo genericFieldInfoHandle;
private static readonly FieldInfo genericFieldInfoContext;
private static readonly FieldInfo ownerField;
private object dynamicScope;
private ILGenerator generator;
static DynamicILReaderProvider()
{
BindingFlags bindingFlags = BindingFlags.NonPublic | BindingFlags.Instance;
dynamicScopeIndexor = Type.GetType("System.Reflection.Emit.DynamicScope").GetProperty("Item", bindingFlags);
dynamicScopeField = Type.GetType("System.Reflection.Emit.DynamicILGenerator").GetField("m_scope", bindingFlags);
varArgMethodType = Type.GetType("System.Reflection.Emit.VarArgMethod");
varArgMethodMethod = varArgMethodType.GetField("m_method", bindingFlags);
genericMethodInfoType = Type.GetType("System.Reflection.Emit.GenericMethodInfo");
genericMethodHandleField = genericMethodInfoType.GetField("m_methodHandle", bindingFlags);
genericMethodContextField = genericMethodInfoType.GetField("m_context", bindingFlags);
genericFieldInfoType = Type.GetType("System.Reflection.Emit.GenericFieldInfo", false);
if (genericFieldInfoType != null)
{
genericFieldInfoHandle = genericFieldInfoType.GetField("m_fieldHandle", bindingFlags);
genericFieldInfoContext = genericFieldInfoType.GetField("m_context", bindingFlags);
}
else
{
genericFieldInfoHandle = genericFieldInfoContext = null;
}
RuntimeDynamicMethodType = typeof(DynamicMethod).GetNestedType("RTDynamicMethod", BindingFlags.NonPublic);
ownerField = RuntimeDynamicMethodType.GetField("m_owner", bindingFlags);
}
private DynamicILReaderProvider(DynamicMethod method)
{
this.Method = method;
this.generator = method.GetILGenerator();
this.dynamicScope = dynamicScopeField.GetValue(this.generator);
}
public DynamicMethod Method { get; private set; }
internal object this[int token]
{
get
{
return dynamicScopeIndexor.GetValue(this.dynamicScope, new object[] { token });
}
}
public static DynamicILReaderProvider Create(MethodInfo method)
{
if (method == null)
{
throw new ArgumentNullException("method");
}
DynamicMethod dynamicMethod = method as DynamicMethod;
if (dynamicMethod != null)
{
return new DynamicILReaderProvider(dynamicMethod);
}
Type methodType = method.GetType();
if (RuntimeDynamicMethodType.IsAssignableFrom(methodType))
{
return new DynamicILReaderProvider(ownerField.GetValue(method) as DynamicMethod);
}
return null;
}
public byte[] GetMethodBody()
{
byte[] data = null;
ILGenerator ilgen = this.Method.GetILGenerator();
try
{
data = (byte[])bakeByteArrayMethod.Invoke(ilgen, null) ?? new byte[0];
}
catch (TargetInvocationException)
{
int length = (int)fileLengthField.GetValue(ilgen);
data = new byte[length];
Array.Copy((byte[])IntermediateLanguageBytesField.GetValue(ilgen), data, length);
}
return data;
}
public FieldInfo ResolveField(int metadataToken)
{
object tokenValue = this[metadataToken];
if (tokenValue is RuntimeFieldHandle)
{
return FieldInfo.GetFieldFromHandle((RuntimeFieldHandle)tokenValue);
}
if (tokenValue.GetType() == DynamicILReaderProvider.genericFieldInfoType)
{
return FieldInfo.GetFieldFromHandle(
(RuntimeFieldHandle)genericFieldInfoHandle.GetValue(tokenValue),
(RuntimeTypeHandle)genericFieldInfoContext.GetValue(tokenValue));
}
return null;
}
public MemberInfo ResolveMember(int metadataToken)
{
if ((metadataToken & TypeRidPrefix) != 0)
{
return this.ResolveType(metadataToken);
}
if ((metadataToken & MethodRidPrefix) != 0)
{
return this.ResolveMethod(metadataToken);
}
if ((metadataToken & FieldRidPrefix) != 0)
{
return this.ResolveField(metadataToken);
}
return null;
}
public MethodBase ResolveMethod(int metadataToken)
{
object tokenValue = this[metadataToken];
DynamicMethod dynamicMethod = tokenValue as DynamicMethod;
if (dynamicMethod != null)
{
return dynamicMethod;
}
if (tokenValue is RuntimeMethodHandle)
{
return MethodBase.GetMethodFromHandle((RuntimeMethodHandle)this[metadataToken]);
}
if (tokenValue.GetType() == DynamicILReaderProvider.genericFieldInfoType)
{
return MethodBase.GetMethodFromHandle(
(RuntimeMethodHandle)genericMethodHandleField.GetValue(tokenValue),
(RuntimeTypeHandle)genericMethodContextField.GetValue(tokenValue));
}
if (tokenValue.GetType() == DynamicILReaderProvider.varArgMethodType)
{
return DynamicILReaderProvider.varArgMethodMethod.GetValue(tokenValue) as MethodInfo;
}
return null;
}
public byte[] ResolveSignature(int metadataToken)
{
return this[metadataToken] as byte[];
}
public string ResolveString(int metadataToken)
{
return this[metadataToken] as string;
}
public Type ResolveType(int metadataToken)
{
return Type.GetTypeFromHandle((RuntimeTypeHandle)this[metadataToken]);
}
}
internal class ILReaderProvider : IILReaderProvider
{
public ILReaderProvider(MethodInfo method)
{
this.Method = method;
this.MethodBody = method.GetMethodBody();
this.MethodModule = method.Module;
}
public MethodInfo Method { get; private set; }
public MethodBody MethodBody { get; private set; }
public Module MethodModule { get; private set; }
public byte[] GetMethodBody()
{
return this.MethodBody.GetILAsByteArray();
}
public FieldInfo ResolveField(int metadataToken)
{
return this.MethodModule.ResolveField(metadataToken);
}
public MemberInfo ResolveMember(int metadataToken)
{
return this.MethodModule.ResolveMember(metadataToken);
}
public MethodBase ResolveMethod(int metadataToken)
{
return this.MethodModule.ResolveMethod(metadataToken);
}
public byte[] ResolveSignature(int metadataToken)
{
return this.MethodModule.ResolveSignature(metadataToken);
}
public string ResolveString(int metadataToken)
{
return this.MethodModule.ResolveString(metadataToken);
}
public Type ResolveType(int metadataToken)
{
return this.MethodModule.ResolveType(metadataToken);
}
}
关于c# - 如何使用反射检索字符串文字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14243284/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!