How to patch public int "set" method though Harmony Patches - c#

I'm trying to patch public int "set" method taught Harmony Patches. The method I want to patch is a 7D2D function (ProgressionValue.Level). I wrote a little patch, but It doesn't work.
Method I want to patch:
public void set_Level(int value)
{
this.calculatedFrame = -1;
if (this.ProgressionClass == null)
{
this.level = value;
return;
}
if (this.ProgressionClass.IsSkill)
{
this.level = this.ProgressionClass.MaxLevel;
return;
}
this.level = value;
}
Method I wrote:
using HarmonyLib;
using UnityEngine;
namespace Undead_InstantSkillLeveling
{
[HarmonyPatch(typeof(ProgressionValue))]
[HarmonyPatch(nameof(ProgressionValue.Level))]
public class Udead_Harmony_InstantSkill
{
private static void Prefix(ProgressionValue __instance)
{
__instance.Level = __instance.ProgressionClass.MaxLevel;
}
}
}
Harmony used: Harmony

Related

Can someone explain how to fix the error?

Ok, so I found an open source script for Unity and it kinda don't want to be friends with the new input system. I have no idea how to replace InputActionAssetReference
If somebody helps - thank you. The errors are: Assets\Input\InputMaster.cs(7,28): error CS0246: The type or namespace name 'InputActionAssetReference' could not be found (are you missing a using directive or an assembly reference?) and Assets\Input\InputMaster.cs(50,26): error CS0115: 'InputMaster.MakePrivateCopyOfActions()': no suitable method found to override
I'd really like the help because I want to use this 2D platformer controller. The script:
using System;
using UnityEngine;
using UnityEngine.InputSystem;
[Serializable]
public class InputMaster : InputActionAssetReference
{
public InputMaster()
{
}
public InputMaster(InputActionAsset asset)
: base(asset)
{
}
[NonSerialized] private bool m_Initialized;
private void Initialize()
{
// Player
m_Player = asset.GetActionMap("Player");
m_Player_Movement = m_Player.GetAction("Movement");
m_Player_Jump = m_Player.GetAction("Jump");
m_Player_Dash = m_Player.GetAction("Dash");
m_Player_Interact = m_Player.GetAction("Interact");
m_Player_AttackA = m_Player.GetAction("Attack A");
m_Initialized = true;
}
private void Uninitialize()
{
if (m_PlayerActionsCallbackInterface != null)
{
Player.SetCallbacks(null);
}
m_Player = null;
m_Player_Movement = null;
m_Player_Jump = null;
m_Player_Dash = null;
m_Player_Interact = null;
m_Player_AttackA = null;
m_Initialized = false;
}
public void SetAsset(InputActionAsset newAsset)
{
if (newAsset == asset) return;
var PlayerCallbacks = m_PlayerActionsCallbackInterface;
if (m_Initialized) Uninitialize();
asset = newAsset;
Player.SetCallbacks(PlayerCallbacks);
}
public override void MakePrivateCopyOfActions()
{
SetAsset(ScriptableObject.Instantiate(asset));
}
// Player
private InputActionMap m_Player;
private IPlayerActions m_PlayerActionsCallbackInterface;
private InputAction m_Player_Movement;
private InputAction m_Player_Jump;
private InputAction m_Player_Dash;
private InputAction m_Player_Interact;
private InputAction m_Player_AttackA;
public struct PlayerActions
{
private InputMaster m_Wrapper;
public PlayerActions(InputMaster wrapper) { m_Wrapper = wrapper; }
public InputAction #Movement { get { return m_Wrapper.m_Player_Movement; } }
public InputAction #Jump { get { return m_Wrapper.m_Player_Jump; } }
public InputAction #Dash { get { return m_Wrapper.m_Player_Dash; } }
public InputAction #Interact { get { return m_Wrapper.m_Player_Interact; } }
public InputAction #AttackA { get { return m_Wrapper.m_Player_AttackA; } }
public InputActionMap Get() { return m_Wrapper.m_Player; }
public void Enable() { Get().Enable(); }
public void Disable() { Get().Disable(); }
public bool enabled { get { return Get().enabled; } }
public InputActionMap Clone() { return Get().Clone(); }
public static implicit operator InputActionMap(PlayerActions set) { return set.Get(); }
public void SetCallbacks(IPlayerActions instance)
{
if (m_Wrapper.m_PlayerActionsCallbackInterface != null)
{
Movement.started -= m_Wrapper.m_PlayerActionsCallbackInterface.OnMovement;
Movement.performed -= m_Wrapper.m_PlayerActionsCallbackInterface.OnMovement;
Movement.cancelled -= m_Wrapper.m_PlayerActionsCallbackInterface.OnMovement;
Jump.started -= m_Wrapper.m_PlayerActionsCallbackInterface.OnJump;
Jump.performed -= m_Wrapper.m_PlayerActionsCallbackInterface.OnJump;
Jump.cancelled -= m_Wrapper.m_PlayerActionsCallbackInterface.OnJump;
Dash.started -= m_Wrapper.m_PlayerActionsCallbackInterface.OnDash;
Dash.performed -= m_Wrapper.m_PlayerActionsCallbackInterface.OnDash;
Dash.cancelled -= m_Wrapper.m_PlayerActionsCallbackInterface.OnDash;
Interact.started -= m_Wrapper.m_PlayerActionsCallbackInterface.OnInteract;
Interact.performed -= m_Wrapper.m_PlayerActionsCallbackInterface.OnInteract;
Interact.cancelled -= m_Wrapper.m_PlayerActionsCallbackInterface.OnInteract;
AttackA.started -= m_Wrapper.m_PlayerActionsCallbackInterface.OnAttackA;
AttackA.performed -= m_Wrapper.m_PlayerActionsCallbackInterface.OnAttackA;
AttackA.cancelled -= m_Wrapper.m_PlayerActionsCallbackInterface.OnAttackA;
}
m_Wrapper.m_PlayerActionsCallbackInterface = instance;
if (instance != null)
{
Movement.started += instance.OnMovement;
Movement.performed += instance.OnMovement;
Movement.cancelled += instance.OnMovement;
Jump.started += instance.OnJump;
Jump.performed += instance.OnJump;
Jump.cancelled += instance.OnJump;
Dash.started += instance.OnDash;
Dash.performed += instance.OnDash;
Dash.cancelled += instance.OnDash;
Interact.started += instance.OnInteract;
Interact.performed += instance.OnInteract;
Interact.cancelled += instance.OnInteract;
AttackA.started += instance.OnAttackA;
AttackA.performed += instance.OnAttackA;
AttackA.cancelled += instance.OnAttackA;
}
}
}
public PlayerActions #Player
{
get
{
if (!m_Initialized) Initialize();
return new PlayerActions(this);
}
}
private int m_KeyboardSchemeIndex = -1;
public InputControlScheme KeyboardScheme
{
get
{
if (m_KeyboardSchemeIndex == -1) m_KeyboardSchemeIndex = asset.GetControlSchemeIndex("Keyboard");
return asset.controlSchemes[m_KeyboardSchemeIndex];
}
}
private int m_GamepadSchemeIndex = -1;
public InputControlScheme GamepadScheme
{
get
{
if (m_GamepadSchemeIndex == -1) m_GamepadSchemeIndex = asset.GetControlSchemeIndex("Gamepad");
return asset.controlSchemes[m_GamepadSchemeIndex];
}
}
}
public interface IPlayerActions
{
void OnMovement(InputAction.CallbackContext context);
void OnJump(InputAction.CallbackContext context);
void OnDash(InputAction.CallbackContext context);
void OnInteract(InputAction.CallbackContext context);
void OnAttackA(InputAction.CallbackContext context);
}
If there's too much to edit then can someone say what's the last supported version that has InputActionAssetReference?
Edited message --
I am replacing my answer without links as I have been told to. Basically instead of using InputActionAssetReference, another class like IInputActionCollection should be used. The first class must have been deprecated which is why it wasn't working properly.
Note: I have never used this new input system myself, but I am glad I was able to help! I get to learn something too which is a bonus.
InputActionAssetReference was removed at release [0.2.8-preview] - 2019-4-23
Generated wrapper code for Input Action Assets are now self-contained,
generating all the data from code and not needing a reference to the
asset; InputActionAssetReference has been removed.
link to changelog

CS1503 Argument 1: cannot convert from 'Poc.Core.Player' to 'Poc.Interfaces.IScheduleable'

sorry im newish to programming so this may be an easy solvable problem that im not knowledgeable enough to know how to fix
Im using this tutorial for a simple dungeon crawler https://bitbucket.org/FaronBracy/roguesharpv3tutorial/src/master/
when it came to implementing the behaviors of the kobolds (mutants in my project) i would get an error saying 'Argument 1: cannot convert from 'Poc.Core.(Player/monster)" to "Poc.Interface.ISchedule"
this was happening on the addplayer void, addmonster void, and removemonster void in the DungeonMap.cs and twice on the ActivateMonsters void in CommandSystem.cs
i would appreciate it so much if someone could help me fix this problem
problem voids:
public void AddPlayer(Player player)
{
Game.Player = player;
SetIsWalkable(player.X, player.Y, false);
UpdatePlayerFieldOfView();
**Game.SchedulingSystem.Add(player);**
}
public void AddMonster(Monster monster)
{
_monsters.Add(monster);
// After adding the monster to the map make sure to make the
cell not walkable
SetIsWalkable(monster.X, monster.Y, false);
**Game.SchedulingSystem.Add( monster );**
}
public void RemoveMonster(Monster monster)
{
_monsters.Remove(monster);
SetIsWalkable(monster.X, monster.Y, true);
**SchedulingSystem.Remove(monster);**
}
public void ActivateMonsters()
{
IScheduleable scheduleable = Game.SchedulingSystem.Get();
if (scheduleable is Player)
{
IsPlayerTurn = true;
**Game.SchedulingSystem.Add(Game.Player);**
}
else
{
Monster monster = scheduleable as Monster;
if (monster != null)
{
monster.PerformAction(this);
**Game.SchedulingSystem.Add(monster);**
}
ActivateMonsters();
}
}
then my Scheduling System code
namespace Poc.Systems
{
public class SchedulingSystem
{
private int _time;
private readonly SortedDictionary<int, List<IScheduleable>> _scheduleables;
public SchedulingSystem()
{
_time = 0;
_scheduleables = new SortedDictionary<int, List<IScheduleable>>();
}
public void Add(IScheduleable scheduleable)
{
int key = _time + scheduleable.Time;
if (!_scheduleables.ContainsKey(key))
{
_scheduleables.Add(key, new List<IScheduleable>());
}
_scheduleables[key].Add(scheduleable);
}
public void Remove(IScheduleable scheduleable)
{
KeyValuePair<int, List<IScheduleable>> scheduleableListFound
= new KeyValuePair<int, List<IScheduleable>>(-1, null);
foreach (var scheduleablesList in _scheduleables)
{
if (scheduleablesList.Value.Contains(scheduleable))
{
scheduleableListFound = scheduleablesList;
break;
}
}
if (scheduleableListFound.Value != null)
{
scheduleableListFound.Value.Remove(scheduleable);
if (scheduleableListFound.Value.Count <= 0)
{
_scheduleables.Remove(scheduleableListFound.Key);
}
}
}
public IScheduleable Get()
{
var firstScheduleableGroup = _scheduleables.First();
var firstScheduleable = firstScheduleableGroup.Value.First();
Remove(firstScheduleable);
_time = firstScheduleableGroup.Key;
return firstScheduleable;
}
// Get the current time (turn) for the schedule
public int GetTime()
{
return _time;
}
{
_time = 0;
_scheduleables.Clear();
}
}
}
Make sure that your Actor class, which Player and Monster inherit from, is implementing IScheduleable:
public class Actor : IActor, IDrawable, IScheduleable
{
// ... Previous Actor code omitted
// IScheduleable
public int Time
{
get
{
return Speed;
}
}
}

Converting vb to c# code

Could you help me here, this is my friend's work(actually don't know where did he get this code, it uses vb language) and i'm trying to convert the code to c#. Thought it was easy, even though i lack of c# knowledge, and i'm stacked from here. I found a vb.net to c# converter from the net, and this is the result:
*see the comment below
clsProcess.cs:
using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Drawing;
[Serializable()]
public class clsProcess : IComparable<clsProcess>
{
public int Priority
{
get { return _Priority; }
set { _Priority = value; }
}
public Color ProcessColor
{
get { return _ProcessColor; }
set { _ProcessColor = value; }
}
public double ArrTime
{
get { return _ArrTime; }
set { _ArrTime = value; }
}
public double ExeTime
{
get { return _ExeTime; }
set { _ExeTime = value; }
}
public string Label
{
get { return _Label; }
set { _Label = value; }
}
public clsProcess()
{
}
public clsProcess(int prior, double arr, double exe, string lbl, Color clr)
{
_Priority = prior;
_ArrTime = arr;
_ExeTime = exe;
_Label = lbl;
_ProcessColor = clr;
}
private double _ArrTime;
private double _ExeTime;
private string _Label;
private int _Priority;
private Color _ProcessColor;
public int CompareTo(clsProcess other)
{
switch ((modGlobals.SortColumn))
{
//The method SortType from modGlobals.cs is the error.
//Error says: The name 'SortType' does not exist in the current context
//I'm getting error from here:
case SortType.Arr:
return this.ArrTime.CompareTo(other.ArrTime);
case SortType.Exe:
return this.ExeTime.CompareTo(other.ExeTime);
case SortType.Label:
return this.Label.CompareTo(other.Label);
case SortType.Prior:
return this.Priority.CompareTo(other.Priority);
//Until here.
}
}
}
modGlobals.cs:
using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
static class modGlobals
{
public enum SortType //The error referring to.
{
Arr,
Exe,
Prior,
Label
}
public static SortType SortColumn; //I doubt it has something to do here.
public static List<clsProcess> CreateMemberwiseClone(List<clsProcess> pList)
{
List<clsProcess> tempList = new List<clsProcess>();
int i = 0;
for (i = 0; i <= pList.Count - 1; i++) {
tempList.Add(CloneProcess(pList[i]));
}
return tempList;
}
public static clsProcess CloneProcess(clsProcess process)
{
clsProcess temp = new clsProcess();
temp.ExeTime = process.ExeTime;
temp.ArrTime = process.ArrTime;
temp.Label = process.Label;
temp.Priority = process.Priority;
temp.ProcessColor = process.ProcessColor;
return temp;
}
public static void MergeBlocks(ref List<clsBlock> blocks)
{
if (blocks.Count < 2)
return;
int i = 0;
while (i < blocks.Count - 1) {
if (blocks[i].BlockCaption == blocks[i + 1].BlockCaption) {
blocks[i].BlockLength += blocks[i + 1].BlockLength;
blocks.RemoveAt(i + 1);
i -= 1;
}
i += 1;
}
}
}
Could you give me an alternate solution for here?
try
public int CompareTo(clsProcess other)
{
switch ((modGlobals.SortColumn))
{
case modGlobals.SortType.Arr:
return this.ArrTime.CompareTo(other.ArrTime);
case modGlobals.SortType.Exe:
return this.ExeTime.CompareTo(other.ExeTime);
case modGlobals.SortType.Label:
return this.Label.CompareTo(other.Label);
case modGlobals.SortType.Prior:
return this.Priority.CompareTo(other.Priority);
}
//This next part will happen if the switch statement doesnt find a match
//use this to return some default value or a value that tells you it didnt find something
//I'll use 0 as an example
return 0;
//now all paths return a value, even if it doesnt find a match in the switch statement
}
Your static class modGlobals should only have static members.
The SortType should be static.
public static enum SortType
{
Arr,
Exe,
Prior,
Label
}

Modifying List in ViewState does not persist

I have a ViewState holding a List<T>
public List<AwesomeInt> MyList
{
get { return ((List<int>)ViewState["MyIntList"]).Select(i => new AwesomeInt(i)).ToList(); }
set { ViewState["MyIntList"] = value.GetIntegers(); }
}
Now, when I call MyList.Add(new AwesomeInt(3)) let's say, the list does not persist the change.
I believe this is because the .ToList() in the get is creating a new List object and therefore the set will never be called, thus never saving in ViewState.
I have worked around this problem before by either
not calling .Select/.ToList() by saving/calling directly without a
conversion.
not using the .Add or .Remove functions and instead
re-initializing the List with an equals.
However sometimes 1. is impractical if the class is not serializable and I have no control over that, and 2. is kind of ugly because I have to copy it to a temp first, then add, then re-assign, or play around with Concat to add a single item.
Is there a better way of doing this?
Alright, below is a fully functional console application that should give you the capabilities you need. I leveraged generics so that you could build surrounding collections of whatever type necessary - but yet serialize something more rudimentary. Keep in mind I don't have a real view state to write to in the set but you can fix that up.
Also bear in mind I wrote this in a pretty short time frame (e.g. 20 minutes) so there may be optimizations that exist (e.g. the set on the ViewState property isn't really necessary generally because this solution modifies the underlying rudimentary data source).
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static List<int> _viewState = new List<int>();
static RawCollection<AwesomeInt, int> ViewState
{
get { return new RawCollection<AwesomeInt, int>(_viewState); }
set { _viewState = value.RawData; }
}
static void Main(string[] args)
{
ViewState.Add(new AwesomeInt(1));
ViewState.Add(new AwesomeInt(2));
WriteViewState();
ViewState[0].Val = 5;
WriteViewState();
ViewState.RemoveAt(0);
WriteViewState();
for (int i = 10; i < 15; i++)
{
ViewState.Add(new AwesomeInt(i));
}
WriteViewState();
}
private static void WriteViewState()
{
for (int i = 0; i < ViewState.Count; i++)
{
Console.WriteLine("The value at index {0} is {1}.", i, ViewState[i].Val);
}
Console.WriteLine();
Console.WriteLine();
}
}
public class RawCollection<T, K> : Collection<T>
{
private List<K> _data;
public RawCollection(List<K> data)
{
foreach (var i in data)
{
var o = (T)Activator.CreateInstance(typeof(T), i);
var oI = o as IRawData<K>;
oI.RawValueChanged += (sender) =>
{
_data[this.IndexOf((T)sender)] = sender.Val;
};
this.Add(o);
}
_data = data;
}
public List<K> RawData
{
get
{
return new List<K>(
this.Items.Select(
i => ((IRawData<K>)i).Val));
}
}
protected override void ClearItems()
{
base.ClearItems();
if (_data == null) { return; }
_data.Clear();
}
protected override void InsertItem(int index, T item)
{
base.InsertItem(index, item);
if (_data == null) { return; }
_data.Insert(index, ((IRawData<K>)item).Val);
}
protected override void RemoveItem(int index)
{
base.RemoveItem(index);
if (_data == null) { return; }
_data.RemoveAt(index);
}
protected override void SetItem(int index, T item)
{
base.SetItem(index, item);
if (_data == null) { return; }
_data[index] = ((IRawData<K>)item).Val;
}
}
public class AwesomeInt : IRawData<int>
{
public AwesomeInt(int i)
{
_val = i;
}
private int _val;
public int Val
{
get { return _val; }
set
{
_val = value;
OnRawValueChanged();
}
}
public event Action<IRawData<int>> RawValueChanged;
protected virtual void OnRawValueChanged()
{
if (RawValueChanged != null)
{
RawValueChanged(this);
}
}
}
public interface IRawData<T> : INotifyRawValueChanged<T>
{
T Val { get; set; }
}
public interface INotifyRawValueChanged<T>
{
event Action<IRawData<T>> RawValueChanged;
}
}

Wrap C# code as ActiveX

I write a C# class library and want to use it in vbscript.
Here is my code:
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.PointOfService;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using System.Reflection;
using System.ComponentModel;
namespace IndigoDynamic
{
#region class implements IAsyncResult
[ProgId("IndigoDynamic.VirtualManager")]
[ClassInterface(ClassInterfaceType.AutoDispatch)]
[ComVisible(true)]
public class AsyncResult : IAsyncResult
{
object _state;
private bool m_completed;
private System.Threading.ManualResetEvent m_handle;
private Exception m_exception;
public bool IsCompleted
{
get { return m_completed; }
set { m_completed = value; }
}
public System.Threading.WaitHandle AsyncWaitHandle
{
get { return m_handle; }
set { m_handle = (System.Threading.ManualResetEvent)value; }
}
public object AsyncState
{
get
{
if (Exception != null)
{
throw Exception;
}
return _state;
}
internal set
{
_state = value;
}
}
public bool CompletedSynchronously { get { return IsCompleted; } }
internal Exception Exception
{
get { return m_exception; }
set { m_exception = value; }
}
}
#endregion
#region extends CashDrawer
[ProgId("IndigoDynamic.VirtualManager")]
[ClassInterface(ClassInterfaceType.AutoDispatch)]
[ComVisible(true)]
public class MyCashDrawer
{
private CashDrawer me;
public delegate void status_callback(int newstatus);
private status_callback myF;
public MyCashDrawer(CashDrawer param)
{
me = param;
me.StatusUpdateEvent += new StatusUpdateEventHandler(this.StatusUpdate);
}
[ComVisible(true)]
public void Claim(int timeout) { me.Claim(timeout); }
[ComVisible(true)]
public void Close() { me.Close(); }
[ComVisible(true)]
public void Open() { me.Open(); }
[ComVisible(true)]
public void OpenDrawer() { me.OpenDrawer(); }
[ComVisible(true)]
public void Release() { me.Release(); }
[ComVisible(true)]
public void Release(int timeout, int freq, int duration, int delay)
{
me.WaitForDrawerClose(timeout, freq, duration, delay);
}
[ComVisible(true)]
public int StatusClosed() { return CashDrawer.StatusClosed; }
[ComVisible(true)]
public int StatusOpen() { return CashDrawer.StatusOpen; }
[ComVisible(true)]
public bool Claimed() { return me.Claimed; }
[ComVisible(true)]
public bool DeviceEnabled() { return me.DeviceEnabled; }
[ComVisible(true)]
public bool DrawerOpened() { return me.DrawerOpened; }
[ComVisible(true)]
public ControlState State() { return me.State; }
[ComVisible(true)]
public void addStatusCallback(status_callback f)
{
myF = f;
}
[ComVisible(true)]
public void removeStatusCallback(status_callback f)
{
if (myF == f)
myF = null;
}
[ComVisible(true)]
private void StatusUpdate(object sender, StatusUpdateEventArgs arg)
{
if (myF != null)
myF(arg.Status);
}
}
#endregion
[ProgId("IndigoDynamic.VirtualManager")]
[ClassInterface(ClassInterfaceType.AutoDispatch)]
[ComVisible(true)]
class VirtualManager : ISynchronizeInvoke
{
private readonly object _sync;
// Constructor
public VirtualManager()
{
_sync = new object();
}
#region implements methods of ISynchronizeInvoke
public IAsyncResult BeginInvoke(Delegate method, object[] args) {
AsyncResult result = new AsyncResult();
System.Threading.ThreadPool.QueueUserWorkItem(delegate {
result.AsyncWaitHandle = new System.Threading.ManualResetEvent(false);
try {
result.AsyncState = Invoke(method, args);
} catch (Exception exception) {
result.Exception = exception;
}
result.IsCompleted = true;
});
return result;
}
public object EndInvoke(IAsyncResult result) {
if (!result.IsCompleted) {
result.AsyncWaitHandle.WaitOne();
}
return result.AsyncState;
}
public object Invoke(Delegate method, object[] args) {
lock (_sync) {
return method.DynamicInvoke(args);
}
}
public bool InvokeRequired {
get { return true; }
}
#endregion
[ComVisible(true)]
public MyCashDrawer getCashDrawer()
{
PosExplorer posExplorer = new PosExplorer(this);
DeviceInfo deviceInfo = posExplorer.GetDevice(DeviceType.CashDrawer);
if (deviceInfo == null)
{
//<report failure >
return null;
}
else
{
CashDrawer cd = posExplorer.CreateInstance(deviceInfo) as CashDrawer;
return new MyCashDrawer(cd);
}
}
[ComVisible(true)]
public MyCashDrawer getCashDrawer(String name)
{
PosExplorer posExplorer = new PosExplorer(this);
DeviceInfo deviceInfo = posExplorer.GetDevice(DeviceType.CashDrawer, name);
if (deviceInfo == null)
{
//<report failure >
return null;
}
else
{
CashDrawer cd = posExplorer.CreateInstance(deviceInfo) as CashDrawer;
return new MyCashDrawer(cd);
}
}
[ComRegisterFunction()]
public static void RegisterClass(string key)
{
StringBuilder sb = new StringBuilder(key);
sb.Replace(#"HKEY_CLASSES_ROOT\", "");
RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(), true);
RegistryKey ctrl = k.CreateSubKey("Control");
ctrl.Close();
RegistryKey inprocServer32 = k.OpenSubKey("InprocServer32", true);
inprocServer32.SetValue("CodeBase", Assembly.GetExecutingAssembly().CodeBase);
inprocServer32.Close();
k.Close();
}
[ComUnregisterFunction()]
public static void UnregisterClass(string key)
{
StringBuilder sb = new StringBuilder(key);
sb.Replace(#"HKEY_CLASSES_ROOT\", "");
RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(), true);
if (k == null)
{
return;
}
k.DeleteSubKey("Control", false);
RegistryKey inprocServer32 = k.OpenSubKey("InprocServer32", true);
inprocServer32.DeleteSubKey("CodeBase", false);
inprocServer32.Close();
k.Close();
}
}
}
After building, I use RegAsm but it threw Warning No types are registered.
Then I write a sample code in vbs but it says ActiveX can not create Object.
Sub main
set objTest = CreateObject("IndigoDynamic.VirtualManager")
end sub
call main
Somebody said that I have to check AssemblyInfo.cs and make sure I have
[assembly: ComVisible(true)]
Of course I have, but problem is still not solved.
Can anybody tell me a solution?
I change my code like that. More simple, no threading, no interface, all is public.
But it still doesn't work.
Please, I really need help.
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.PointOfService;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using System.Reflection;
using System.ComponentModel;
namespace IndigoDynamic
{
[ProgId("IndigoDynamic.VirtualManager")]
[ClassInterface(ClassInterfaceType.AutoDispatch)]
[ComVisible(true)]
public class VirtualManager
{
public VirtualManager()
{
}
[ComVisible(true)]
public CashDrawer getCashDrawer()
{
PosExplorer posExplorer = new PosExplorer();
DeviceInfo deviceInfo = posExplorer.GetDevice(DeviceType.CashDrawer);
if (deviceInfo == null)
{
//<report failure >
return null;
}
else
{
CashDrawer cd = posExplorer.CreateInstance(deviceInfo) as CashDrawer;
return cd;
}
}
[ComVisible(true)]
public CashDrawer getCashDrawer(String name)
{
PosExplorer posExplorer = new PosExplorer();
DeviceInfo deviceInfo = posExplorer.GetDevice(DeviceType.CashDrawer, name);
if (deviceInfo == null)
{
//<report failure >
return null;
}
else
{
CashDrawer cd = posExplorer.CreateInstance(deviceInfo) as CashDrawer;
return cd;
}
}
[ComRegisterFunction()]
public static void RegisterClass(string key)
{
StringBuilder sb = new StringBuilder(key);
sb.Replace(#"HKEY_CLASSES_ROOT\", "");
RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(), true);
RegistryKey ctrl = k.CreateSubKey("Control");
ctrl.Close();
RegistryKey inprocServer32 = k.OpenSubKey("InprocServer32", true);
inprocServer32.SetValue("CodeBase", Assembly.GetExecutingAssembly().CodeBase);
inprocServer32.Close();
k.Close();
}
[ComUnregisterFunction()]
public static void UnregisterClass(string key)
{
StringBuilder sb = new StringBuilder(key);
sb.Replace(#"HKEY_CLASSES_ROOT\", "");
RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(), true);
if (k == null)
{
return;
}
k.DeleteSubKey("Control", false);
RegistryKey inprocServer32 = k.OpenSubKey("InprocServer32", true);
inprocServer32.DeleteSubKey("CodeBase", false);
inprocServer32.Close();
k.Close();
}
}
}
You are unfortunately very far removed from a workable solution. The warning is accurate, none of the classes you made [ComVisible] at creatable by a COM client. MyCashDrawer is missing the required default constructor, a COM client app cannot pass arguments to a constructor. VirtualManager isn't public and derives from an interface that's not [ComVisible]
The code is also missing the required implementations for interfaces that makes an ActiveX component work on a ActiveX host window, like IOleObject, IOleInPlaceObject, IOleInplaceActiveObject, IOleWindow, IViewObject, etcetera. Furthermore, you are exposing implementation details that an ActiveX object can't take care of, the threading model in COM is very different from the one in .NET.
You are going to need a seriously different approach. Consider deriving the visible object from System.Windows.Forms.Control, it takes care of the minimum ActiveX interface implementation requirements. And make threading your problem, don't leave it up to the client to sort it out.
The regasm warning isn't the problem.
Maybe it's beacause VirtualManager class isn't public. Try to expose your class as public.

Categories

Resources