First of all, it works! I am glad to see that project was revived and .NET Core was supported. It really opens up a lot of new possibilities for .NET developers. But, not everything is perfect yet:
No support for JDK higher than JDK 8. This means that you cannot use JAR files compiled by JDK 9 for example. It is quite an old limitation, and the project requires an incredible amount of work to catch up with later versions. Everyone can help here 😉
IKVM Compiler (IKMVc) is hard to use. Currently project ships two compilers (IKVMc): one for .NET Framework and one for .NET Core as well as two sets of runtime libraries for two runtimes. You should use .NET Core version of IKVMc with .NET Core set of runtime libraries to produce .NET Core version of a JAR file. Is it confusing and quite hard to use! In most cases, you should not IKVMc use directly anymore, because the project gives you access to MavenReference / MSBuild integration (read further for details).
You should build on Windows with .NET Core 3.1 installed. Windows is the only fully supported platform (once again, it only build-time dependency, produced DLLs will work on all platforms including Linux & macOS, and runtimes like .NET 6). Linux version almost works, except for Sockets support. The macOS version does not exist yet but looks like something is coming…
MavenReference
MavenReference is a very cute new addition to the IKVM family of tools that hide from you the complexity of IKVMc. All you need is to edit your csprof/fsproj file and reference to Maven package! (You may think about Maven like a Nuget from Java world)
That is all you need to get started using Maven dependencies from .NET Core!
P.S.If something co wrong, just check that run build on Windows and Maven package compiled using JDK 8. JDK version (Build-Jdk-Spec) you can find in the manifest inside of the JAR file, do not confuse it with Bundle-RequiredExecutionEnvironment!
I am excited to announce my new project “OpenXML Package Explorer” extension for Visual Studio Code.
It allows to explore content of Office Open XML packages (*.pptx, *.docx, *.xlsx) inside Visual Studio Code. You can open any valid OpenXML package in Tree View, explore parts inside package, their relationships and content of xml parts (pre-formatted xml with highlighting).
I believe that source code of this extension can be used as one more sample of Fable-powered VSCode extension. Here is how it currently works:
F# source code compiled to JS using Fable 3 and bundled with webpack.
Code that interacts with OpenXML packages is written in .NET and uses the latest version of System.IO.Packaging
When extension is activated it starts .NET 5 process with API exposed using Fable.Remoting.
Extension assumes that .NET 5 runtime is installed on user machine but it depends on .NET Install Tool for Extension Authors that should help to install runtime to users that do not have it yet.
Fable.Remoting.Client cannot be used, because it is built on top of XMLHttpRequest that does not exist in Node.js world. Here is feature request for Fable.Remoting.NodeClient that may become a thing one day.
Current client-server communication is built on top of axios library and Fable.Axios bindings with manually written client.
Microsoft.Identity.Web is new (GA from Sept 30, 2020) library which contains a set of reusable classes used in conjunction with ASP.NET Core for integrating with the Microsoft identity platform (formerly Azure AD v2.0 endpoint) and AAD B2C.
The reason is not obvious from the error message. In fact, you browser calls the server with .AspNetCore.Cookies cookies that server cannot accept and cannot renew. What to do? Easy – open dev tool, clean cookies, refresh the page, wait for next server restart and repeat it again. You won’t last long.
The last line (AddInMemoryTokenCaches) configure application to use in-memory cache that is empty after each server restart. We need to find a way to store tokens outside the app process and restore the cache after process restart.
The only alternative to AddInMemoryTokenCaches is AddDistributedTokenCaches with ability to store tokens in memory, Redis, CosmosDB, SqlServer. Last three are nice options to distributed application but all of them are complicated for localhost development.
For our use case would be enough to serialise token cache to local file between restart. Luckily, it is not that complicated. We can implement IDistributedCache interface using TestDistributedCache as reference implementation.
public class LocalFileTokenCache : IDistributedCache
{
private class FileTransaction : IDisposable
{
public FileTransaction(string fileName = "cache.json")
{
var root = Path.GetDirectoryName(GetType().Assembly.Location);
_fileName = Path.Combine(root, fileName);
if (File.Exists(_fileName))
{
var str = File.ReadAllText(_fileName);
Dict = JsonSerializer.Deserialize<Dictionary<string, byte[]>>(str);
}
Dict ??= new Dictionary<string, byte[]>();
}
private readonly string _fileName;
public Dictionary<string, byte[]> Dict { get; }
public void Dispose()
{
var str =JsonSerializer.Serialize(Dict);
File.WriteAllText(_fileName, str);
}
}
public byte[] Get(string key)
{
using var cache = new FileTransaction();
return cache.Dict.TryGetValue(key, out var value) ? cache.Dict[key] : null;
}
public Task<byte[]> GetAsync(string key, CancellationToken token = default)
{
return Task.FromResult(Get(key));
}
public void Refresh(string key)
{
// Don't process anything
}
public Task RefreshAsync(string key, CancellationToken token = default)
{
Refresh(key);
return Task.CompletedTask;
}
public void Remove(string key)
{
using var cache = new FileTransaction();
cache.Dict.Remove(key, out _);
}
public Task RemoveAsync(string key, CancellationToken token = default)
{
Remove(key);
return Task.CompletedTask;
}
public void Set(string key, byte[] value, DistributedCacheEntryOptions options)
{
using var cache = new FileTransaction();
cache.Dict[key] = value;
}
public Task SetAsync(string key, byte[] value, DistributedCacheEntryOptions options, CancellationToken token = default)
{
Set(key, value, options);
return Task.CompletedTask;
}
}
LocalFileTokenCache implementation is not suitable for anything rather than local development.
The last step is to register LocalFileTokenCache in DI container as implementation of IDistributedCache instead of MemoryDistributedCache for development environment.
public class Startup
{
public Startup(IConfiguration configuration, IWebHostEnvironment env)
{
Configuration = configuration;
CurrentEnvironment = env;
}
public IConfiguration Configuration { get; }
private IWebHostEnvironment CurrentEnvironment{ get; set; }
public void ConfigureServices(IServiceCollection services)
{
services.AddMicrosoftIdentityWebAppAuthentication(Configuration)
.EnableTokenAcquisitionToCallDownstreamApi(new[]
{
"User.Read", "Files.ReadWrite.AppFolder", "Files.ReadWrite"
}).AddDistributedTokenCaches();
if (CurrentEnvironment.IsDevelopment())
{
services.AddSingleton<IDistributedCache, LocalFileTokenCache>();
}
else
{
services.AddSingleton<IDistributedCache, MemoryDistributedCache>();
}
//...
}
//...
}
If you have sophisticated user feedback like rating (or likes and most importantly dislikes) then we can use Matrix Factorization algorithm to estimate unknown ratings.
If we have not only rating but other product fields, we can use more advanced algorithm called “Field-Aware Factorization Machine”
If we have no rating at all then “One Class Matrix Factorization” is the only option for us.
In this post I would like to focus on the last option.
One-Class Matrix Factorization
This algorithm can be used when data is limited. For example:
Books store: We have history of purchases (list of pairs userId + bookId) without user’s feedback and want to recommend new books for existing users.
Amazon store: We have history of co-purchases (list of pairs productId + productId) and want to recommend products in section “Customers Who Bought This Item Also Bought”.
Social network: We have information about user friendship (list of pairs userId + userId) and want to recommend users in section “People You May Know”.
As you already understood, it is applicable for a pair of 2 categorical variables, not only for userId + productId pairs.
Google showed several relevant posts about the usage of ML.NET One Class Matrix Factorizarion:
After reading all these 3 samples I realised that I do not fully understand what is Label column is used for. Later I came to a conclusion that all three samples most likely are incorrect and here is why.
There are three input columns required, one for matrix row indexes, one for matrix column indexes, and one for values (i.e., labels) in matrix. They together define a matrix in COO format. The type for label column is a vector of Single (float) while the other two columns are key type scalar.
COO stores a list of (row, column, value) tuples. Ideally, the entries are sorted first by row index and then by column index, to improve random access times. This is another format that is good for incremental matrix construction
So anyway we need three columns. If in the classic Matrix Factorization the Label column is the rating, then for One-Class Matrix Factorization we need to fill it with something else.
The second gem is
The coordinate descent method included is specifically for one-class matrix factorization where all observed ratings are positive signals (that is, all rating values are 1). Notice that the only way to invoke one-class matrix factorization is to assign one-class squared loss to loss function when calling MatrixFactorization(Options). See Page 6 and Page 28 here for a brief introduction to standard matrix factorization and one-class matrix factorization. The default setting induces standard matrix factorization. The underlying library used in ML.NET matrix factorization can be found on a Github repository.
As you see, Label is expected to be always 1, because we watched only One Class (positive rating): user downloaded a book, user purchased 2 items together, there is a friendship between two users.
In the case when data set does not provide rating to us, it is our responsibility to provide 1s to MatrixFactorizationTrainer and specify MatrixFactorizationTrainer.LossFunctionType as loss function.
Clippit is .NETStandard 2.0 library that allows you to easily and efficiently extract all slides from PPTX presentation into one-slide presentations or compose slides back together into one presentation.
Why?
PowerPoint is still the most popular way to present information. Sales and marketing people regularly produce new presentations. But when they work on new presentation they often reuse slides from previous ones. Here is the gap: when you compose presentation you need slides that can be reused, but result of your work is the presentation and you are not generally interested in “slide management”.
One of my projects is enterprise search solution, that help people find Office documents across different enterprise storage systems. One of cool features is that we let our users find particular relevant slide from presentation rather than huge pptx with something relevant on slide 57.
How it was done before
Back in the day, Microsoft PowerPoint allowed us to “Publish slides” (save each individual slide into separate file). I am absolutely sure that this button was in PowerPoint 2013 and as far as I know was removed from PowerPoint 365 and 2019 versions.
When this feature was in the box, you could use Microsoft.Office.Interop.PowerPoint.dll to start instance of PowerPoint and communicate with it using COM Interop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
But server-side Automation of Office has never been recommended by Microsoft. You were never able to reliably scale your automation, like start multiple instances to work with different document (because you need to think about active window and any on them may stop responding to your command). There is no guarantee that File->Open command will return control to you program, because for example if file is password-protected Office will show popup and ask for password and so on.
That was hard, but doable. PowerPoint guarantees that published slides will be valid PowerPoint documents that user will be able to open and preview. So it is worth playing the ceremony of single-thread automation with retries, timeouts and process kills (when you do not receive control back).
Over the time it became clear that it is the dead end. We need to keep the old version of PowerPoint on some VM and never touch it or find a better way to do it.
The History
Windows only solution that requires MS Office installed on the machine and COM interop is not something that you expect from modern .NET solution.
Ideally it should be .NETStandard library on NuGet that platform-agnostic and able to solve you task anywhere and as fast as possible. But there was nothing on Nuget few months ago.
If you ever work with Office documents from C# you know that there is an OpenXml library that opens office document, deserialize it internals to an object model, let you modify it and then save it back. But OpenXml API is low-level and you need to know a lot about OpenXml internals to be able to extract slides with images, embedding, layouts, masters and cross-references into new presentation correctly.
If you google more you will find that there is a project “Open-Xml-PowerTools” developed by Microsoft since 2015 that have never been officially released on NuGet. Currently this project is archived by OfficeDev team and most actively maintained fork belongs to EricWhiteDev (No NuGet.org feed at this time).
Open-Xml-PowerTools has a feature called PresentationBuilder that was created for similar purpose – compose slide ranges from multiple presentations into one presentation. After playing with this library, I realized that it does a great job but does not fully satisfy my requirements:
Resource usage are not efficient, same streams are opened multiple times and not always properly disposed.
Library is much slower than it could be with proper resource management and less GC pressure.
It generates slides with total size much larger than original presentation, because it copies all layouts when only one is needed.
It does not properly name image parts inside slide, corrupt file extensions and does not support SVG.
It was a great starting point, but I realized that I can improve it. Not only fix all mentioned issues and improve performance 6x times but also add support for new image types, properly extract slide titles and convert then into presentation titles, propagate modification date and erase metadata that does not belong to slide.
How it is done today
So today, I am ready to present the new library Clippit that is technically a fork of most recent version of EricWhiteDev/Open-Xml-PowerTools that is extended and improved for one particular use case: extracting slides from presentation and composing them back efficiently.
All classes were moved to Clippit namespace, so you can load it side-by-side with any version of Open-Xml-PowerTools if you already use it.
The library is already available on NuGet, it is written using C# 8.0 (nullable reference types), compiled for .NET Standard 2.0, tested with .NET Core 3.1. It works perfectly on macOS/Linux and battle-tested on hundreds of real world PowerPoint presentations.
New API is quite simple and easy to use
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
HashiCorp Vault is a tool for secrets management, encryption as a service, and privileged access management. It is quite popular nowadays, especially if you own your own infrastructure, private cloud or just cannot store your secrets using Key Vault services provided by Azure/AWS/GCP.
I assume that you already have one up and running instance of HashiCorp Vault, otherwise you may install one using official Installing Vault guide.
Why TLS certificate authentication?
Vault supports many Auth Methods. But what if you are still deploying your app on plain old Windows Server VMs or develop SharePoint application (like I am 😝).
The challenge in this case, that you have to authenticate in Vault in order to get a secret. This means that we need to choose auth method that protects our auth secrets from an accident IT guys who may login on the VM (or malicious code that may find it on file system)
TLS Certificate Auth is a good solution candidate, because we can install certificate into windows certificate store, protect private key (mark it as not-exportable) and even specify list of service accounts, allowed to use this certificate for authentication.
TLS certificate generation
I will be using ssh command on my macOS for certificate generation and Vault configuration, but you can repeat the same step from Window for sure.
For our needs we will use self-signed certificate. You can generate one using OpenSSL. If you do not have OpenSSL installed, you can install from Homebrew.
brew install openssl
First of all we generate private key (it is highly secured, do not share it)
openssl genrsa 2048 > vault_private.pem
Then we generate public part of the key in .pem format (.pem file will be uploaded to Vault for client validation during authentication)
Answer all questions properly, it will help you identify this certificate in future (I’ve created certificate that is valid for 365 days, but you should follow security standards defined in you company).
Note: Common Name cannot be empty, otherwise you will not be able to use this certificate to retrieve the secret (Vault returns ‘missing name in alias’ error). Thank you Vadzim Makarchyk for this note.
The final step is to archive both parts in .pfx format (.pfx file will be deployed into Windows Server certificate store on all machines from where our code should have access to Vault)
I uses Enterprise version of Vault that is used by several teams, that it why I also specify namespace (aka folder for my secrets)
VAULT_NAMESPACE=dev/my-teamexport VAULT_NAMESPACE
I am lazy to properly setup certificates for Vault CLI, that is why I skip certificate validation (never repeat it in production 😉)
VAULT_SKIP_VERIFY=trueexport VAULT_SKIP_VERIFY
We are almost ready to login. The easiest option is to login using Web UI and then reuse issued token in the terminal. Login using your favorite browser, pass authentication and copy token in buffer.
vault login s.fJTY5S51oIfXKnBAG3Qq5eWp.9GKyY
That is it! Token is saved into ~/.vault-token and CLI is ready to use!
Key/Value secret engine creation
Vault supports multiple Secret Engines, but for our demo we create simple Key/Value storage for secrets (for example to store logins and passwords)
vault secrets enable -path=kv kv
This command enable key/value engine (V1) and name kv (-path param)
NOTE: The kv secrets engine has two versions: kv and kv-v2. To enable versioned kv secrets engine, pass kv-v2 instead.
Engine is ready, but it is empty – let’s fix it.
vault write kv/my-secret value="s3c(eT"
This command effectively creates my-secret secret inside kv secret engine and store one key/value pair inside value=”s3c(eT”
ACL Policy creation
Secret engine is secured, nobody (except you, admin) has access to secrets. We need to create rules/policy that define what access we want to provide. Create new files policy-file.hcl and put following content inside.
path "kv/*" { capabilities = ["read", "list"]}
This policy allows to read and list all secrets inside kv secret engine. All users with this policy will be able to read secrets from our engine. Read more about policies.
Write this policy to the server (and name it policy-name)
vault policy write policy-name policy-file.hcl
TLS Certificates – Auth Method
The last step is to assign this policy. But we want to assign it to all clients authenticated in Vault using TLS certificate created by us earlier.
Fist of all we need to enable certificate authentication in our namespace
vault auth enable cert
and create certificate auth in Vault (name it app), assign policy-name to it and upload the public part of generated key (vault_public.pem)
That is it! Vault is configured and waiting for first connection.
TLS certificate deployment
TLS certificate allows us to deploy it to certain set of machines that should have access to the Vault and then specify which accounts (on these machines) may use it for authentication.
On the screenshot you see the step that imports certificate on all target machines with tag SharePoint (in my case) to LocalMachine certificate store to My/Personal store, mark private-key as not exportable and provide access to private key to 2 service accounts.
If your deployment is not automated, you may script the same steps using PowerShell and run it on all machines.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
If you are brave, you can click it even manually! 🙈
Double click on vault.pfx file and choose LocalMachine store location
Click Next, Next and type password used during *.pfx creation and Next again.
Choose Personal certificate store.
Click Next, Finish, OK – your certificated in the store!
Execute mmc (Microsoft Managed Console) from start menu.
File -> Add/Remove Snap-in …
Certificate, Add, Computer account and click Next & Ok
Find our certificate and click Manage Private Keys…
On this screen you can manage the list of accounts that will be able to use this certificate for authentication on the current machine.
.NET client application
Vault is ready, machine is ready (service account / current user is allowed to use certificate from the LocalMachine/Personal store). Few lines of code are separating us from success 😊.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
VaultSecretProvider find X509 certificate in StoreName.My / StoreLocation.LocalMachine, then create CertAuthMethodInfo using certificate and VaultClient that X-Vault-Namespace header to each request with vaultNamespace name.
Using configured instance of VaultClient we can request our secret from Vault _vaultClient.V1.Secrets.KeyValue.V1.ReadSecretAsync(path, mountPoint) specifying path to the secret and mountPoint (name of secret engine).
We are ready to call and receive secrets
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
It is 2018, the time of .NET Core, x-plat, clouds, microservices, blockchain and shine of JavaScript. But, there are guys, like me, who still maintain and sometimes develop classic .NET desktop applications for Windows.
I am not a WPF expert, but I spent a couple of days reviewing, testing and fixing one of our desktop apps and I definitely learned a couple of new tips & tricks that worth to share with other non-experts.
Part #1: General Tips
Tip #1.1: Choose right library/framework
It happened that we use MvvmLight. The library is lightweight and already exists for almost 10 years, MVVM pattern is well-known and lets us keep solution code reasonably well-structured.
But this is definitely not the only choice, there are many other different-purpose libraries and frameworks that may suit you better, especially if you do green-field development. So choose carefully:
Installers always were hard, the seamless auto-update process is even harder. But, today, we have the solution that works for simple user-oriented applications that don’t do crazy things during installation. This solution is Squirrel.Windows – an installation and update framework for Windows desktop apps, designed for C# apps.
It’s definitely worth to learn it once and use it for all apps that you develop.
Tip #1.3: Think about monitoring
Aggregated analytics from user’s machine is priceless for successful apps. There are plenty amount of data that can help you deliver better apps:
Crash reports
Application version distribution
User’s count / Active user
Performance / Integrations tracking
Custom events / Logs
It is not always possible to collect all kinds of data from user’s machine, but do it if you can. There are a couple of services that may help you, like Application Insights, HockeyApp and others.
When data bindings do not play nice you have a possibility to debug. It is not super intuitive, but there are ways to step into the binding process to better figure out what is actually going on. Check this nice article from Mike Woelmer – How To Debug Data Binding Issues in WPF
Part #2: MVVM Light – Code Tips
C# quickly evolves over time, more and more features become available to us. It is not always obvious how to use new async code with an old API.
Tip #2.1: “New” INotifyPropertyChanged syntax
I think almost any WPF developer knows how to implement INotifyPropertyChanged interface
public class MyViewModel : INotifyPropertyChanged
{
private string _isBusy;
public event PropertyChangedEventHandler PropertyChanged;
public MyViewModel() {}
public string IsBusy
{
get { return _isBusy; }
set
{
_isBusy = value;
OnPropertyChanged("IsBusy");
}
}
protected void OnPropertyChanged(string name)
{
if (PropertyChanged == null)
return;
PropertyChanged(this,
new PropertyChangedEventArgs(name))
}
}
Using MVVM Light you can do way shorter (such syntax probably exists for a while, but I discovered it only recently)
public class MyViewModel : ViewModelBase
{
public MyViewModel() {}
private string _isBusy;
public string IsBusy
{
get => _isBusy;
set { Set(() => IsBusy, ref _isBusy, value) }
}
}
All property change events will happen under the hood of Set method. Also, Set method returns true when the value changed so you can use it to do additional actions on property change.
private string _isBusy;
public string IsBusy
{
get => _isBusy;
set {
if (Set(() => IsBusy, ref _isBusy, value)) {
// Do whatever you need on update
}
}
}
There are overloads that allow us to omit first argument – propertyExpression. In this case [CallerMemberName] will be used as the property name, so the code will be even shorter. Not bad for 2018 =)
private string _isBusy;
public string IsBusy
{
get => _isBusy;
set => Set(ref _isBusy, value);
}
Tip #2.2: Async to Action glue
C# async was designed to be better compatible with old APIs and consume Action or delegate. Also, it is one of the reasons why async void exists in the language, but we should always use async Task in our own code.
Read “Do async lambdas return Tasks?” to better understand what’s actually going on here. It means that you can pass your async method as Action to RelayCommand.
new RelayCommand(async() => await Download());
TBH, you should use it like this (explanation in the next tip)
new RelayCommand(async() => await Download(), keepTargetAlive:true);
Tip #2.3: Do not use lambdas with RelayCommand
Lambdas as a parameter for RelayCommand is a bad idea unless you know what can go wrong and use the latest version of MvvmLight.
Actually, I have spent almost 2 days of my life to figure out why at some point of time several buttons in our application stopped working, even though all commands defined in the ViewModel are read-only and assigned once in the constructor.
We had simple commands that do some trivial actions on click, so the developer decided to use lambda in command declaration to save space and simplify the code.
new RelayCommand(() => IsBusy = true);
The code looks simple and correct, but RelayCommand under the hood stores only weak reference to the delegate and any GC cycle can recycle local lambda function. So at some point in time (after next cycle of GC) RelayCommand may not find delegate to call and nothing will happen after the click. For a deeper analysis of this behavior, you can read “RelayCommands and WeakFuncs“.
If you really want to use lambdas with RelayCommand & Messenger you should manually set keepTargetAlive:true (false by default), but probably better do not use them at all.
new RelayCommand(() => IsBusy = true, keepTargetAlive:true);
P.S. Worth to mention that Laurent Bugnion has the course on Pluralsight “MVVM Light Toolkit Fundamentals” that provides detailed MVVM Light overview.
There are some cases when you host and/or maintain 3rd-party .NET products in IIS and logs are not enough to understand the importance of some issues and find root causes. You may need the high-level view of what’s actually going on live.
Fortunately, Microsoft has a tool called Application Insights Status Monitor that can help you to instrument your IIS site with required configs to start collecting telemetry data into Application Insights.
In this post, I want to go one step further and share some tips on how to use it for Microsoft products. So here you can find extra steps which you may need during setup on Office Online Server, but I guess that you can do the same with on-premise SharePoint farm as well.
Configure Telemetry for Office Online Server
Create a new instance of Application Insights
Install Application Insight Status Monitor on machines with Office Online Server. You can do it using the direct link http://go.microsoft.com/fwlink/?LinkID=506648 that will run installation using Web Platform Installer.
Download update (the latest SDK version from NuGet). Click “Update is available” and then “Install Update”.
You may see an error message that app cannot download new SDK from NuGet
This can mean that IE Enhanced Security Configuration is enabled on your server, in this case, you need to temporarily turn it off:
Open Server Manager
Go to Local Server, find “IE Enhanced Security Configuration” and turn it off. Do not forget to turn it on again when you finish this guide!
Sign in using your Azure account
Your sign in flow may end with error “Authentication failed: service_returned_error: Service returned error. Check InnerException for more details”
Go to Event Viewer\Windows Logs\System. If you see Errors from Schannel with a message like “A fatal error occurred while creating an SSL client credential. The internal error state is 10013.” then it is System-wide crypto issue and you need to allow “Use FIPS compliant algorithms for encryption, hashing, and signing” and try to sign in again.
Configure each IIS application to send telemetry to Application Insights resource created in step 1.
Restart IIS from the Status Monitor app to start collecting telemetry data.
Wait for some time to collect enough data to analyze (for example one day).
After that, you can start digging deeper into collected stats to better understand what’s actually going on.
Turn on IE Enhanced Security Configuration.
Performance Counters Note: Actually Application Insights Status Monitor does two simple things: updates web.config to incorporate Application Insights and puts ApplicationInsights.config beside with configuration. By default, it is configured to collect data from performance counters, but it may not work if your Application Pool is running under an account that does not have permissions to access performance counters. Note, that in this case, you have to add App Pool account to Performance Monitor Users group. Read more.
Note: Described fix is not permanent, VS may reset your changes in devenv.exe.config file after the new extensions install/update.
Yesterday Microsoft released the first update to Visual Studio 2015 that contains some pretty cool features and improvements, but this update has broken “some” machines.
During the first run after the update, you may see errors like this one:
or even NullReferenceException when you try to open the list of installed extensions
In order to fix all this stuff you need to check ActivityLog.xml file (c:\Users\{user_name}\AppData\Roaming\Microsoft\VisualStudio\14.0\) and find the exact error message. Most probably, you will see something like this
SetSite failed for package [CSharpPackage][Could not load file or assembly ‘System.Collections.Immutable, Version=1.1.36.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a’ or one of its dependencies. The located assembly’s manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)]:{ at Microsoft.VisualStudio.LanguageServices.Implementation.LanguageService.AbstractPackage`2.Initialize() at Microsoft.VisualStudio.LanguageServices.CSharp.LanguageService.CSharpPackage.Initialize() at Microsoft.VisualStudio.Shell.Package.Microsoft.VisualStudio.Shell.Interop.IVsPackage.SetSite(IServiceProvider sp)}
This error says that bindingRedirect set up incorrectly for VS process. You need to find file devenv.exe.config in c:\Users\{user_name}\AppData\Local\Microsoft\VisualStudio\14.0\ and update it. (Or c:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\, depending of location of your devenv.exe file).
For this particular case, you should find rows that setup redirects for System.Collections.Immutable and change newVersion from 1.1.36.0 to 1.1.37.0. Final config should look like this
After this fix, I was able to load my IDE and setup latest version of Azure SDK 2.8.1 that reset my changes in .config file and I needed to fix it once again.
Everything was OK, until I have tried to open my web project. This time it crashed with the following error in ActiveLog.xml:
SetSite failed for package [JavaScriptWebExtensionsPackage][Could not load file or assembly 'Microsoft.VisualStudio.ProjectSystem.V14Only, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)]:{ at Microsoft.VisualStudio.Html.Package.Utilities.ProjectUtilities.IsImmersiveProject(IVsHierarchy hierarchy) at Microsoft.VisualStudio.Html.Package.Project.WebProjectServices.IsWebProject(IVsHierarchy hierarchy) at Microsoft.VisualStudio.Html.Package.Project.WebProjectServices.AdviseProject(IVsHierarchy hierarchy) at Microsoft.VisualStudio.Html.Package.Project.WebProjectServices.AdviseOpenedProjects(IVsSolution solution) at Microsoft.VisualStudio.Html.Package.Project.WebProjectServices.HookGlobalEvents() at Microsoft.VisualStudio.Html.Package.Project.WebProjectServices.Microsoft.VisualStudio.Html.Package.Project.IWebProjectServices.get_OpenedProjects() at Microsoft.VisualStudio.JavaScript.Web.Extensions.ReferenceAutoSync.ProjectServices.Initialize() at Microsoft.VisualStudio.JavaScript.Web.Extensions.ReferenceAutoSync.ProjectServices..ctor() at Microsoft.VisualStudio.JavaScript.Web.Extensions.JavaScriptWebExtensionsPackage.Initialize() at Microsoft.VisualStudio.Shell.Package.Microsoft.VisualStudio.Shell.Interop.IVsPackage.SetSite(IServiceProvider sp)}
After the search on C:\ drive for Microsoft.VisualStudio.ProjectSystem.V14Only.dll I realized that my machine has version 14.1.0.0 instead of 14.0.0.0. So it looks like we need to add one more redirect in devenv.exe.config.
After these fixes, I have not seen any other errors on my machine (at least for now). I hope that you understand the core idea on how to troubleshoot and fix such errors. So good luck to you and VS team with dependency fighting.