在Visual Studio 2010 里,Dotfuscator变得更好(依然免费)

[原文作者]:Beth Massi     

[原文链接]:http://blogs.msdn.com/bethmassi/archive/2010/02/23/dotfuscator-gets-better-and-still-free-in-visual-studio-2010.aspx

        这周我学习了Visual Studio 2010里面的一个由 PreEmptive Solutions 提供的免费工具Dotfuscator软件服务,如果您正在使用Visual Studio2008的版本,那么你已经熟悉了其代码模糊技术(code obfuscation technology)。你将在2010里更深入了。新增加了一个全新基于代码注入的功能类,例如防止篡改和通知, 正如性能和使用的监督一样 。 如果你曾经想通过你的程序收集用户实际操作程序的信息来改进软件,它可以为你提供解决方案。

        我一直和一些人制作操作演示视频,展示如何让程序迅速启动和更快运行 。这些视频这品将会在 Developer Center Visual Basic开发中心发布,敬请期待。

        目前为止我所学到的,用Visual Studio 2010可以非常简单的建立你的程序并且编译这些功能。之后程序和一个叫做Runtime Intelligence Services Portal免费云服务通讯,它可以收集正在运行的程序的数据。但是,如果你不想使用PreEmptive的免费云服务,希望用自己的终端来收集信息,该怎么做?你十分幸运,因为今天PreEmptive发布了一个用于创建并且托管的终端开源的软件stater kit,在CodePlex上得到它:http://riendpointkit.codeplex.com/

        真的吗,如果它全部是免费的,这些家伙怎么赚钱?虽然Visual Studio2010的免费版中有一些伟大的功能,但是, 当然,专业版本有更多强大的功能,请看看这里两者的功能比较

        希望你会喜欢!

System.Diagnostics.Process: 重定向标准输入、输出和错误

[原文作者]:Lucian Wischik

[原文链接]:System.Diagnostics.Process: redirect StandardInput, StandardOutput, StandardError

    有时我们运行一个外部适用程序,向里面输入数据然后获取它的输出。这往往很容易发生这样的死锁:

     ‘ BAD CODE

     Using p As New System.Diagnostics.Process

     p.StartInfo.FileName = "cat"

     p.StartInfo.UseShellExecute = False

     p.StartInfo.RedirectStandardOutput = True

     p.StartInfo.RedirectStandardInput = True

     p.Start()

     p.StandardInput.Write("world" & vbCrLf & "hello")

    ‘ 这里将发生死锁,如果P写到输出接口的量达到12k

     p.StandardInput.Close()

     Dim op = p.StandardOutput.ReadToEnd()

     p.WaitForExit()

     p.Close()

     Console.WriteLine("OUTPUT:") : Console.WriteLine(op)

     End Using

    这段程序将发生死锁,因为“Cat”首先从标准输入接口中读取,然后写到标准输出接口,最后再读取它,这样一直循环下去直到没有任何东西可读取。但是如果它的标准输出接口已经填满了,并且没有对象去读取,这样就不能继续往里面写东西,从而出现阻塞。

    这里的12k仅是一个随机数,我不会关注于它…

     ‘ BAD CODE

     Using p As New System.Diagnostics.Process

     p.StartInfo.FileName = "findstr"

     p.StartInfo.UseShellExecute = False

     p.StartInfo.RedirectStandardOutput = True

     p.StartInfo.RedirectStandardError = True

     p.Start()

    ‘ deadlock here if p needs to write more than 12k to StandardError

     Dim op = p.StandardOutput.ReadToEnd()

     Dim err = p.StandardError.ReadToEnd()

     p.WaitForExit()

     Console.WriteLine("OUTPUT:") : Console.WriteLine(op)

     Console.WriteLine("ERROR:") : Console.WriteLine(err)

     End Using

     MSDN文档中说:你可以通过异步读取操作来避免这些依赖和潜在的死锁;或者你可以通过创建两个线程,让其中一个独立线程来读取输出流来避免死锁。因此我们将这样来做:

     使用线程来重定向就不会死锁

     ‘  GOOD CODE: 这里不会发生死锁.

     Using p As New Diagnostics.Process

     p.StartInfo.FileName = "sort"

     p.StartInfo.UseShellExecute = False

     p.StartInfo.RedirectStandardOutput = True

     p.StartInfo.RedirectStandardInput = True

     p.Start()

     Dim op = ""

     ‘ do NOT WaitForExit yet since that would introduce deadlocks.

      p.InputAndOutputToEnd("world" & vbCrLf & "hello", op, Nothing)

     p.WaitForExit()

     p.Close()

     Console.WriteLine("OUTPUT:") : Console.WriteLine(op)

     End Using

     ”’ <summary>

     ”’ InputAndOutputToEnd: a handy way to use redirected input/output/error on a p.

     ”’ </summary>

     ”’ <param name="p">The p to redirect. Must have UseShellExecute set to false.</param>

     ”’ <param name="StandardInput">This string will be sent as input to the p. (must be Nothing if not StartInfo.RedirectStandardInput)</param>

     ”’ <param name="StandardOutput">The p’s output will be collected in this ByRef string. (must be Nothing if not StartInfo.RedirectStandardOutput)</param>

     ”’ <param name="StandardError">The p’s error will be collected in this ByRef string. (must be Nothing if not StartInfo.RedirectStandardError)</param>

     ”’ <remarks>This function solves the deadlock problem mentioned at http://msdn.microsoft.com/en-us/library/system.diagnostics.p.standardoutput.aspx</remarks>  

     <Runtime.CompilerServices.Extension()> Sub InputAndOutputToEnd(ByVal p As Diagnostics.Process, ByVal StandardInput As String, ByRef StandardOutput As String, ByRef StandardError As String)

     If p Is Nothing Then Throw New ArgumentException("p must be non-null")

     ‘ Assume p has started. Alas there’s no way to check.

      If p.StartInfo.UseShellExecute Then Throw New ArgumentException("Set StartInfo.UseShellExecute to false")

      If (p.StartInfo.RedirectStandardInput <> (StandardInput IsNot Nothing)) Then Throw New ArgumentException("Provide a non-null Input only when StartInfo.RedirectStandardInput")

      If (p.StartInfo.RedirectStandardOutput <> (StandardOutput IsNot Nothing)) Then Throw New ArgumentException("Provide a non-null Output only when StartInfo.RedirectStandardOutput")

     If (p.StartInfo.RedirectStandardError <> (StandardError IsNot Nothing)) Then Throw New ArgumentException("Provide a non-null Error only when StartInfo.RedirectStandardError")

 

     Dim outputData As New InputAndOutputToEndData

     Dim errorData As New InputAndOutputToEndData

 

     If p.StartInfo.RedirectStandardOutput Then

     outputData.Stream = p.StandardOutput

     outputData.Thread = New Threading.Thread(AddressOf InputAndOutputToEndProc)

     outputData.Thread.Start(outputData)

     End If

     If p.StartInfo.RedirectStandardError Then

     errorData.Stream = p.StandardError

     errorData.Thread = New Threading.Thread(AddressOf InputAndOutputToEndProc)

     errorData.Thread.Start(errorData)

     End If

 

     If p.StartInfo.RedirectStandardInput Then

     p.StandardInput.Write(StandardInput)

     p.StandardInput.Close()

    End If

    If p.StartInfo.RedirectStandardOutput Then outputData.Thread.Join() : StandardOutput = outputData.Output

    If p.StartInfo.RedirectStandardError Then errorData.Thread.Join() : StandardError
= errorData.Output

    If outputData.Exception IsNot Nothing Then Throw outputData.Exception

    If errorData.Exception IsNot Nothing Then Throw errorData.Exception

    End Sub

    Private Class InputAndOutputToEndData

    Public Thread As Threading.Thread

    Public Stream As IO.StreamReader

    Public Output As String

    Public Exception As Exception

    End Class

    Private Sub InputAndOutputToEndProc(ByVal data_ As Object)

    Dim data = DirectCast(data_, InputAndOutputToEndData)

    Try : data.Output = data.Stream.ReadToEnd : Catch e As Exception : data.Exception = e : End Try

    End Sub

PInvoke 和COM对象

 

   我偶尔会觉得有必要把COM的互操作和PInvoke结合起来。在某些场景中,用PInvoke的声明和方法会更容易编码一些。在这些场景中包括进COM对象,并且在签名上加上合适的Marshal标记也是合法的。

    最简单的完成这些场景的方法是有本地的签名只暴露IUnkown实例。在托管代码这边,用一个对象声明并且标记上MarshalAs(UnmanagedType.IUnknown)。例如:

[DllImport("SomeDll.dll")]

[return: MarshalAs(UnmanagedType.IUnknown)]

public static extern object GetSomeComObject();

     有一条需要记住,在这种场景中怎么处理ref这个关键字。在任何情况下,如果一个COM对象被当作来自于PInvoke的签名,CLR会假定他会去调用IUKnown::Release()。 相对的本地代码必须考虑这种情况,适当的对这个对象AddRef()。

    这已经包括了任何的场景,像上面的代码,COM对象返回的值是function [1].

功能预览:VS2010中快速查询文件或标签

 

[原文作者]:Lisa Feigenbaum

[原文链接]:Walkthrough: Quick Search for Files and Symbols in Visual Studio 2010

 

    快速查询是2010CTP(Community Technical Preview,社区技术预览)中我喜欢的功能之一,基本上我每时每刻都在使用。我希望读者在开发中也感受到这项功能的魅力。由于开发者需要不时在代码中寻找某些信息的需求,快速查询已经成为当今开发环境最常用的功能,这篇文章深入介绍了VS2010的这项功能。

    此博文是October VS2010 CTP(VS2010社区技术预览十月版)功能预览系列的一部分,该系列旨在深入浅出地介绍VS2010及.NET 4.0中的新功能,即使读者没有下载社区技术预览,也可以在本文结尾处或以下论坛:

    http://social.msdn.microsoft.com/Forums/en-US/vs2010ctpvbcs/thread/1eb74a01-0d50-4a58-b9b3-cdfae5807ef8

    就本文内容及预览发表评论。

    谢谢!

    Lisa(非译者)

    功能预览:针对文件及标签的快速查询

     本文介绍的是VS2010中针对文件及标签的快速查询。快速查询指借助模糊查询技术协助开发者在代码中快速定位至某段代码。当打开项目工程中任意代码文件时,用户可以借助按下CTRL+,(CTRL键和逗号键)快速启动此功能。在快速查询窗口中,用户可以输入任意数量的查询条件,VS会根据输入值寻找项目中符合条件的标签,包括文件名,类型名,成员名。

     此功能预览使用VS中自带的PeopleTrax例子来进行示范,用户可以在任意工程中使用此功能。

    打开示例工程

  1. 示例文件位于:C:\Program Files\Visual Studio 10.0\Samples\1033\TeamDev Samples.zip.
  2. 解压缩示例文件压缩包到自定义路径,找到并打开PeopleTrax 文件夹。
  3. 双击 PeopleTrax.sln在 Visual Studio 2010中打开该工程.

     使用快速查询来寻找标签

     1. Open any file. Click inside the code editor and press CTRL+,. The following window appears. 打开任意文件,点击代码编辑器内部然后按下CTRL+,,将打开如下窗口

       

        

 

 

     2. 在快速查询窗口顶部文本输入框内输入get. 快速查询窗口将列出所有包含单词 "get" 的标签, 如下图所示,输入不分大小写.

   

          

 

      3. 在 "get"之后, 输入空格及单词 name.快速查询窗口会显示所有包含单词"get" 和 "name"的标签, 如下图所示.

 

          

 

       4.按下向下键选中结果列表中的 GetNames 项. 按回车, Visual Studio 将定位到GetNames 方法定义处.

你知道吗?你可以在异常中解退调用栈

 

[原文作者]:Bill Horst

[原文链接]:Did you know? You can unwind the call stack from exceptions (Bill Horst)

    解退一个异常堆栈的能力是Visual Basic.NET 2005的一个新引进的特性。当调式器触发了一个异常,你可以解退这个堆栈以便于使用代码编辑器修复这个异常并继续调式 修改后的代码。这个异常辅助用户界面有一个“Enable Editing”选项,这个选项可以在当前Solution中展开调式器到代码堆栈的最顶端。

 

  

 

 

    当一个异常未被处理的时候,unwind将会自动发生,但是这个特性可以在Options dialog(在Tools下面)被开启或关闭。(见下图)

  

  

 

    如果你试图在一个异常被触法后去编辑代码,并在解退栈之前,你可以被允许去使用“解退栈并且编辑代码”,“终止代码调试的session”,或“取消编辑”这三个选项。(见下图)

 

    

 

      用户还可以从call stack窗口中进行解退栈,通过在需要的Call stack中单击右键并选择“Unwind To This Frame”。这个特性只是当异常已经被处发并且没有被解退栈时才有效,并且只有当在堆栈的足够靠前的的地方才有效。(见下图)

 

  

     我们希望这个特性可以给您提供更有效率的代码调试,并可以帮助您加强在Visual Basic中使用“Edit and Continue”能力。