Is it still possible to do ContentOverride in Winforms ViewModels? - mdriven

Previously it was possible to use ContentOverride in Winforms ViewModels.
Is this still possible in MDriven 7.0.0.11262?

I am not aware of any changes so it should work as before. The ContentOverride signal the render-logic (Eco.ViewModel.WinForms.ViewModelUserControl) to call the OnColumnUIOverride event with the following argument:
/// <summary>
/// Arguments for the OnColumnUIOverrideArgs event; fired to allow for override of column render.
/// If you have other UI components that you want to use in ViewModel driven UI's this event provides
/// a hook point to inject them.
/// </summary>
public class OnColumnUIOverrideArgs : EventArgs
{
public ViewModel ViewModel;
/// <summary>
/// The Column in question
/// </summary>
public ViewModelColumn ViewModelColumn;
/// <summary>
/// What kind of UI we had in mind
/// </summary>
public ViewModelUIComponentType ViewModelUIComponentType;
/// <summary>
/// Set this to false to stop us from calling default logic
/// </summary>
public bool ContinueWithDefault;
}

Related

How to custom unity visual scripting's Trigger Transition node?

using UnityEngine;
namespace Unity.VisualScripting
{
/// <summary>
/// Triggers the transition in the parent state graph.
/// </summary>
[UnitSurtitle("State")]
[UnitCategory("Nesting")]
[UnitShortTitle("Trigger Transition")]
[TypeIcon(typeof(IStateTransition))]
public sealed class TriggerStateTransition : Unit
{
/// <summary>
/// The moment at which the parent state transition should be triggered.
/// </summary>
[DoNotSerialize]
[PortLabelHidden]
public ControlInput trigger { get; private set; }
protected override void Definition()
{
trigger = ControlInput(nameof(trigger), Trigger);
}
private ControlOutput Trigger(Flow flow)
{
var stateTransition = flow.stack.GetParent<INesterStateTransition>();
flow.stack.ExitParentElement();
Debug.Log($"change state !!!");
stateTransition.Branch(flow);
return null;
}
}
}
After I copy this code from ProjectName\Library\PackageCache\com.unity.visualscripting#1.7.7\Runtime\VisualScripting.State\TriggerStateTransition.cs and add some debug log the state graph turn gray but it still work to translate to next state.
How can I custom the Trigger Transition node but and do not change graph look?
before:
state graph before
transition before
after:
state graph after
transition after

How to find out which path is running a process when it is shown in blank / empty in the command line of the task Manager

How do I find out in Powershell which path is running a process when it is shown in blank / empty in the command line of the Task Manager?
There are processes (e. g. "csrss.exe") that run in a higher security context (see protected processes) than the current PowerShell session, even if the PowerShell session runs as administrator. For such processes, PowerShell isn't able to query some informations like the process path using Get-Process or the .NET Process class, because PowerShell doesn't have the required permissions.
It depends on the kind of API being used though. Since Windows Vista there is a newer native API QueryFullProcessImageName() that works when the process is opened using the flag PROCESS_QUERY_LIMITED_INFORMATION. AFAIK this functionality isn't available as a .NET API, so you have to use P/Invoke:
Add-Type -TypeDefinition #'
using System;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Text;
public static class WinApiProcess {
[Flags]
public enum ProcessAccess
{
/// <summary>
/// Required to create a thread.
/// </summary>
CreateThread = 0x0002,
/// <summary>
///
/// </summary>
SetSessionId = 0x0004,
/// <summary>
/// Required to perform an operation on the address space of a process
/// </summary>
VmOperation = 0x0008,
/// <summary>
/// Required to read memory in a process using ReadProcessMemory.
/// </summary>
VmRead = 0x0010,
/// <summary>
/// Required to write to memory in a process using WriteProcessMemory.
/// </summary>
VmWrite = 0x0020,
/// <summary>
/// Required to duplicate a handle using DuplicateHandle.
/// </summary>
DupHandle = 0x0040,
/// <summary>
/// Required to create a process.
/// </summary>
CreateProcess = 0x0080,
/// <summary>
/// Required to set memory limits using SetProcessWorkingSetSize.
/// </summary>
SetQuota = 0x0100,
/// <summary>
/// Required to set certain information about a process, such as its priority class (see SetPriorityClass).
/// </summary>
SetInformation = 0x0200,
/// <summary>
/// Required to retrieve certain information about a process, such as its token, exit code, and priority class (see OpenProcessToken).
/// </summary>
QueryInformation = 0x0400,
/// <summary>
/// Required to suspend or resume a process.
/// </summary>
SuspendResume = 0x0800,
/// <summary>
/// Required to retrieve certain information about a process (see GetExitCodeProcess, GetPriorityClass, IsProcessInJob, QueryFullProcessImageName).
/// A handle that has the PROCESS_QUERY_INFORMATION access right is automatically granted PROCESS_QUERY_LIMITED_INFORMATION.
/// </summary>
QueryLimitedInformation = 0x1000,
/// <summary>
/// Required to wait for the process to terminate using the wait functions.
/// </summary>
Synchronize = 0x100000,
/// <summary>
/// Required to delete the object.
/// </summary>
Delete = 0x00010000,
/// <summary>
/// Required to read information in the security descriptor for the object, not including the information in the SACL.
/// To read or write the SACL, you must request the ACCESS_SYSTEM_SECURITY access right. For more information, see SACL Access Right.
/// </summary>
ReadControl = 0x00020000,
/// <summary>
/// Required to modify the DACL in the security descriptor for the object.
/// </summary>
WriteDac = 0x00040000,
/// <summary>
/// Required to change the owner in the security descriptor for the object.
/// </summary>
WriteOwner = 0x00080000,
StandardRightsRequired = 0x000F0000,
/// <summary>
/// All possible access rights for a process object.
/// </summary>
AllAccess = StandardRightsRequired | Synchronize | 0xFFFF
}
[DllImport("kernel32.dll")]
private static extern bool QueryFullProcessImageName(IntPtr hprocess, int dwFlags,
StringBuilder lpExeName, out int size);
[DllImport("kernel32.dll")]
private static extern IntPtr OpenProcess(ProcessAccess dwDesiredAccess,
bool bInheritHandle, int dwProcessId);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool CloseHandle(IntPtr hHandle);
public static string QueryProcessPath(int ProcessId)
{
var buffer = new StringBuilder(1024);
IntPtr hprocess = OpenProcess(ProcessAccess.QueryLimitedInformation, false, ProcessId);
if (hprocess != IntPtr.Zero)
{
try
{
int size = buffer.Capacity;
if (QueryFullProcessImageName(hprocess, 0, buffer, out size))
{
return buffer.ToString();
}
}
finally
{
CloseHandle(hprocess);
}
}
throw new Win32Exception(Marshal.GetLastWin32Error());
}
}
'#
Usage example:
[WinApiProcess]::QueryProcessPath( (Get-Process csrss)[0].Id )
This works for me when PowerShell runs elevated ("as administrator").
Finally works , the problem was that to show all the info, I needed to use a user with elevated privileges or DC admin. Then you can see the full info
Many thanks for your help

Unable to configure Dependency Injection - IoC in WINUI3 app - visual studio 2022

someone has the same problem using this code in the new WINUI3 app (Visual Studio 2022) as explained https://learn.microsoft.com/en-us/windows/communitytoolkit/mvvm/ioc :
public sealed partial class App : Application
{
public App()
{
Services = ConfigureServices();
this.InitializeComponent();
}
/// <summary>
/// Gets the current <see cref="App"/> instance in use
/// </summary>
public new static App Current => (App)Application.Current;
/// <summary>
/// Gets the <see cref="IServiceProvider"/> instance to resolve application services.
/// </summary>
public IServiceProvider Services { get; }
/// <summary>
/// Configures the services for the application.
/// </summary>
private static IServiceProvider ConfigureServices()
{
var services = new ServiceCollection();
services.AddSingleton<IFilesService, FilesService>();
services.AddSingleton<ISettingsService, SettingsService>();
services.AddSingleton<IClipboardService, ClipboardService>();
services.AddSingleton<IShareService, ShareService>();
services.AddSingleton<IEmailService, EmailService>();
return services.BuildServiceProvider();
}
}
This is NUGET packages installed
and this is my error:
You need to install:
Microsoft.Extensions.DependencyInjection
instead of,
Microsoft.Extensions.DependencyInjection.Abstractions

Workflow Foundation Native activity child activities on designer

I've created Native Activity that looks like this:
public sealed class ConsoleColorScope : NativeActivity
{
#region Constructors and Destructors
/// <summary>
/// Initializes a new instance of the <see cref="ConsoleColorScope"/> class.
/// </summary>
public ConsoleColorScope()
{
this.Color = ConsoleColor.Gray;
}
#endregion
#region Public Properties
/// <summary>
/// Gets or sets Body.
/// </summary>
[DefaultValue(null)]
public Activity Body { get; set; }
/// <summary>
/// Gets or sets Color.
/// </summary>
public ConsoleColor Color { get; set; }
#endregion
#region Methods
/// <summary>
/// The execute.
/// </summary>
/// <param name="context">
/// The context.
/// </param>
protected override void Execute(NativeActivityContext context)
{
context.Properties.Add(ConsoleColorProperty.Name, new ConsoleColorProperty(this.Color));
if (this.Body != null)
{
context.ScheduleActivity(this.Body);
}
}
#endregion
/// <summary>
/// The console color property.
/// </summary>
private class ConsoleColorProperty : IExecutionProperty
{
#region Constants and Fields
/// <summary>
/// The name.
/// </summary>
public const string Name = "ConsoleColorProperty";
/// <summary>
/// The color.
/// </summary>
private readonly ConsoleColor color;
/// <summary>
/// The original.
/// </summary>
private ConsoleColor original;
#endregion
#region Constructors and Destructors
/// <summary>
/// Initializes a new instance of the <see cref="ConsoleColorProperty"/> class.
/// </summary>
/// <param name="color">
/// The color.
/// </param>
public ConsoleColorProperty(ConsoleColor color)
{
this.color = color;
}
#endregion
#region Explicit Interface Methods
/// <summary>
/// Cleanup the workflow thread.
/// </summary>
void IExecutionProperty.CleanupWorkflowThread()
{
Console.ForegroundColor = this.original;
}
/// <summary>
/// Setup the workflow thread.
/// </summary>
void IExecutionProperty.SetupWorkflowThread()
{
this.original = Console.ForegroundColor;
Console.ForegroundColor = this.color;
}
#endregion
}
}
This is class taken from the working sample:
http://code.msdn.microsoft.com/windowsdesktop/Windows-Workflow-c5649c23#content
However, when I open XAML file, I'm unable to see child activities within scope, as it is shown on the picture on the link above. All I can see is the names of the scopes.
I've created my own version of NativeActivity and I have same issue. Is there some procedure that I have to follow that would allow me to see body of NativeActivity in which I can drag and drop other activities (similar to Sequence activity) as it is shown on the demo description?
You'll need to create an Activity Designer project to go along with your custom activity which has a drop-zone (a WorkflowItemPresenter control) for placing an activity to fill your custom activity's body property with. Then you can setup the plumbing to link your designer to an activity. The following illustrates the steps in detail.
Create A New Activity Designer Project
In your solution, add a new Activity Designer project named like <Your Custom Activity Library>.Design. The assembly must be named <Your Custom Activity Library>.Design.dll, so that Visual Studio will use your activity designers for your custom activities. In the XAML for your designer, you'll utilize the WorkflowItemPresenter to display a drop-zone that accepts an activity that users of your custom activity can use.
<sap:ActivityDesigner x:Class="Your_Custom_Activity_Library.Design.ConsoleColorScopeDesigner"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sap="clr-namespace:System.Activities.Presentation;assembly=System.Activities.Presentation"
xmlns:sapv="clr-namespace:System.Activities.Presentation.View;assembly=System.Activities.Presentation">
<Grid>
<sap:WorkflowItemPresenter HintText="Drop an activity here!"
Item="{Binding Path=ModelItem.Body, Mode=TwoWay}"
MinWidth="300"
MinHeight="150" />
</Grid>
</sap:ActivityDesigner>
The ModelItem in the XAML represents your activity, and you can have your designer set any property in your activity with it. In the above sample, I'm setting up the WorkflowItemPresenter to bind to your activity's Body property.
Registering Designers With Your Activity
Next, add a class called RegisterMetadata (can be any name really) that implements the IRegisterMetadata interface. Its implementation is very simple:
public class RegisterMetadata : IRegisterMetadata
{
/// <summary>
/// Registers all activity designer metadata.
/// </summary>
public static void RegisterAll()
{
// Attribute table builder for the metadata store.
AttributeTableBuilder builder = new AttributeTableBuilder();
// Register the designer for the custom activities.
builder.AddCustomAttributes(typeof(ConsoleColorScope), new DesignerAttribute(typeof(ConsoleColorScopeDesigner)));
// Add the attributes to the metadata store.
MetadataStore.AddAttributeTable(builder.CreateTable());
}
/// <summary>
/// Registers this instance.
/// </summary>
public void Register()
{
RegisterMetadata.RegisterAll();
}
}
The way Visual Studio loads your custom activity designers is by looking for assemblies named <Your Custom Activity Library>.Design.dll, and then it looks for a public class that implements the IRegisterMetadata interface.
You should now be able to drag and drop your custom activity to a workflow and it will have a drop-zone allowing you to specify the Body activity.
You can get fancy with your designer, and expose friendly controls to allow a user to setup your custom activity. You could also create your own designers for the out-of-the-box activities provided in the .NET Framework.
Hope that helps.

Why does Autofac fail to find log4net using the "LogInjectionModule"?

As discussed on the Autofac Wiki, the best way to automatically inject the log4net.ILog implementation for a class is to use the LogInjectionModule. This module's implementation is given in the wiki article:
public class LogInjectionModule : Module
{
protected override void AttachToComponentRegistration(IComponentRegistry componentRegistry, IComponentRegistration registration)
{
if (registration == null) throw new ArgumentNullException("registration");
registration.Preparing += OnComponentPreparing;
}
static void OnComponentPreparing(object sender, PreparingEventArgs e)
{
var t = e.Component.Activator.LimitType;
e.Parameters = e.Parameters.Union(new[]
{
new ResolvedParameter((p, i) => p.ParameterType == typeof(ILog), (p, i) => LogManager.GetLogger(t))
});
}
}
I'm including this module along with a module of my own to configure some components:
var builder = new ContainerBuilder();
builder.RegisterModule(new Common.Logging.LogInjectionModule());
builder.RegisterModule(new DataLayer.DataLayerModule("connectionstring"));
builder.RegisterType<SomeServiceType>();
AutofacHostFactory.Container = builder.Build();
Inside the DataLayerModule I'm constructing a type as follows:
protected override void Load(ContainerBuilder builder)
{
builder.Register(c => new DataAccess(this.ConnectionString, c.Resolve<ILog>()))
.As<IDataAccess>();
// Some other type registrations...
}
When my application attempts to construct an IDataAccess object I get the following exception:
The requested service 'log4net.ILog' has not been registered. To avoid this exception, either register a component to provide the service, check for service registration using IsRegistered(), or use the ResolveOptional() method to resolve an optional dependency.
I know that on the wiki page it is mentioned that the injection method only works for constructor injection. However I thought that was what I was doing here. Am I wrong?
Edit
On further investigation, my original answer doesn't fix your problem (I've left it below for reference). The issue is that your code bypasses the LogInjectionModule by creating a new instance of DataAccess and resolving ILog directly. This is not a usage pattern that is supported by the LogInjectionModule, which is designed to provide an ILog instance that matches the type of the instance being activated by Autofac (log4net's LogManager.GetLogger() method needs to know about the type that is using the logger).
To work around this, you have two options. The simplest is to provide the logger instance directly without using the LogInjectionModule:
builder.Register(c =>
new DataAccess(
this.ConnectionString,
LogManager.GetLogger(typeof(DataAccess)))
.As<IDataAccess>();
Alternatively (and more cleanly), you can register DataAccess in the normal Autofac way, and then register IDataAccess by using named parameters to specify the connection string that Autofac passes to the constructor. With this technique, you are enabling Autofac to use the LogInjectionModule when resolving the constructor's ILog parameter.
builder.RegisterType<DataAccess>();
builder.Register(c =>
c.Resolve<DataAccess>(
new NamedParameter("connectionString", this.ConnectionString)))
.As<IDataAccess>();
(Note that this code assumes that the connection string parameter in the DataAccess constructor is named "connectionString").
The advantage of the second technique is that your module doesn't reference log4net's LogManager class directly, so the only coupling is to the ILog interface.
Original (incorrect) answer
That code sample is for Autofac v2.0 (I originally provided the sample on that wiki page). The code for my current working module (for Autofac v2.4.5) is:
public class LogInjectionModule : ComponentInjectionModule
{
/// <summary>
/// Called when Autofac is preparing a component for activation.
/// </summary>
/// <param name = "sender">
/// The sender.
/// </param>
/// <param name = "e">
/// The <see cref = "ActivatingEventArgs{T}" /> instance containing the event data.
/// </param>
protected override void OnComponentPreparing(object sender, PreparingEventArgs e)
{
Enforce.ArgumentNotNull(e, "e");
Type t = e.Component.Activator.LimitType;
e.Parameters = e.Parameters.Union(
new[]
{
new ResolvedParameter(
(p, i) => p.ParameterType == typeof(ILog), (p, i) => LogManager.GetLogger(t))
});
}
}
That code relies on my ComponentInjectionModule class which is defined below. There are some subtle differences in the way that this module hooks into the registration/activation process.
/// <summary>
/// Base module for injecting into registrations when they are prepared/activated.
/// </summary>
public class ComponentInjectionModule : IModule
{
/// <summary>
/// Apply the module to the component registry.
/// </summary>
/// <param name = "componentRegistry">
/// Component registry to apply configuration to.
/// </param>
public void Configure(IComponentRegistry componentRegistry)
{
Enforce.ArgumentNotNull(componentRegistry, "componentRegistry");
foreach (var registration in componentRegistry.Registrations)
{
this.AttachToComponentRegistration(registration);
}
componentRegistry.Registered +=
(sender, e) => this.AttachToComponentRegistration(e.ComponentRegistration);
}
/// <summary>
/// Attaches to the <see cref = "IComponentRegistration.Preparing" /> event of a component registration.
/// </summary>
/// <param name = "registration">
/// The registration whose Preparing event will be attached.
/// </param>
protected virtual void AttachToComponentRegistration(IComponentRegistration registration)
{
Enforce.ArgumentNotNull(registration, "registration");
registration.Preparing += this.OnComponentPreparing;
registration.Activating += this.OnComponentActivating;
registration.Activated += this.OnComponentActivated;
}
/// <summary>
/// Called when Autofac has activated a component.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The <see cref="ActivatedEventArgs{T}"/> instance containing the event data.</param>
[SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", Justification = "Not an event handler")]
protected virtual void OnComponentActivated(object sender, ActivatedEventArgs<object> e)
{
}
/// <summary>
/// Called when Autofac is activating a component.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The <see cref="ActivatingEventArgs{T}"/> instance containing the event data.</param>
[SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", Justification = "Not an event handler")]
protected virtual void OnComponentActivating(object sender, ActivatingEventArgs<object> e)
{
}
/// <summary>
/// Called when Autofac is preparing a component for activation.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The <see cref="ActivatingEventArgs{T}"/> instance containing the event data.</param>
[SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", Justification = "Not an event handler")]
protected virtual void OnComponentPreparing(object sender, PreparingEventArgs e)
{
}
}