Can I run code-contracts analysis manually? - c#

When I rebuild my C# app I often don't get the results of my code-contracts analysis. This is caused by the following error message
CodeContracts: MyApp.Client.Model: Analysis method MyApp.Client.Model.MyClass.CreateCalculatedElements(System.Collections.Generic.List1<System.Collections.Generic.KeyValuePair2<System.String,MyCompany.Scripting.ICompiledFunction1<System.Object>>>,System.Collections.Generic.Dictionary2<System.String,MyCompany.Scripting.ICompiledFunction1<System.Decimal>>,System.Collections.Generic.Dictionary2<System.String,MyCompany.Scripting.ICompiledFunction1<System.Decimal>>) timed out
Here is the definition of the method
internal void CreateCalculatedElements(
List<KeyValuePair<string, ICompiledFunction<object>>> preFinalCalculationScripts,
Dictionary<string, ICompiledFunction<decimal>> factorCalculators,
Dictionary<string, ICompiledFunction<decimal>> elementCalculators)
This doesn't always time out. Is there a way I can manually run contract checking just for one project rather than all of them via a rebuild-solution?

You can increase the timeout for that project by adding an extra option to the static checking options in the property pane as follows: -timeout
The default is 180, which is per method.
As to your original question, yes you can run the tools manually as follows:
Say your project P is in directory D, then go to D\obj\Debug\Decl. In there you'll find a convenient file called Pcccheck.rsp which contains the parameters which were passed to cccheck during the build. To run the analysis again, you simply issue:
cccheck #Pcccheck.rsp
Right now, there isn't an option to trigger a re-analysis of just one project without a rebuild.

Related

AppInstance.RedirectActivationTo() fails with "The group or resource is not in the correct state to perform the requested operation." error

I am trying to determine which instance of my multi-instance UWP application should be activated based on the argument passed to it:
var instances = AppInstance.GetInstances();
if (instances.Count() != 0)
{
instances[0].RedirectActivationTo();
}
I have tried placing the code in app.xaml.cs (OnActivated) and main.xaml.cs (OnNavigatedTo) and they both throw the "The group or resource is not in the correct state to perform the requested operation." error for which there appears to be no documentation.
How can I redirect the activation to a current instance?
The AppInstance class should be used in a main method. This is mentioned in the document: The AppInstance class is intended to be used in the Main method of the app. If this class is used later, the property values may be null, and the methods may fail.
To create a main method of UWP app, you will need to disable the defaulted main method which is generated automatically first. Please right click on your project and choose properties, in the Build tab, add DISABLE_XAML_GENERATED_MAIN to the Conditional Compilation Symbols.
Then you could add a new static class to your project and add a new static main mehtod in the class.
I found a blog which have detailed steps about how to use AppInstance.RedirectActivationTo method, you could take a look at: Multiple instances support for UWP apps (Part 2): Redirection
Besides if you want to redirect to an existing instance, it will be better to register the instance first.

How to disable predeployment and postdeployment scripts in DacServices.Deploy()

We have some automated dacpac deployment code which correctly handles both a CreateNewDatabase and straightforward Update database scenarios in C# using Microsoft.SqlServer.Dac
Now in the CreateNewDatabase case we want to be able to run the DacServices.Deploy() with both the Pre and Post Deployment scripts disabled. I.e. they should not be executed in this scenario.
I have tried to find a suitable place in the DacDeployOptions and DacServices objects but cannot find anything that will do this.Ideally
Question 1: I would like something like DacDeployOptions.IgnorePreDeploymentScript = true Is there any means by which I could achieve this at runtime?
As an alternative, some time ago I remember seeing example code which showed how to traverse a dacpac and create a new dacpac in run time. I think this approach would allow me to simply create a new dacpac which I could pass to the Deploy and which would exclude the Pre and Post Deployment scripts. I don't like this solution but it would allow me to achieve what I need.
Question 2: Can anyone point me to some examples for this please?
My code:
var dacService = new DacServices(ConstDefaultConnectionString);
using (var dacPackage = DacPackage.Load(dacPacFilePath))
{
var deployOptions = new DacDeployOptions
{
CreateNewDatabase = true,
IncludeTransactionalScripts = false
};
dacService.Deploy(dacPackage, TestDatabaseName, true, deployOptions);
}
The question is related to: Create LocalDB for testing from Visual Studio SQL project
There are a number of approaches you can take for this, this is a bit of a brain dump (hey the clocks went back last night and I'm not even sure if the current time):
1) create an empty project that references your main project using a same database reference - when you deploy without the scripts deploy the empty one using IncludeCompositeObjects - pre/post deploy scripts are only run from the dacpac you deploy not from any referenced dacpacs but obviously the code and scheme are deployed. This describes it:
https://the.agilesql.club/blog/Ed-Elliott/2016-03-03/Post-Deploy-Scripts-In-Composite-Dacpac-not-deploying
2) use SQLCMD variables to wrap the data setups and pass in the value to the deploy.
3) make your scripts check for whether they should setup data like only insert if the table rowcount is zero
4) for reference data use merge scripts - I'm not clear if the point of this is for reference data or setting up test data
5) Use .net packaging api to remove the pre/post deploy scripts from the dacpac, this shows you how to write the scripts so you should be able to do a GetPart rather than WritePart:
https://github.com/GoEddie/Dir2Dac/blob/master/src/Dir2Dac/DacCreator.cs
On the whole I would guess that there is probably a simpler solution- if this is for testing then maybe make the data setup part of the test setup? If you are unit testing tSQLt helps you avoid all this by using FakeTable.
Hope it helps :)
Ed
Two things to try:
First, doing this type of thing is quite easy if you are using MSBuild since you can tailor a particular Configuration to include one or more pieces of the Project. In your .sqlproj file there is an <ItemGroup> section that should look similar to the following:
<ItemGroup>
<PreDeploy Include="Script.PreDeployment1.sql" />
<PostDeploy Include="Script.PostDeployment1.sql" />
</ItemGroup>
You can simply add a "Condition" that will determine if that ItemGroup is used or not. You can see these "Condition" attributes throughout the .sqlproj file (usually). So the result should look similar to:
<ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PreDeploy Include="Script.PreDeployment1.sql" />
<PostDeploy Include="Script.PostDeployment1.sql" />
</ItemGroup>
Then you just flip between "Release" or "Debug" in the "Active Configuration" drop-down and the pre and post deploy scripts will be included or excluded accordingly.
The other thought was to somehow reset the pre and post deployment scripts. Since you are loading the DacPac into dacPackage, you will have access to the PreDeploymentScript and PostDeploymentScript properties. I am not able to test, but it might be possible to "erase" what is there (assuming that the streams already point to the stored scripts).
DACPACs are ZIP files. Use the functionality of the System.IO.Packaging namespace to remove pre- and post-deployment scripts from an existing package.
using System.IO.Packaging;
// [...]
using (var dacPac = Package.Open(dacPacFile))
{
var preDeploy = new Uri("/predeploy.sql", UriKind.Relative);
if (dacPac.PartExists(preDeploy))
{
dacPac.DeletePart(preDeploy);
}
var postDeploy = new Uri("/postdeploy.sql", UriKind.Relative);
if (dacPac.PartExists(postDeploy))
{
dacPac.DeletePart(postDeploy);
}
dacPac.Close();
}
The file is simply overwritten after Close, so consider copying it away first, in case you want the original unchanged.
(this is partly covered by the internet resource linked in item 5) in the accepted answer; however the code shown above is all you need)

Run MSBuild Task programatically and access the output

I'm trying to run an MSBuild task, in this case ResolveAssemblyReferences, and get access to the outputs of the task such as ResolvedFiles. A short F# script that loads the project (a default F# project created with VS2013) and runs the task is below. With the log verbosity set to Diagnostic, I can see that the task runs successfully, and resolves all the assemblies correctly.
#r #"C:\Program Files (x86)\MSBuild\12.0\bin\Microsoft.Build.dll"
#r #"C:\Program Files (x86)\MSBuild\12.0\bin\Microsoft.Build.Framework.dll"
open System
open Microsoft.Build
let p = new Evaluation.Project("d:/dev/fsharptest/Test/Test.fsproj")
let log = Logging.ConsoleLogger()
log.Verbosity <- Framework.LoggerVerbosity.Diagnostic
p.Build([|"ResolveProjectReferences";"ResolveAssemblyReferences"|],
Seq.singleton (log :> Framework.ILogger) )
for i in p.AllEvaluatedProperties do
printfn "%s: %s" i.Name i.EvaluatedValue
However, neither the evaluated properties nor the items contain any of the outputs of ResolveAssemblyReferences, which is what I am after. The file Microsoft.Common.CurrentVersion.targets has as one output of ResolveAssemblyReferences <Output TaskParameter="ResolvedFiles" ItemName="ReferencePath"/>, but I cannot access this value.
How should I go about getting hold of it?
It turns out that Evaluation.Project and Execution.ProjectInstance are rather different. I tried to use the former, but the latter is closest to the obsolete BuildEngine.Project class I was previously using. The following code snippet returns the fully resolved references for a given project file:
#r #"C:\Program Files (x86)\MSBuild\12.0\bin\Microsoft.Build.dll"
#r #"C:\Program Files (x86)\MSBuild\12.0\bin\Microsoft.Build.Framework.dll"
open System
open Microsoft.Build
let p = new Execution.ProjectInstance(#"d:\dev\fsharptest\Test\Test.fsproj")
p.Build([|"ResolveReferences"|], new Collections.Generic.HashSet<_>())
for i in p.GetItems("ReferencePath") do
printfn "%s" i.EvaluatedInclude
It is in fact possible to get an arbitrary output for the target in question in this manner.
I think the problem is that some arbitrary Output parameter of the Task you end up running is not what the MSBuild task itself returns. It gathers up the "target Returns" of the Tasks you specify directly.
However, I don't know exactly how your syntax works here: you are giving Task names rather than Targets?
But based on what I've read (entry 37 in Kretzler’s book) you could have a Target defined to run the desired Task and hook up the task output to the target’s Return attribute. Then the MSBuild task, told to run that target, will pass through the Return attribute as its own.
I think that would be something like:
<Target Name="ResolveAssemblyReferences" ⋯
Returns="#(ReferencePath)" >
So if the Task you are calling from within that Target is populating the Item Array named ReferencePath as its output parameter, then you publish that same item array as the Target's return value.
If you don't use Returns anywhere in the build script, then the Outputs are automatically taken as the returns.
If you can't edit ResolveAssemblyReferences, then I said you can make a new Target which depends on it. Since ReferencePath is global after the task completes, the new target will still see them and can return it.
If all else fails, have your build script write the item list to a file, which you can then load from some other program without concern over what MSBuild is returning.

Attempt by method 'System.Web.Helpers.Json..cctor()' to access method 'System.Web.Helpers.Json.CreateSerializer()' failed

I am using System.Web.Helpers.Json to deserialize some JSON into dynamic in NET 4. The following line fails with this error: TypeInitializationException: Attempt by method 'System.Web.Helpers.Json..cctor()' to access method 'System.Web.Helpers.Json.CreateSerializer()' failed.
var json = Json.Decode(response);
The response is lengthy but valid JSON. What could be the matter here? I have tried LINQPad with a short handcrafted JSON and it worked. Is this a configuration issue of some sort?
[EDIT]
Here is the actual sample JSON. It appears the content is pretty much irrelevant. When this is run in a brand new Console application or LINQPad, it works as expected. But if you try to run the same code from a brand new Windows Forms application, it barfs with the above error.
var json = Json.Decode("{\"r\":{\"0\":{\"id\":\"2\"},\"1\":{\"id\":\"33\"}}}");
[EDIT2]
Actually, it turns out this has nothing to do with project types. The exception is thrown if the project is being debugged. If it is simply run, the exception does not occur. Strange, eh?
I forgot about this question and I found my answer in the meantime. I think it was somewhere on Microsoft's Connect site but I am not sure. So let's share it now.
Basically, in order to workaround this problem you need to make sure "Enable the Visual Studio hosting process" is unchecked in your project's settings under Debug. I am not sure why it's happening but this is definitely a way to "fix" it. I stopped searching for answers once I found out about this. It was good enough for me.
This can also happen if you are running in a partial trust.
Check the exception description here for possible reasons.
I don't know if this will apply to you, since you are not running in a web context, but this is what that link describes:
This exception is thrown in situations such as the following:
A private, protected, or internal method that would not be accessible from normal compiled code is accessed from partially
trusted code by using reflection.
A security-critical method is accessed from transparent code.
The access level of a method in a class library has changed, and one or more assemblies that reference the library have not been
recompiled.
There is problem in the inbuilt json class.
If you want to achieve this in alternate way, please use the below code:
JavaScriptSerializer serializer = new JavaScriptSerializer();
serializer.RegisterConverters(new DynamicJavaScriptConverter[] { new DynamicJavaScriptConverter() });
var result = WrapObject(serializer.DeserializeObject(value)); // here you will have result.
private object WrapObject(object value)
{
IDictionary<string, object> values = value as IDictionary<string, object>;
if (values != null)
{
return new DynamicJsonObject(values);
}
object[] arrayValues = value as object[];
if (arrayValues != null)
{
return new DynamicJsonArray(arrayValues);
}
return value;
}
Further to Roland's answer: some assembly mismatches listed can be fixed in the AssemblyInfo.cs file.
The offending line in my AssemblyInfo was this:
[assembly: AllowPartiallyTrustedCallers]
Removing this allowed me to access the public property (on a public class) that I was trying to set from another assembly that had dynamically loaded this assembly.

Get Assembly name at compile time in Visual Studio

Is there a way to find out the assembly name at design-time (i.e. not using reflection or runtime APIs such as System.Reflection.Assembly.GetEntryAssembly) from within Visual Studio?
The scenario requires a tool to get the assembly name that a Visual Studio project will eventually compile into.
This is like parsing the AssemblyName property of the .csproj - I am wondering if there are any APIs that can give this information reliably.
Please do not respond back with runtime APIs that use reflection - there is no assembly file present at the time I need the assembly name - just the metadata of the assembly in the csproj file.
if you are calling the tool via a post/pre-build event, this data is very easy to access.
Just go to the "project properties->Build Events" tab, then select either "edit pre-build" or "edit post-build", depending on when you want the tool to run. This should bring up an edit window with the ever helpful "Macros >>" button. Press this and you will be given a heap of macros to use and should be pretty much everything you need.
The "API" you could use is LINQ to XML after all the .csproj file is just xml. (and you can get the location of the .csproj file if you need from the solution file which for some reason is not XML but can be easily parsed)
You can use "TargetName" available in Macros for Post-build events. It will give you the assembly name for your project.
After a quick run through MSDN I found this article which might be a good start for some further research:
Accessing Project Type Specific Project, Project Item, and Configuration Properties
I think you will need to write some regular expression that will give you the value of "AssemblyTitle" attribute in AssemblyInfo.cs file.
Something like this:
public class Assembly
{
public static string GetTitle (string fileFullName) {
var contents = File.ReadAllText (fileFullName); //may raise exception if file doesn't exist
//regex string is: AssemblyTitle\x20*\(\x20*"(?<Title>.*)"\x20*\)
//loading from settings because it is annoying to type it in editor
var reg = new Regex (Settings.Default.Expression);
var match = reg.Match (contents);
var titleGroup = match.Groups["Title"];
return (match.Success && titleGroup.Success) ? titleGroup.Value : String.Empty;
}
}

Categories

Resources