.NET 6 System.Drawing.Common Runtime Switch - .net-6.0

According to https://learn.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/6.0/system-drawing-common-windows-only System.Drawing.Common is no longer supported under on non-windows OS UNLESS a runtime configuration switch is set. I've setup runtimeconfig.template.json and see the switch:
"runtimeOptions": {
"configProperties": {
"System.Drawing.EnableUnixSupport": true
}
}
inside the file .runtimeconfig.json in bin/Debug/net6.0
However when I run the app in a linux box using dotnet exec app.dll I still get PlatformNotSupportedException

The following worked for me.
Adding the following line to the .csproj file in a PropertyGroup section:
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
Next create a file named runtimeconfig.template.json in the same directory as your project file containing:
{
"configProperties": {
"System.Drawing.EnableUnixSupport": true
}
}
I used the dotnet publish command, which created a [YourAppNameHere].runtimeconfig.json file in the output directory I supplied to the dotnet publish command.
For my asp.net project, the publish resulted in the following [YourAppNameHere].runtimeconfig.jsonfile:
{
"runtimeOptions": {
"tfm": "net6.0",
"includedFrameworks": [
{
"name": "Microsoft.NETCore.App",
"version": "6.0.1"
},
{
"name": "Microsoft.AspNetCore.App",
"version": "6.0.1"
}
],
"configProperties": {
"System.Drawing.EnableUnixSupport": true,
"System.GC.Server": true,
"System.Reflection.Metadata.MetadataUpdater.IsSupported": false,
"System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false
}
}
}
This worked, where trying to follow the documentation on the page linked to in the question did not. I think this is because I was adding the "runtimeOptions" section in the runtimeconfig.template.json file, but the dotnet publish command was also adding a section named "runtimeOptions", which seems to have prevented the runtime from seeing the "System.Drawing.EnableUnixSupport" option.
For this reason, I excluded the "runTimeOptions" section in my runtimeconfig.template.json file as the publish resulted in the following file that did not work:
{
"runtimeOptions": {
"tfm": "net6.0",
"includedFrameworks": [
{
"name": "Microsoft.NETCore.App",
"version": "6.0.1"
},
{
"name": "Microsoft.AspNetCore.App",
"version": "6.0.1"
}
],
"runtimeOptions": {
"configProperties": {
"System.Drawing.EnableUnixSupport": true
}
},
"configProperties": {
"System.GC.Server": true,
"System.Reflection.Metadata.MetadataUpdater.IsSupported": false,
"System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false
}
}
}
Note the nested "runtimeOptions", which I believe was causing it to fail when trying to follow the documentation in the link from the question.

One more way is to use set switch in the code:
AppContext.SetSwitch("System.Drawing.EnableUnixSupport", true);

Related

I want to compile all my *.scss files residing in a folder using web compiler in VS2019

Is it possible to compile all .scss files residing in a folder using web compiler in Visual Studio 2019?
I don't want to specify each and every file. I tried something like this.
[
{
"outputFile": "wwwroot/assets/css/pages/",
"inputFile": "wwwroot/assets/sass/pages/**/*.scss",
"minify": { "enabled": true },
"includeInProject": true,
"options": { "sourceMap": true }
}
]

electron-builder: How can I remove deeplinking protocols once the program is uninstalled?

I am working on a project using electron and electron-builder. I have implemented deeplinking protocols in my package.json file. after removing the app on windows the deeplinking protocol still persists. I need this to not persist.
i have tried:
1) deleting my %appdata%\program folder as-well
2) restarting my pc after uninstallation.
3) clearing my browser's cache.
{
"name": "program",
//...
"scripts": {
//...
},
"build": {
//...
"protocols": {
"name": "electron-deep-linking",
"schemes": [
"deeplinkingURI"
]
},
"win": {
"artifactName": "program.${ext}",
"target": [
{
"arch": [
"ia32",
"x64"
],
"target": "nsis-web"
}
]
},
//...
},
//...
}
after uninstalling my program, the deeplinking still works (it does not launch the app because it obviously has been uninstalled, but a prompt still appears attempting to launch nothing).
I suspect that something remains within my windows registry.
NOTE: this problem does not occur on macOS
So I've figured out the answer to my own question (not me but colleagues). there is a registry file under computer\HKEY_CLASSES_ROOT\deeplinkingurl that must be deleted at uninstall via script.
there is another question (that i did not see before, forgive me) that gives more details.

How to deploy Next.js with GraphQL backend on Zeit Now?

I have an Next.js/Express/Apollo GraphQL app running fine on localhost.
I try to deploy it on Zeit Now, and the Next.js part works fine, but the GraphQL backend fails because /graphql route returns:
502: An error occurred with your deployment
Code: NO_STATUS_CODE_FROM_LAMBDA
My now.json looks like:
{
"version": 2,
"builds": [
{ "src": "next.config.js", "use": "#now/next" },
{ "src": "server/server.js", "use": "#now/node" }
],
"routes": [
{ "src": "/api/(.*)", "dest": "server/server.js" },
{ "src": "/graphql", "dest": "server/server.js" }
]
}
Suggestions?
Here’s a complete example of Next.js/Apollo GraphQL running both on Zeit Now (as serverless function/lambda) and Heroku (with an Express server):
https://github.com/tomsoderlund/nextjs-pwa-graphql-sql-boilerplate
I was getting that error until I found on a solution on the Wes Bos slack channel.
The following worked for me, but it's possible you could be getting that error for a different reason.
I'm not sure why it works.
You can see it working here
cd backend
Run npm install graphql-import
Update scripts in package.json:
"deploy": "prisma deploy --env-file variables.env&& npm run writeSchema",
"writeSchema": "node src/writeSchema.js"
Note: For non windows users make sure to place space before &&
Create src/writeSchema.js:
const fs = require('fs');
const { importSchema } = require('graphql-import');
const text = importSchema("src/generated/prisma.graphql");
fs.writeFileSync("src/schema_prep.graphql", text)
Update src/db.js:
const db = new Prisma({
typeDefs: __dirname + "/schema_prep.graphql",
...
});
Update src/createServer.js:
return new GraphQLServer({
typeDefs: __dirname + '/schema.graphql',
...
});
Update src/schema.graphql:
# import * from './schema_prep.graphql'
Create now.json
{
"version": 2,
"name": "Project Name",
"builds": [
{ "src": "src/index.js", "use": "#now/node-server" }
],
"routes": [
{ "src": "/.*", "dest": "src/index.js" }
],
"env": {
"SOME_VARIABLE": "xxx",
...
}
}
Run npm run deploy to initially create schema_prep.graphql.
Run now
Another reply said this:
You should not mix graphql imports and js/ts imports. The syntax on the graphql file will be interpreted by graphql-import and will be ignored by ncc (the compiler which reads the __dirname stuff and move the file to the correct directory etc)
In my example 'schema_prep.graphql' is already preprocessed with the imports from the generated graphql file.
Hopefully this helps.

How to update self-hosted firefox webExtension

How do I configure my self-distrubuted firefox webExtension to auto-update, I have tried following MDN update doc but still unable to update.
My web Extension is hosted on a sub-domain name like
"https://files.example.com/myfile/extension.xpi"
My updates.json file resides at the same location with my .xpi file
This is a prototype of my updates.json
{
"addons": {
"updates": [ { "version": "1.2",
"update_link": "https://files.abc.com/myfiles/extension-1.2-an+fx.xpi" },
{ "version": "1.3",
"update_link": "https://files.abc.com/myfiles/extension-1.3-an+fx.xpi" }
]
}
}
This is the gibberish I get from browser console
1535658478365 addons.update-checker WARN onUpdateCheckComplete failed
to parse update manifest: [Exception... "Update manifest is missing a
required addons property." nsresult: "0x80004005 (NS_ERROR_FAILURE)"
location: "JS frame ::
resource://gre/modules/addons/AddonUpdateChecker.jsm ::
getRequiredProperty :: line 120" data: no] Stack trace:
getRequiredProperty()#resource://gre/modules/addons/AddonUpdateChecker.jsm:120
parseJSONManifest()#resource://gre/modules/addons/AddonUpdateChecker.jsm:130 onLoad()#resource://gre/modules/addons/AddonUpdateChecker.jsm:309 UpdateParser/<()#resource://gre/modules/addons/AddonUpdateChecker.jsm:241
It looks like your 'updates.json' is missing the add-on name and XPI hash. I would also test without the "+" in the file name, I think that caused me issues (Due to hosting server).
To view your add-ons UUID (ex "ADDONNAME#test.com") log into the developer hub, click edit information, then look under technical information. To generate an update_hash of your XPI file I would recommend VSCryptoHash, but any other program that generates a cryptographic hash will work.
{
"addons": {
"ADDONNAME#test.com": {
"updates": [
{ "version": "1.0.0",
"update_link": "https://files.abc.com/myfiles/extension-1.2-fx.xpi" ,
"update_hash": "sha256:blahblah" }
]
}
}
}
The console error says your manifest is missing something too. Here is an example based on mine that works.
"applications": {
"gecko": {
"id": "ADDONNAME#test.com",
"strict_min_version": "50.0",
"update_url": "https://webpage/Updatefile.json"
}
},

How do I use CloudFormation resources in a Lambda function?

I have added a Redis ElastiCache section to my s-resource-cf.json (a CloudFormation template), and selected its hostname as an output.
"Resources": {
...snip...
"Redis": {
"Type": "AWS::ElastiCache::CacheCluster",
"Properties": {
"AutoMinorVersionUpgrade": "true",
"AZMode": "single-az",
"CacheNodeType": "cache.t2.micro",
"Engine": "redis",
"EngineVersion": "2.8.24",
"NumCacheNodes": "1",
"PreferredAvailabilityZone": "eu-west-1a",
"PreferredMaintenanceWindow": "tue:00:30-tue:01:30",
"CacheSubnetGroupName": {
"Ref": "cachesubnetdefault"
},
"VpcSecurityGroupIds": [
{
"Fn::GetAtt": [
"sgdefault",
"GroupId"
]
}
]
}
}
},
"Outputs": {
"IamRoleArnLambda": {
"Description": "ARN of the lambda IAM role",
"Value": {
"Fn::GetAtt": [
"IamRoleLambda",
"Arn"
]
}
},
"RedisEndpointAddress": {
"Description": "Redis server host",
"Value": {
"Fn::GetAtt": [
"Redis",
"Address"
]
}
}
}
I can get CloudFormation to output the Redis server host when running sls resources deploy, but how can I access that output from within a Lambda function?
There is nothing in this starter project template that refers to that IamRoleArnLambda, which came with the example project. According to the docs, templates are only usable for project configuration, they are not accessible from Lambda functions:
Templates & Variables are for Configuration Only
Templates and variables are used for configuration of the project only. This information is not usable in your lambda functions. To set variables which can be used by your lambda functions, use environment variables.
So, then how do I set an environment variable to the hostname of the ElastiCache server after it has been created?
You can set environment variables in the environment section of a function's s-function.json file. Furthermore, if you want to prevent those variables from being put into version control (for example, if your code will be posted to a public GitHub repo), you can put them in the appropriate files in your _meta/variables directory and then reference those from your s-function.json files. Just make sure you add a _meta line to your .gitignore file.
For example, in my latest project I needed to connect to a Redis Cloud server, but didn't want to commit the connection details to version control. I put variables into my _meta/variables/s-variables-[stage]-[region].json file, like so:
{
"redisUrl": "...",
"redisPort": "...",
"redisPass": "..."
}
…and referenced the connection settings variables in that function's s-function.json file:
"environment": {
"REDIS_URL": "${redisUrl}",
"REDIS_PORT": "${redisPort}",
"REDIS_PASS": "${redisPass}"
}
I then put this redis.js file in my functions/lib directory:
module.exports = () => {
const redis = require('redis')
const jsonify = require('redis-jsonify')
const redisOptions = {
host: process.env.REDIS_URL,
port: process.env.REDIS_PORT,
password: process.env.REDIS_PASS
}
return jsonify(redis.createClient(redisOptions))
}
Then, in any function that needed to connect to that Redis database, I imported redis.js:
redis = require('../lib/redis')()
(For more details on my Serverless/Redis setup and some of the challenges I faced in getting it to work, see this question I posted yesterday.)
update
CloudFormation usage has been streamlined somewhat since that comment was posted in the issue tracker. I have submitted a documentation update to http://docs.serverless.com/docs/templates-variables, and posted a shortened version of my configuration in a gist.
It is possible to refer to a CloudFormation output in a s-function.json Lambda configuration file, in order to make those outputs available as environment variables.
s-resource-cf.json output section:
"Outputs": {
"redisHost": {
"Description": "Redis host URI",
"Value": {
"Fn::GetAtt": [
"RedisCluster",
"RedisEndpoint.Address"
]
}
}
}
s-function.json environment section:
"environment": {
"REDIS_HOST": "${redisHost}"
},
Usage in a Lambda function:
exports.handler = function(event, context) {
console.log("Redis host: ", process.env.REDIS_HOST);
};
old answer
Looks like a solution was found / implemented in the Serverless issue tracker (link). To quote HyperBrain:
CF Output variables
To have your lambda access the CF output variables you have to give it the cloudformation:describeStacks access rights in the lambda IAM role.
The CF.loadVars() promise will add all CF output variables to the process'
environment as SERVERLESS_CF_OutVar name. It will add a few ms to the
startup time of your lambda.
Change your lambda handler as follows:
// Require Serverless ENV vars
var ServerlessHelpers = require('serverless-helpers-js');
ServerlessHelpers.loadEnv();
// Require Logic
var lib = require('../lib');
// Lambda Handler
module.exports.handler = function(event, context) {
ServerlessHelpers.CF.loadVars()
.then(function() {
lib.respond(event, function(error, response) {
return context.done(error, response);
});
})
};

Resources