是否可以查看在Expression树上调用Compile()时生成的IL代码?考虑这个非常简单的例子:
class Program
{
public int Value { get; set; }
static void Main(string[] args)
{
var param = Expression.Parameter(typeof(Program));
var con = Expression.Constant(5);
var prop = Expression.Property(param, typeof(Program).GetProperty("Value"));
var assign = Expression.Assign(prop, con);
Action<Program> lambda = Expression.Lambda<Action<Program>>(assign, param).Compile();
Program p = new Program();
lambda(p);
//p.Value = 5;
}
}
Run Code Online (Sandbox Code Playgroud)
现在,表达式树执行最后一行Main
所说的内容.编译应用程序,然后在Reflector中打开它.您可以看到p.Value = 5;
执行分配的IL代码.但表达式树是在运行时编译和编译的.是否可以从编译中查看生成的IL代码?
是否有可能使用.net反射(或其他工具)来修改和重新编译代码快(即没有倾销源,然后使用Visual Studio的重新编译)?
没有继承但只有反射是否可以在C#中动态更改方法的代码?
就像是 :
nameSpaceA.Foo.method1 = aDelegate;
Run Code Online (Sandbox Code Playgroud)
我不能改变/编辑Foo类.
namespace nameSpaceA
{
class Foo
{
private void method1()
{
// ... some Code
}
}
}
Run Code Online (Sandbox Code Playgroud)
我的最终目标是动态改变代码:
public static IList<XPathNavigator> EnsureNodeSet(IList<XPathItem> listItems);
Run Code Online (Sandbox Code Playgroud)
在System.Xml.Xsl.Runtime.XslConvert.cs中
转:
if (!item.IsNode)
throw new XslTransformException(Res.XPath_NodeSetExpected, string.Empty);
Run Code Online (Sandbox Code Playgroud)
进入:
if (!item.IsNode)
throw new XslTransformException(Res.XPath_NodeSetExpected, item.value);
Run Code Online (Sandbox Code Playgroud) 首先,我创建了一个测试程序集HelloWorld.dll
,我想调试它并使用发布配置构建它.
namespace HelloWorld
{
public class HelloClass
{
public string SayHello(string name)
{
return "Hi " + name + "!";
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后我创建了标准的ASP.NET MVC项目并:
HelloWorld.dll
装配修改了HomeController的About
方法
public ActionResult About()
{
var testingClass = new HelloClass();
ViewBag.Message = testingClass.SayHello("John");
return View();
}
Run Code Online (Sandbox Code Playgroud)通过.NET Reflector对象浏览器反编译HelloWorld程序集
~/Home/About
页面中运行调试结果:Brekpoint从未被击中.
当我去Debug -> Windows -> Modules
它时似乎HelloWorld.dll
加载了汇编的符号:
那么,我做错了什么?
编辑:我正在使用Visual Studio 2015 Update 1和RedGate Reflector 8.5
好的,我将从.NET反射器剪切和粘贴以演示我正在尝试做的事情:
public override void UpdateUser(MembershipUser user)
{
//A bunch of irrelevant code...
SecUtility.CheckParameter(ref user.UserName, true, true, true, 0x100, "UserName");
//More irrelevant code...
}
Run Code Online (Sandbox Code Playgroud)
这行代码来自.NET Framework中的System.Web.Security.SqlMembershipProvider.UpdateUser(System.Web.dll v2.0.50727).
SecUtility.CheckParameter需要一个引用值作为第一个参数,它们将传入的用户属性作为参数传递给它.
CheckParameter代码的定义是:
internal static void CheckParameter(ref string param, bool checkForNull, bool checkIfEmpty, bool checkForCommas, int maxSize, string paramName)
{
//Code omitted for brevity
}
Run Code Online (Sandbox Code Playgroud)
它所做的一切都很有意义 - 在纸面上...所以我在某个地方敲了一个快速的小原型,我想用类似的东西:
public class DummyClass
{
public string ClassName{ get; set; }
}
public class Program
{
private static DoSomething(ref string value)
{
//Do something with the value passed …
Run Code Online (Sandbox Code Playgroud) 我刚刚将包含WinForms,通用库和Web应用程序的VS 2008解决方案升级到VS 2010,但所有项目仍然针对.NET 3.5 SP 1.我使用此技术为我的常用库生成XmlSerializers.WinForms应用程序运行正常.当我的Web应用程序尝试使用引用相同XmlSerializers的这些库运行时,它会抛出以下内容:
'/ WebSubscribers'应用程序中的服务器错误.无法加载文件或程序集"Ceoimage.Basecamp.XmlSerializers"或其依赖项之一.此程序集由比当前加载的运行时更新的运行时构建,无法加载.描述:执行当前Web请求期间发生未处理的异常.请查看堆栈跟踪以获取有关错误及其源自代码的位置的更多信息.
异常详细信息:System.BadImageFormatException:无法加载文件或程序集"Ceoimage.Basecamp.XmlSerializers"或其依赖项之一.此程序集由比当前加载的运行时更新的运行时构建,无法加载.
我已经使用.NET Reflector查看了XmlSerializer的引用,并看到它引用了2.0和4.0版本mscorlib
以及3.5和4.0版本System.Data.Linq
.奇怪的是,它只使用4.0版本System.Xml
.那可能是我的问题.
如何使用这些XmlSerializers运行Web应用程序?当我简单地删除那些XmlSerializers时,Web应用程序运行正常.这是一个选项,但是如何强制MSBUILD为特定版本的CLR创建序列化程序?
这是我添加到项目文件的MSBuild任务,它强制创建XmlSerializers:
<Target Name="AfterBuild" DependsOnTargets="AssignTargetPaths;Compile;ResolveKeySource" Inputs="$(MSBuildAllProjects);@(IntermediateAssembly)" Outputs="$(OutputPath)$(_SGenDllName)">
<Delete Files="$(TargetDir)$(TargetName).XmlSerializers.dll" ContinueOnError="true" />
<SGen BuildAssemblyName="$(TargetFileName)" BuildAssemblyPath="$(OutputPath)" References="@(ReferencePath)" ShouldGenerateSerializer="true" UseProxyTypes="false" KeyContainer="$(KeyContainerName)" KeyFile="$(KeyOriginatorFile)" DelaySign="$(DelaySign)" ToolPath="$(SGenToolPath)">
<Output TaskParameter="SerializationAssembly" ItemName="SerializationAssembly" />
</SGen>
</Target>
Run Code Online (Sandbox Code Playgroud) msbuild sgen visual-studio-2010 .net-reflector xmlserializer
可能重复:
DLL混淆DLL:我如何保护我的代码?
大家好,
我正在使用.net framework 4.0并制作任何程序.当我完成它,我发布它并获得我的程序exe.但任何第三方软件都会反编译我的exe,任何人都可以查看我的代码.例如 :
我如何保存我的代码?
谢谢大家......
当我第一次安装.NET Reflector时,它就像解压缩一样容易,将文件夹拖到磁盘上的适当位置并启动它.在UI中,我能够配置诸如Windows资源管理器和Visual Studio集成之类的东西.这一切都很好,我广泛使用它.
现在,我不能再使用它了,因为Red Gate决定不仅开始为其软件的新版本收费,而且还要锁定所有现有版本.我对此的个人感受促使我不要升级到最新版本,事实上,根本不使用任何Red Gate软件.幸运的是,有很多很棒的免费和/或开源替代品 ; 我会选择其中一个.
问题是我无法弄清楚如何从我的PC中完全消除Reflector的所有痕迹.我需要能够打开软件,以便在我从磁盘上盲目删除文件夹之前,我可以要求它从Explorer和Visual Studio中删除它.但我不能这样做,因为我不愿意为此付费或下载新版本.相反,我得到了这个无益且现在不准确的消息:
是的,我可能会删除可执行文件,然后在注册表中自行删除shell集成和所有关联.但我宁愿不这样做.该软件应该像我所有其他软件一样为我提供一种删除它的方法,特别是现在它不再是免费的.
那是什么意思?下载试用版只是为了让我可以删除它不是一个合理的选择.
我意识到VS2012 Express Edition现在支持NuGet包.不知道在VS Express Editions 2012中添加生产力工具如Resharper或Reflector的限制现在已经改变了吗?我从Visual Studio 2010 Express中安装扩展或加载项的限制中引用了一些参考.但是,我正在寻找VS 2012的行为是否已经改变.
我们有一个来自另一个项目的.NET程序集,其中一个来自Reflector的生成文件有一个方法的代码片段.
现在VS 2010 c#编译器抛出各种编译错误$$意外.关闭括号等
在ILDASM中,我看到了这个方法以及许多其他提到的方法,但是在生成的代码中,我发现只有这些编译器生成的方法中的一个进入.
怎么去编译?
.net-reflector ×10
c# ×5
.net ×4
reflector ×2
debugging ×1
decompiling ×1
iis ×1
il ×1
msbuild ×1
reflection ×1
resharper ×1
sgen ×1
vsix ×1
windows ×1