Can I use a regular System.dll in a Compact Framework project? - dll

In my test Winforms app (in which I'm targeting .NET 3.5, to simulate the Windows CE / Compact Framework 3.5 app that this is a first-line test for as much as possible), I added some JSON.NET code to deserialize json returned from WebAPI methods:
try
{
const string uri = "http://localhost:48614/api/departments";
var webRequest = (HttpWebRequest)WebRequest.Create(uri);
var webResponse = (HttpWebResponse)webRequest.GetResponse();
if ((webResponse.StatusCode == HttpStatusCode.OK) && (webResponse.ContentLength > 0))
{
var reader = new StreamReader(webResponse.GetResponseStream());
string s = reader.ReadToEnd();
MessageBox.Show(string.Format("Content from HttpWebRequest is {0}", s));
var arr = JsonConvert.DeserializeObject<JArray>(s);
int i = 1;
foreach (JObject obj in arr)
{
var id = (string)obj["Id"];
var accountId = (double)obj["AccountId"];
var departmentName = (string)obj["DeptName"];
MessageBox.Show(string.Format("Object {0} in JSON array: id == {1}, accountId == {2}, deptName == {3}", i, id, accountId, departmentName));
i++;
}
}
else
{
MessageBox.Show(string.Format("Status code == {0}", webResponse.StatusCode));
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
...This runs fine in the .NET 3.5 Winforms app, but when I copied it over to the Windows CE-targetted app, the code wouldn't run, with the following errors spilling forth:
The type 'System.ComponentModel.IBindingList' is defined in an assembly that is not referenced. You must add a reference to assembly 'System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
The type 'System.ComponentModel.ITypedList' is defined in an assembly that is not referenced. You must add a reference to assembly 'System, Version=2.0.0.0...
The type 'System.ComponentModel.INotifyPropertyChanging' is defined in an assembly that is not referenced....
The type 'System.ComponentModel.ICustomTypeDescriptor' is defined in an assembly...
The type 'System.ComponentModel.INotifyPropertyChanged' ...
The type 'System.Uri'...
I saw that in the Winforms (testbed) app, I'm using version 2.0.0.0 of the "regular" (or "deluxe" when compared to CF) System.dll. In the Windows CE app, though, I was using the CF flavor of version 3.5 found here:
C:\Program Files (x86)\Microsoft.NET\SDK\CompactFramework\v3.5\WindowsCE\System.dll
I tried using version 2 CF from C:\Program Files (x86)\Microsoft.NET\SDK\CompactFramework\v2.0\WindowsCE\System.dll, but that failed, too - so it's apparently not really the version (3.5 vs. 2.0), but the "flavor" (CF vs "deluxe"/regular System.dll).
SO...I replaced the CF-flavored System.dll[s] with the one successfully used by the Winforms test app, explicitly the one in C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.dll (I have no System.dll in C:\Windows\Microsoft.NET\Framework\v3.5, anyway).
It no longer gives those same err msgs as listed above, but there is another compile error that may (or may not be) related (Can I give an emulator more disk space?) now.
Whether it is or not (related), it brings up the intriguing question: Will using a regular System.dll in a Windows CE project cause a problem?
If it will -- or there's a good chance that it will -- cause a problem, since it was apparently the JSON.NET code that required the change to an "off-colored" version of System.dll, is there a CF-ready / CF-specific version of JSON.NET? Will I have to create my own CF-targeted version of an assembly from the JSON.NET source?
UPDATE
In the JSON.NET readme, it states:
For a Compact Framework 3.5 build download Json.NET 3.5.
Which I assumed meant the .DLL in \Json50r7\Bin\Net35
Am I wrong about that?
UPDATE 2
When I attempt to open Newtonsoft.Json.Net35.sln in Windows 2008, with the intention of creating a CE-targeted assembly, it doesn't allow me, saying, "The selected file is a solution file, but was created by a newer version of this appllication and cannot be opened*"
It also says in the JSON.NET read me:
Microsoft stopped support for the Compact Framework in Visual Studio 2010.
...so I don't think I can open it in a newer version of VS2008 and create a CF-friendly DLL, either...
UPDATE 3
Looking for a "Compact" folder in the download from http://json.codeplex.com/releases/view/113546, but I see no such folder:
It's not the "Portable" folder, is it?

As Robert Harvey suggests, the tile and the actual question here don't match. You probably should fix that.
The answer to the current title "Can I use a regular System.dll in a Compact Framework Project?" is absolutely, definitively no. You cannot mix and match. Full-framework assemblies cannot run under the Compact Framework. There's no way to make them work. Period. Stop trying this.
The answer to "How do I use JSON.NET is a Compact Framework Project" is that you should go to the JSON.NET project site on GitHub and specifically look at the last JSON.NET 3.5 release (it was Release 8) and download it. Inside that zip file is a folder named "Compact" that contains an assembly named Newtonsoft.Json.Compact.dll. Add a reference to that DLL to your Compact Framework 3.5 project.

Related

Registering .net assembly for COM succeeds with regasm but fails using RegistrationServices.RegisterAssembly

This is one of the strangest issue I have encountered.
There is a .net assembly, which is exposed to COM.
If you register it with regasm /codebase my.dll - it is sucessfully registered, and can be used.
However, if you register it from code using RegistrationServices.RegisterAssembly() :
[...]
RegistrationServices regSvcs = new RegistrationServices();
Assembly assembly = Assembly.LoadFrom(path);
// must call this before overriding registry hives to prevent binding failures on exported types during RegisterAssembly
assembly.GetExportedTypes();
using (RegistryHarvester registryHarvester = new RegistryHarvester(true))
{
// ******** this throws *********
regSvcs.RegisterAssembly(assembly, AssemblyRegistrationFlags.SetCodeBase);
}
Then it throws exception:
Could not load file or assembly 'Infragistics2.Win.UltraWinTree.v9.2, Version=9.2.20092.2083,
Culture=neutral, PublicKeyToken=7dd5c3163f2cd0cb' or one of its dependencies.
Provider type not defined. (Exception from HRESULT: 0x80090017)
This error has very little resource on the net, and looks like related to some security(?) cryptography(?) feature.
After long-long hours, I figured out what causes this (but don't know why):
If there is a public class with a public constructor in the assembly with a parameter UltraTree (from the referenced assembly 'Infragistics2.Win.UltraWinTree.v9.2'), then you cannot register from code, but with regasm only.
When I changed the have a public function Init(UltraTree tree), then it works, I can register from code. So:
// regasm: OK / RegistrationServices.RegisterAssembly(): exception
public class Foo
{
public Foo(UltraWinTree tree) { .. }
}
Foo foo = new Foo(_tree);
-------------- vs --------------
// regasm: OK / RegistrationServices.RegisterAssembly(): OK
public class Foo
{
public Foo() {}
public void Init(UltraWinTree tree) { .. }
}
Foo foo = new Foo();
foo.Init(_tree);
So I could workaround by passing UltraWinTree in a new Init() function instead of constructor, but this is not nice, and I want to know the reason, what the heck is going on?
Anyone has any idea? Thanks.
PS:
Okay, but why we want to register from code? As we use Wix to create installer, which uses heat.exe to harvest registry entries (which are added during asm registration), so heat.exe does assembly registration from code.
I've been dealing with this for years so this is the only answer you need to read:
Heat calls regasm /regfile. So does InstallShield when you tell it to. If you read this page:
https://learn.microsoft.com/en-us/dotnet/framework/tools/regasm-exe-assembly-registration-tool
There's a very important caveat in the remarks section.
You can use the /regfile option to generate a .reg file that contains
the registry entries instead of making the changes directly to the
registry. You can update the registry on a computer by importing the
.reg file with the Registry Editor tool (Regedit.exe). The .reg file
does not contain any registry updates that can be made by user-defined
register functions. The /regfile option only emits registry entries
for managed classes. This option does not emit entries for TypeLibIDs
or InterfaceIDs.
So what to do? Use Heat to generate most of the metadata. Then on a clean machine, (snapshot VM best) us a registry snapshot and compare tool such as InCntrl3 or InstallWatch Pro and sniff out what additional meta regasm writes to the registry. Finally massage that into your Wxs code.
Then on a cleam machine test the install. The result should work and not require any custom actions in the install.

DiffGrams for .NET Core. We are upgrading our project to .NET Core 3.x so need to find the DiffGrams used in the previous version of .NET

We are upgrading our .NET 2.0 application to .NET Core 3.x there's a DiffGrams used to capture the Table field updates (before/after values) used for Auditing purpose. I have to achieve the similar in the .NET Core 3.x. I am not sure which one is the equivalent for .NET Core 3.x.
Could you anyone help me guide on this? Thank you.
DataSet.WriteXml/DataSet.ReadXml method applies to .NET Core 3.x.
The WriteXml method provides a way to write either data only, or both data and schema from a DataSet into an XML document.
private void WriteXmlToFile(DataSet thisDataSet)
{
if (thisDataSet == null) { return; }
// Create a file name to write to.
string filename = "XmlDoc.xml";
// Create the FileStream to write with.
System.IO.FileStream stream = new System.IO.FileStream
(filename, System.IO.FileMode.Create);
// Create an XmlTextWriter with the fileStream.
System.Xml.XmlTextWriter xmlWriter =
new System.Xml.XmlTextWriter(stream,
System.Text.Encoding.Unicode);
// Write to the file with the WriteXml method.
thisDataSet.WriteXml(xmlWriter, XmlWriteMode.DiffGram);
xmlWriter.Close();
}
The resultant XML code is rooted in the <diffgr:diffgram> node and contains up to three distinct data sections, as follows:
<diffgr:diffgram>
<MyDataSet>
:
</MyDataSet>
<diffgr:before>
:
</diffgr:before>
<diffgr:errors>
:
</diffgr:errors>
</diffgr:diffgram>

How can I read version of project in dotnet core (formerly asp.net mvc6)

how can I read assembly version information for my project, the value which in this case comes from the from project.json, and read that in my ASP.net core Controller and pass it to the view?
You can use Razor to get this right from the View and bypass the Controller.
<b>Version</b> #(
Assembly.GetAssembly(typeof(HomeController))
.GetCustomAttribute<AssemblyInformationalVersionAttribute>()
.InformationalVersion
)
To get your application version, as it exists in project.json, you would write:
string appVersion = Assembly.
GetEntryAssembly().
GetCustomAttribute<AssemblyInformationalVersionAttribute>().
InformationalVersion;
Additionally, if you want to know which version of .net core your app is running on you can do this:
....
string dotNetRuntimeVersion = typeof(RuntimeEnvironment)
.GetTypeInfo()
.Assembly
.GetCustomAttribute<AssemblyInformationalVersionAttribute>()
.InformationalVersion;
You may need to add these units to your using for the above runtime version snippet:
using Microsoft.DotNet.InternalAbstractions;
using System.Reflection;
You can get the AssemblyInformationalVersionAttribute from your project's assembly and then pass it to the view.
Here's how to get that attribute: https://github.com/aspnet/dnx/blob/dev/src/Microsoft.Dnx.Host/RuntimeEnvironment.cs#L35-L44
In an early beta version you could add constructor to your controller with parameter IApplicationEnvironment. this param have a property with Version name
public HomeController(IApplicationEnvironment appEnvironment) {
this.appEnvironment = appEnvironment;
}
(No longer works in ASP.net core 1.0)

Using Kentico API from LINQPad is throwing an exception

I am trying to call Kentico API from LINQPad, but getting the following exception:
[AbstractProvider.GetProvider]: The object type 'cms.document' is missing the provider type configuration
My code is:
void Main()
{
var pages = DocumentHelper.GetDocuments("CMS.MenuItem").Path("/", PathTypeEnum.Children);
pages.Dump();
}
Note: I tested the code from Visual Studio, it works, but not from LINQPad.
The problem is that during the initial discovery Kentico looks only at the following paths:
AppDomain.CurrentDomain.BaseDirectory
AppDomain.CurrentDomain.RelativeSearchPath
Which in case of LINQPad are C:\Program Files (x86)\LINQPad4\ and null. Therefore the providers do not get resolved.
I've tried running the code in a new AppDomain but it doesn't seem to work in LINQPad. I suggest submitting this to Kentico as an idea or an issue.
A workaround to this would be copying the LINQPad executable to a location of Kentico DLLs - e.g. C:\inetpub\wwwroot\Kentico82\Lib. That works just fine.
Update (thx to Joe Albahari):
If you wrap your code in this:
var appDomain = Util.CreateAppDomain ("AD", null, new AppDomainSetup
{
PrivateBinPath = #"C:\inetpub\wwwroot\Kentico82\CMS\bin",
});
appDomain.DoCallBack(() => { /* your code */ });
you'll be able to execute it. However, you can't Dump() it to the output window. But you can write it to a text file for example. If you experience the following error:
FileNotFoundException: Could not load file or assembly 'LINQPad, Version=1.0.0.0, Culture=neutral, PublicKeyToken=21353812cd2a2db5' or one of its dependencies. The system cannot find the file specified.
Go to Edit -> Preferences -> Advanced -> Run each query in its own process and turn it off.

Automatically incremented revision number doesn't show up in the About Box

I have a small VB.NET application that I'm working on using the full version of Visual Studio 2005. In the Publish properties of the project, I have it set to Automatically increment revision with each publish.
The issue is that it's only incrementing the revision in the Setup files. It doesn't seem to be updating the version number in the About Box (which is the generic, built-in, About Box template). That version number seems to be coming from My.Application.Info.Version.
What should I be using instead so that my automatically incrementing revision number shows up in the about box?
Change the code for the About box to
Me.LabelVersion.Text = String.Format("Version {0}", My.Application.Deployment.CurrentVersion.ToString)
Please note that all the other answers are correct for "how do I get my assembly version", not the stated question "how do I show my publish version".
It took me a second to find this, but I believe this is what you are looking for:
using System;
using System.Reflection;
public class VersionNumber
{
public static void Main()
{
System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly();
Version version = assembly.GetName().Version;
Console.WriteLine ("Version: {0}", version);
Console.WriteLine ("Major: {0}", version.Major);
Console.WriteLine ("Minor: {0}", version.Minor);
Console.WriteLine ("Build: {0}", version.Build);
Console.WriteLine ("Revision: {0}", version.Revision);
Console.Read();
}
}
It was based upon the code provided at the following site - http://en.csharp-online.net/Display_type_version_number
I'm no VB.NET expert, but have you tried to set the value to for example 1.0.0.*?
This should increase the revision number (at least it does in the AssemblyInfo.cs in C#).
The option you select is only to update the setup number. To update the program number you have to modify the AssemblyInfo.
C#
[assembly: AssemblyVersion("X.Y.")]
[assembly: AssemblyFileVersion("X.Y.")]
VB.NET
Assembly: AssemblyVersion("X.Y.*")
It's a maximum of 65535 for each of the 4 values, but when using 1.0.* or 1.0.*.*, the Assembly Linker will use a coded timestamp (so it's not a simple auto-increment, and it can repeat!) that will fit 65535.
See my answer to this question for more links and details.