Dynamics NAV RTC : Command Line Parameter Passing - c#

I am currently developing a system that will allow for an external piece of software to click a button and his will then execute some c#.net code that plans to call the Dynamics NAV RTC by using the following code.
Process.Start("Microsoft.Dynamics.Nav.Client.exe");
The external application contains variables that I would like to pass through to the NAV CRM.
Is there a way that i could do this by Passing the parameters like what you would with a web address similar to the way below:
Process.Start("Microsoft.Dynamics.Nav.Client.exe", "DynamicsNAV://localhost:7046/DynamicsNAV70/CRONUS%20UK%20Ltd./RunPage?Page=50000&No=10");
The above line doesn't work. I receive the followowing error:
Priming dictionary contains a key 'no' which is not allowed
Parameter name: primingDictionary
Does anyone in the community know how I could produce this functionality in a similar way?

you can use it like that:
ProcessStartInfo psi = new ProcessStartInfo("Microsoft.Dynamics.Nav.Client.exe",
"DynamicsNAV://localhost:7046/DynamicsNAV70/CRONUS%20UK%20Ltd./RunPage?Page=50000&No=10");
Process.Start(psi);
the first argument is the process itself, the secomd is the argument.
you can change them as you'd like
you can learn on the argument NAV accept here

Yes, just call the overload of Process.Start() that takes input arguments:
Process.Start("Microsoft.Dynamics.Nav.Client.exe", "DynamicsNAV://localhost:7046/DynamicsNAV70/CRONUS%20UK%20Ltd./RunPage?Page=50000&No=10");

Related

How to call "BeginDialogAsync" method using a dialog defined in Bot Framework Composer

As the title says, I have my Bot created inside the Bot Framework Composer and would like to be able to manually call (BeginDialogAsync) those dialogs in C# inside something like a bot component where I have access to DialogContext.
Some context: The whole reason why I would want this is because, for whatever reason, there doesn't seem to be a way to use the composer action "Begin a new dialog" where I can assign it a property containing the name of the Dialog I wish to Start(Even though it has an "expression" type of input). The alternative is to predefine 60 different "Begin a new dialog" actions, which is not feasible.
I have googled this extensively and have found several solutions however none of them seem to be working for the newest version of Bot Framework Composer 2.x and Bot Framework SDK 4.x
Things I have tried usually revolved around loading the ".dialog" file using ResourceExplorer. My last ditch attempt was to load and cast that ".dialog" file as AdaptiveDialog, however that just throws the error:
Could not create an instance of type Microsoft.Bot.Builder.Dialogs.Dialog. Type is an interface or abstract class and cannot be instantiated.
Sample code:
private void startDialogTest(DialogContext dc, CancellationToken cancellationToken, string dialogName)
{
var dialogResource = _resourceExplorer.GetResource($"{dialogName}.dialog");
var composerDialog = _resourceExplorer.LoadType<AdaptiveDialog>(dialogResource);
dc.Dialogs.Add(composerDialog);
dc.BeginDialogAsync(dialogName, cancellationToken: cancellationToken);
}
I understand why it happened because there is simply not enough information and it does not know what the heck to deserialize that Json into since Dialog is an abstract class.
If anybody has a sample code or a github link that does what I want I would be very grateful.
I have found a solution to my problem a few days ago.
The reason why assiging a property to "Begin a new dialog" action did not work is not because the "expression input" itself didn't work but because doing it that way skips 1 crucial step for hoping to another dialog to even work at all.
Inside that dialog json root(Click "Show code" option) you need to define an array containing the names of all dialogs you wish to be able to jump to.
Example:
Let's assume we have dialogs named TestDialogA, TestDialogB and TestDialogC.
We want dialog TestDialogA to be able to able to start TestDialogB or TestDialogC. The way to do this is to open the json code of TestDialogA and at the root define a property called "dialogs" where you will insert TestDialogB and TestDialogC, like so:
{
"$kind": "Microsoft.AdaptiveDialog",
----------------------------------------------------------- Insert Here
"dialogs": [
"TestDialogB",
"TestDialogC"
],
---------------------------------------------------------- Insert Here
"$designer": {
"id": "s8Uwor",
"name": "TestDialogA",
"comment": ""
}
This is actually what "Begin a new dialog" is suppose to do and is what it does when you manually hardcode/select a dialog but it does not do that if you send it a property containing the value of the Dialog you wish to jump to.
Likely to do with it having to know what dialog "Begin a new dialog" will jump to during compile time and not runtime as then it is too late.
This is a crucial step as without it TestDialogA does not even know that TestDialogB and TestDialogC exist. Same goes if you wish to jump to TestDialogA from TestDialogB.

How to reset a password via BAPI in a CUA environment?

I am currently developing a C# application with SAP NCo 3.
I am wondering if I could invoke BAPI into CUA and this BAPI would pass details to child system.
This field is available through Test Function Module (field "RFC target sys"), but it is unavailable directly in standard BAPIs when accessed from SAP NCo.
In ABAP, devs can use:
call function 'BAPI_USER_CHANGE' destination '<TARGET_SYS>'
Can I use something similar in NCo library?
IRfcFunction rfcs = rfcDest.Repository.CreateFunction("BAPI_USER_CHANGE");
Does anybody know how this could be achieved?
Main intent is to reset user passwords to initial ones through App(BAPI) --> CUA --> ChildSystem
Without direct access into child systems.
Hmm, it looks like you have not yet fully understood the meaning of "RFC target sys".
In SE37 "RFC target sys" you enter the name of an RFC destination, which provides details about in which SAP system you want to execute the function module. These details are then defined in SM59, where you can specify parameters like hostname, system number, client, user, password, language, etc.
In the NCo library you do the same via the Class RfcDestinationManager. Here you define the parameters (hostname, system number, client, user, password, language, etc.) of the target system in which you want to execute the function module.
So the line
"RFC target sys: TARGET_SYS"
in SE37 corresponds to a line like
RfcDestination myDest = RfcDestinationManager.GetDestination("TARGET_SYS");
in your .NET program.
And a line of ABAP code like
call function 'BAPI_USER_CHANGE' destination 'TARGET_SYS'
would then correspond to some .NET code like
RfcDestination targetSys = RfcDestinationManager.GetDestination("TARGET_SYS");
IRfcFunction bapiUserChange = targetSys.Repository.CreateFunction("BAPI_USER_CHANGE");
targetSys.Invoke(bapiUserChange);
Note: setting of the input values and error handling is omitted here.
Ok, so I found out that what I wanted to achieve is not possible with just sapnco.
But, in SAP I created function module, which calls function module and uses DESTINATION 'target_sys' to run in end system. This way I achieved what I wanted. By calling my Z_FUNC_MODULE from sapnco I pass variable target_sys and FN is called in child system of CUA.
Hope this helps to someone.

vmware .net api help vmware.vim.dll problems

Vmware's .net api reference is somewhat confusing and hard to follow. I have been able to connect to my vcenter host then get a list of esxi hosts. Then I have been able get all the running modules on the host using HostKernelModuleSystem, and probe the properties on the variable "mod"... but I am not able to figure out how to get license info, I tried creating an object lic below, trying all different kinds of "types" from vmware with the word license in the type. but, it never works it has a problem converting the line with LicenseManagerLicenseInfo lic = .... I always get the following:
"Cannot convert type 'Vmware.Vim.Viewbase' to
'Vmware.Vim.LicenseManagerLicenseInfo'"
but the declaration above it for "mod" works fine.
I have also tried:
HostLicenseConnectInfo
LicenseAssignmentManagerLicenseAssignment
LicenseManager
I am hoping someone who has worked with vmware .net api can shed some light on what i am doing wrong? I am new to C# about 1 year :) but these VMware APIs are somewhat confusing to me.
esxList = client.FindEntityViews(typeof(HostSystem), null, null, null);
foreach (HostSystem host in esxList)
{
HostKernelModuleSystem mod = (HostKernelModuleSystem)client.GetView(host.ConfigManager.KernelModuleSystem, null);
LicenseManagerLicenseInfo lic = (LicenseManagerLicenseInfo)client.GetView(host.ConfigManager.LicenseManager, null);
string name = lic.Name;
}
I'll have to go to work tomorrow to look at this ( don't have ESX and VMWare SDK for .NET at home ) but I've done a bit of this work.
I wrote a generics method that wraps FindEntityViews and takes a filter as an argument. That makes it easy to search for anything. Also I've noticed that searches come back as ManagedObjectReferences and can't be cast to the subclasses. You have to construct them passing the ManagedObjectReference as an argument.
Also I find searching for PowerCLI examples and watching the classes in the immeadiate window very help in navigating this API. It's a fairly decent SDK but they put all of the classes in a single namespace and there's lots of little style inconsistencies ( Device instead of Devices and properties that take strings instead of enums when an enum exists ).
i figured out how to do it :) , by using http://vcenter_hostname/mob I was able to walk through api better. here is what I did, plus instead of of using "host" which was type HostSystem I jused my instance of my vCenter host "client"
VMware.Vim.LicenseManager lic_manager = (VMware.Vim.LicenseManager)client.GetView(client.ServiceContent.LicenseManager, null);
LicenseManagerLicenseInfo[] lic_found = lic_manager.Licenses;
foreach (LicenseManagerLicenseInfo lic in lic_found)
{
string test = lic.Name.ToString();
string test2 = lic.LicenseKey.ToString();
}

Access commandline arguments to WPF application in separate appdomain

Is there a clean way to access the commandline arguments passed as part of an AppDomain.ExecuteAssembly call that starts a WPF application?
I'm spinning up a WPF application in a separate app domain and passing arguments to the application like so:
AppDomain moduleDomain = AppDomain.CreateDomain("Friendly Name");
moduleDomain.ExecuteAssembly(path, new[] { "arg1", "arg2" });
There's a work-around to access these arguments, since both Environment.GetCommandLineArgs() and StartupEventArgs return the commandline arguments for the original application, not the one spun up with ExecuteAssembly().
I would like to access the arguments passed to the WPF application without having to manually define a Main method, preferably using StartupEventArgs. Is there a way to do so?
Starting the WPF application in a separate process works, but has performance penalties and complicates debugging.
Tigran's comment lead me to a solution that I'm happy with, using AppDomain.SetData instead of using command line arguments. The basic outline looks like this:
AppDomain moduleDomain = AppDomain.CreateDomain("Friendly Name");
moduleDomain.SetData("arg1", "arg1Value");
moduleDomain.SetData("arg2", "arg2Value");
moduleDomain.ExecuteAssembly(path);
Then, to access the 'arguments' in the WPF app:
string arg1Value = AppDomain.CurrentDomain.GetData("arg1");
string arg2Value = AppDomain.CurrentDomain.GetData("arg2");
This works well for my use case.

C# process with an input and output file

When creating a new process you can give some StartInfo with it before you start the process.
But how would one give the input of/output to parameter.
the output to is achievable through a File.WriteAllLines() with the output of the command.
But now the following must me achieved:
C:\Windows\System32\inetsrv\appcmd.exe add site /in < iisSite.xml
But when we give the
add site /in < iisSite.xml
with the arguments method of StartInfo appcmd thinks it is a parameter for it's program.
See this error
Failed to process input: The parameter
'd:\import\iisSite.xml' must begin with a / or - (HRESULT=80070057).
So we need somehow the same parsing as the command prompt would do it.
What could be possible is something like ReadAllLines and use that as an input, but I thought maybe there is a better solution.
Any suggestions?
Thanks in advance!
Stream redirection like that is a feature of the command processor cmd. If you want to do that then you need to invoke it and send your arguments. See EDIT2 and EDIT3 in this post.
EDIT
And direct from Raymond
using < is not the way to do it. Use >
so for example: appcmd.exe add site /in > iisSiteExport.xml
and have your program spit out all the output as if it was printing to the Console

Categories