I write a small program to send fax using FAXCOMLIB .
I make a class "fax" ,here is the code :
internal class Fax
{
public void SendFax( string FileName, string FaxNumber)
{
if (FaxNumber != "")
{
try
{
FAXCOMLib.FaxServer faxServer = new FAXCOMLib.FaxServerClass();
faxServer.Connect(Environment.MachineName);
FAXCOMLib.FaxDoc faxDoc = (FAXCOMLib.FaxDoc)faxServer.CreateDocument(FileName);
faxDoc.RecipientName = "گیرنده";
faxDoc.FaxNumber = FaxNumber;
faxDoc.DisplayName = "Asa";
int Response = faxDoc.Send();
faxServer.Disconnect();
}
catch (Exception Ex) { MessageBox.Show(Ex.Message); }
}
}
}
So when i want to execute the code i got these errors:
1-Error 13 Interop type 'FAXCOMLib.FaxServerClass' cannot be embedded. Use the applicable interface instead
2-Error 12 The type 'FAXCOMLib.FaxServerClass' has no constructors defined
in your project references, expand it and select the assembly in question (whatever the name is... FAX... whatever), then right click on it and go to properties. In there you will see the "Embed Interop Type" property - change it to "False"
Related
Good Morning,
Introduction:
My problem is about C# dll and VB6. And it refers to the reason of why I can't see the values of the C# properties, but I can see the same values of those properties in my VB6 project.
Explanation:
I created a dll file and a tlb file from a Windows Form Application with VS19 (Visual Studio 2019).
I moved into Properties -> Application and I changed the "Output type" from "Windows application" to "Class Library". After, I clicked in "Assembly information" and I checked the COM visible voice at the bottom of the window that appeared when I clicked.
After that I moved in "Compilation" and checked the "Interop COM" checkbox at the bottom.
In the end I compile the solution and moved the two files in a Virtual Machine (Win XP 32bit SP3), created with Virtual Box. where there's my application developed in VB6.
In my VB6 project I can set and use properties and method of the .NET dll and I see the values (EOL and EOLs are my .NET classes).
Like this:
Vin_car_11 = Mid$(frmInput.txtVinCode.Text, 11, 1)
Select Case Vin_car_11
Case "2"
EOL.XMLPrdWsUrl = "URL" 'Brescia
Case "5"
EOL.XMLPrdWsUrl = "URL" 'Suzzara
Case "9"
EOL.XMLPrdWsUrl = "URL" 'Bolzano
End Select
EOL.Vin = frmInput.txtVinCode.Text
EOL.Van = frmInput.txtVanCode.Text
returnCode = EOLs.GetXMLFile()
Here the problem:
Why I see the value of "EOL.vin" in VB6, but I can't see the same value in C#?
Here the code of my EOL class:
public class cEOL
{
private string vin;
public string Vin
{
get
{
return this.vin;
}
set
{
this.vin = value;
}
}
}
Here the code of my EOLs class:
public class cEOLs
{
#region DICHIARAZIONI
Vehicle.AuthHeader auth;
cEOL EOL;
string result;
string errorDescr;
#endregion
#region COSTRUTTORE
public cEOLs()
{
EOL = new cEOL();
auth = new Vehicle.AuthHeader();
result = "";
errorDescr = "";
}
#endregion
#region METODO
public int GetXMLFile()
{
//chiave di autenticazione server rilasciato da EHSA (IVECO)
auth.AuthKey = "Key";
var client = new Vehicle.EOLClientsAPI4EXT { Url = EOL.XMLPrdWsUrl };
EOL.ReturnCode = client.GetProductionXML(EOL.Vin, EOL.Van, out result, out errorDescr);
EOL.Result = result;
EOL.ErrorDescr = errorDescr;
return EOL.ReturnCode;
}
#endregion
THANKS IN ADVANCE! I HOPE I WAS CLEAR IN THE EXPLANATION!
I resolved it by myself by simply creating a method that returns a string.
I recall this method in my VB6 project for setting the value of the property.
Here the method:
public string ImpostaVIN(string vin)
{
EOL.Vin = vin;
return EOL.Vin;
}
Here the call in VB6:
EOL.Vin = EOLs.ImpostaVIN(string)
I have properly overwrite commit in InstallerSetup.cs I do not wish to write the user entered value to app.config but rather I want to pass the string Context.Parameters["TESTPARAMETER"]; to another class in form1.cs on load function. I tried string test = InstallerSetup.Context.Parameters["TESTPARAMETER"];
but getting InstallerSetup.Context is null. Please Help.
InstallerSetup.cs
public static string SQLSERVERNAME = "";
public static string HMSTENANTDB;
public static string SQLLOGIN;
public static string SQLPASSWORD;
public override void Commit(IDictionary savedState)
{
base.Commit(savedState);
try
{
SQLSERVERNAME = Context.Parameters["SQLSERVERNAME"];
HMSTENANTDB = Context.Parameters["HMSTENANTDB"];
SQLLOGIN = Context.Parameters["SQLLOGIN"];
SQLPASSWORD = Context.Parameters["SQLPASSWORD"];
}
catch (Exception e)
{
MessageBox.Show("Failed to update the application configuration file : " + e.Message);
base.Rollback(savedState);
}
}
from1.cs
InstallerSetup InsSetup = new InstallerSetup();
string Vsqlserver = InsSetup.Installers.Count.ToString();
string Vtenant = "";
if (InsSetup.Context != null)
{
Vtenant = InsSetup.Context.Parameters["HMSTENANTDB"];
}
else
{
Vtenant = "context is null";
}
As far as I can tell, the issue is that the property values are not being passed into the custom action. That would be the most obvious explanation. A commentfrom the poster says:
"passed those parameters to the custom action...................................... SQLSERVERNAME = Context.Parameters["SQLSERVERNAME"];
etc...
//................there is only these 4 lines in my custom actions"
which is essentially repeating the code that was previously posted.
This is NOT passing the values into the custom action. This is retrieving values which must already have been passed into the custom action.
Assuming that the custom action has been correctly added to (typically) the install nod of the custom action, and also assuming that the property names are in a TextBoxes dialog in the install, the values must be passed in to the custom action via the CustomActionData settings. To use one example, the CustomActionData setting must be something like:
/SQLSERVERNAME=[SQLSERVERNAME]
or /SQLSERVERNAME=[EDITA1] if EDIOTA1 is being used because that's the default property name.
However there is no reference to the TextBoxes (or any other) install dialog in the original question, so it's not really clear where the value of (say) SQLSERVERNAME is supposed to come from. It may be passed in on the msiexec command line, for example.
I have implemented the IM application (name is "ContactCardDesktop.exe") as suggested by the link https://msdn.microsoft.com/en-us/library/office/jj900715(v=office.15).aspx
I have done all the registry setting per the article. but there is no call to outlook to IM application for function GetAuthenticationInfo() and GetInterface().
Even not getting the ProcessID at registry location HKCU\Software\IM Providers\ContactCardDesktop.
In outlook logs I am getting errors attached below. I have gone through to many suggestion but didn't get help much.
Please suggest the problem/solution.
Sample code for Application.
[ClassInterface(ClassInterfaceType.None)]
[ComSourceInterfaces(typeof(_IUCOfficeIntegrationEvents))]
[ProgId("LitwareClientAppObject.Class")]
[Guid("449B04AD-32A8-4D21-B0AE-8FC316E051CE"), ComVisible(true)]
public partial class LitwareClientAppObject : IUCOfficeIntegration
{
IMClient imClient;
Automation imAutomation;
public LitwareClientAppObject()
{
InitializeComponent();
imClient = new IMClient();
imAutomation = new IMClientAutomation();
}
// Implementation details omitted.
public string GetAuthenticationInfo(string _version)
{
string supportedOfficeVersion = "15.0.0.0";
// Do a simple check for equivalency.
if (supportedOfficeVersion == _version)
{
return "<authenticationinfo>";
}
else
{
return null;
}
}
public object GetInterface(string _version, OIInterface _interface)
{
IMClient imClient = new IMClient();
IMClientAutomation imAutomation = new IMClientAutomation();
switch (_interface)
{
case OIInterface.oiInterfaceILyncClient:
{
return imClient;
}
case OIInterface.oiInterfaceIAutomation:
{
return imAutomation;
}
default:
{
throw new NotImplementedException();
}
}
}
public OIFeature GetSupportedFeatures(string _version)
{
OIFeature supportedFeature1 = OIFeature.oiFeatureQuickContacts;
OIFeature supportedFeature2 = OIFeature.oiFeatureFastSearch;
return (supportedFeature1 | supportedFeature2);
}
Errors like:
CMsoIMProviderFactory::HrEnsureDefaultIMAppRegKeys Succeeded opening reg key (HKCU:SOFTWARE\IM Providers)
CMsoIMProviderFactory::HrEnsureDefaultIMAppRegKeys Succeeded querying reg key (HKCU:SOFTWARE\IM Providers:DefaultIMApp:ContactCardDesktop)
CMsoIMProviderFactory::HrEnsureDefaultIMProcessRegKey Succeeded opening reg key (HKCU:SOFTWARE\IM Providers\ContactCardDesktop)
CMsoIMProviderFactory::HrEnsureDefaultIMProcessRegKey Succeeded opening reg key (HKLM:SOFTWARE\IM Providers\ContactCardDesktop)
CMsoIMProviderFactory::WhichMessengerInProcessList Using (ContactCardDesktop.exe) process name for search
CMsoIMProviderFactory::WhichMessengerInProcessList Using (ContactCardDesktop.exe) process name for search hr = 80040154, We couldn't identify the provider type we now try to manually CoCreate using the LCClient CLSID
CMsoIMProviderFactory::HrGetAvailableProvider !failed! Line: 409 hr = 0x80040154 hr = 80040154, We couldn't identify the provider type we now try to manually CoCreate using the LCClient CLSID
CMsoIMProviderFactory::HrGetAvailableProvider !failed! Line: 289 hr = 0x80004005 !!!Provider Initialization Failed!!!
I have solved this issue to use COM server "CSExeCOMServer" that is at https://code.msdn.microsoft.com/windowsapps/CSExeCOMServer-3b1c1054
We're creating a WPF app in which we execute python scripts from different Test Stations and show the output in its corresponding output panel, To run the scripts in parallel we are using Task but when we run the scripts in parallel from the stations, We are getting the output of other stations also into the station that is started first, we're using the following code,
private void ZmqStatusListener(string endPoint)
{
using (Context context = new Context())
{
StatusPort = string.Empty;
TestResultPort = string.Empty;
using (Socket server = context.Socket(SocketType.REP))
{
try
{
if (isStatusContextActive == false || isPortChanged == true)
{
server.Bind(endPoint);
isStatusContextActive = true;
}
}
catch (ZMQ.Exception ex)
{
if (ex.Errno != 100)
{
string IPCPort = _globalParameters.GlbParam.GlbParamIpcStartPort;
if (IPCPort == string.Empty)
{
IPCPort = "0";
}
if (endPoint == EditorConstants.PortAddress.PortPrefix + IPCPort)
{
StatusPort = endPoint;
TestReultError = EditorConstants.CommonMessageTypes.TestReultError + ex.Message + EditorConstants.CommonMessageTypes.StackTraceMessage + ex.StackTrace;
}
StopExecOfScript(default(object));
isCancelledtask = true;
ScriptStatusDesc = new ScriptStatusDesc()
{
Status = "Failed",
statusDescription = "Failed"
};
}
}
while (true)
{
string message = server.Recv(Encoding.UTF8);
UpdateTestResults(message);
server.Send(" ACK", Encoding.UTF8);
// if (message == "Test Passed")
//break;
}
}
}
}
and for testing purpose we're breaking the while loop in this code based on a test message we kept in the python script, then we are able to get the output in the respective station correctly but this way we can only run in a synchronous fashion which we don't want as we require to run the test stations in parallel and the while loop should not break as it should be listening for the response.
We were able to solve the issue by getting clues doing a sample app to reproduce the issue and to first know whether our ClrZmq pattern was correct for us or not and it is correct. The resolution we followed is that when we needed to bind that data to its corresponding View's Model object in its ViewModel so had to retrieve View's DataContext which is of Type ISomeXViewModel for the particular TestStation using an Id of that TestStation we did this cos all of our TestStations are dynamically added and we even store it to be accessed wherever necessary. This issue was caused to due multiple instances of UserControls so we explicitly needed to update the TestStation manually with a little more effort.
Sample Code Snippet
private void BindTestResult(string xmlPayLoad)
{
// converting xmlPalLoad to a class/model object
ITestStationViewModel viewModel = (ITestStationViewModel)((IView)DynamicTestStationsGrid.Children[StationNumber].Content).DataContext;
// IView class has DataContext property so I am type casting the Content which is ContentControl to IView type first and later to ITestStationViewModel
viewModel.TestStationModel = xmlPayLoadModel;
}
Thanks.
My code:
public class CLASS_A {
public static Dictionary<int, CLASS_A> List = new Dictionary<int, CLASS_A>;
public static PP_CLASS pp = null;
public static CLASS_A ID
{
get
{
int key = get_threadID;
if (List.ContainsKey(key))
return List[key];
else
return null;
}
set
{
int key = get_threadID;
List[key] = value;
}
}
public virtual void init(lib, name)
{
...
if (name != "")
{
if (pp == null)
PP = this;
}
...
}
}
So whichever thread calls init, it's id is used to store this (whoever called). Eg my list looks like this:
45 = CLASS_A_object0
67 = CLASS_A_object1
...
But now when a different thread calls a method on pp, say CLASS_A.pp.setWelcome, this will return null for pp, and throws null exception! Because when set is called the thread id will be different and won't be in the list.
So is it possible that I know which object called so that I can do reverse lookup? Or maybe a different solution?
Why I want this:
Initially we were connecting to one device so that was ok. Now there are multiple devices with each one having its own ip/port. Initial code had just public static PP_CLASS pp = null; So others will be just calling methods on pp using class name and things were good.
Previous behaviour: The software picks list of devices from a file and since pp is static it only talks to the first device. I added that pp==null line which i forgot in my initial post. So when the code starts pp==null will be true and first device is assigned, but now for other devices pp==null will be false and thus I am not able to talk to other devices.
Please let me know if more details are needed.
Beginning with C# 5.0 (August 2012) there is a new feature "Caller Info Attribute". If your classes are stored in separate files, you can make use of the CallerFilePathAttribute to register which class actually has called.
Example from MSDN:
// using System.Runtime.CompilerServices
// using System.Diagnostics;
public void DoProcessing()
{
TraceMessage("Something happened.");
}
public void TraceMessage(string message,
[CallerMemberName] string memberName = "",
[CallerFilePath] string sourceFilePath = "",
[CallerLineNumber] int sourceLineNumber = 0)
{
Trace.WriteLine("message: " + message);
Trace.WriteLine("member name: " + memberName);
Trace.WriteLine("source file path: " + sourceFilePath);
Trace.WriteLine("source line number: " + sourceLineNumber);
}
// Sample Output:
// message: Something happened.
// member name: DoProcessing
// source file path: c:\Users\username\Documents\Visual Studio 2012\Projects\CallerInfoCS\CallerInfoCS\Form1.cs
// source line number: 31
You could try examining the Stack Trace.
var trace = new System.Diagnostics.StackTrace();
or to get the calling line only it should be something like:
var caller = new System.Diagnostics.StackTrace().GetFrame(1)