I am working in a project that's already built and functional at the moment. But there is an issue when I try to insert finger print from device to database table. Let me write it was working fine earlier. But when I setup a new computer or moved the project in a new environment, it throws an exception:
Retrieving the COM class factory for component with CLSID {00853A19-BD51-419B-9269-2DABE57EB61F}
failed due to the following error: 80040154 Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG)).
This is a fingerprint attendance system that uses ZkemKeeper and the dll file is attached with the project. Here is the code snippet:
/**This is a list of the users from database that uses fingerprint system - Starts**/
List<AttMachineBO> lstfrom = new List<AttMachineBO>();
for (int i = 0; i < dgv_Machine.Rows.Count; i++)
{
if (dgv_Machine.Rows[i].Cells[0].Value == null)
{
dgv_Machine.Rows[i].Cells[0].Value = false;
}
if ((bool)dgv_Machine.Rows[i].Cells[0].Value == true)
{
AttMachineBO obj = new AttMachineBO();
obj.Mechine_No = dgv_Machine.Rows[i].Cells[1].Value.ToString();
obj.Machine_Name = dgv_Machine.Rows[i].Cells[2].Value.ToString();
obj.IP_Address = dgv_Machine.Rows[i].Cells[3].Value.ToString().Trim();
lstfrom.Add(obj);
}
}
/**This is a list of the users from database that uses fingerprint system - Ends**/
Basically the above code is to load user details from table assigned with an IP address and on click, the fingerprint data will be inserted into database table from attendance device (ZKTeco i-clock 580). For inserting data, the below is code is used:
if (lstfrom.Count > 0)
{
for (int x = 0; x < lstfrom.Count; x++)
{
/Here the exception starts/
**zkemkeeper.CZKEMClass fromM = new zkemkeeper.CZKEMClass();**
lblStatus.Text = "Connect To Device " + lstfrom[x].Machine_Name + " , IP=" + lstfrom[x].IP_Address + ".....";
lblStatus.Refresh();
if (fromM.Connect_Net(lstfrom[x].IP_Address, 4370))
{
lblStatus.Text = "Register The Device To PC";
lblStatus.Refresh();
if (fromM.RegEvent(fromM.MachineNumber, 65535))
{
lblStatus.Text = "Reading All Data From Machine";
lblStatus.Refresh();
fromM.ReadAllTemplate(fromM.MachineNumber);
List<AttMachineBO> datalst = new List<AttMachineBO>();
string empId = "", name = "", fingerprintData = "", fingerprintData2 = "", password = ""; ;
int prev = 0, TmpLength = 0;
bool isEnable = false;
int k = 0;
while (fromM.SSR_GetAllUserInfo(fromM.MachineNumber, out empId, out name, out password, out prev, out isEnable))
{
lblStatus.Text = "Processing Employee with ID=" + empId + ", Name =" + name;
lblStatus.Refresh();
AttMachineBO bo = new AttMachineBO();
bo.EMP_ID = empId;
bo.EMP_Name = name;
bo.IsfingerSaa = true;
bo.IP_Address = lstfrom[x].IP_Address;
bo.Com_Id = HRMS.MAIN.HRMS.Company;
bool f = fromM.SSR_GetUserTmpStr(fromM.MachineNumber, empId, 0, out fingerprintData, out TmpLength);
bo.finger1 = fingerprintData != null ? fingerprintData : "";
f = fromM.SSR_GetUserTmpStr(fromM.MachineNumber, empId, 1, out fingerprintData, out TmpLength);
bo.finger2 = fingerprintData != null ? fingerprintData : "";
datalst.Add(bo);
}
bool flag = Facede.Attendance.InserDatabase(datalst);
if (flag)
{
MessageBox.Show("Insert Successfully.");
return;
}
else
{
MessageBox.Show("Error In Insert.");
return;
}
}
else
{
lblStatus.Text = "Device registration failed.";
lblStatus.Refresh();
}
}
else
{
lblStatus.Text = "Failed to stablish connecting to device =" + lstfrom[x].Machine_Name + ", IP =" + lstfrom[x].IP_Address + "...."; ;
lblStatus.Refresh();
}
}
}
I've highlighted in the code (Second code section) from the exception starts and bit confused how to resolve it.
The error that you are receiving is clear, zkemkeeper.dll needs to be registered on the windows system.
I don´t know if you already have all the dll files... In case that you don´t have all the dll files you should download the latest SDK version from the following link https://www.zkteco.eu/uploads/ftp/SDK/Standalone%20SDK-Ver6.3.1.34.rar
To avoid troubleshooting, you should register the 32-bit version instead of the 64-bit and compile your application for the x86 architecture.
For registering the dll, copy the contents of the 32-bit folder into c:\windows\system (or c:\windows\syswow64 if your computer is x64) and after that, open the console with admin privileges, position in the folder in which you have just copied the dll and run the following command:
regsvr32 zkemkeeper.dll
After registering the files, you need to adjust the reference to this dll.
In visual studio, delete your current reference and Add a new one in the affected project. You will find the new registered dll at the bottom of the COM tab.
After adding the reference, you need to adjust one parameter. Select the reference and right-click -> properties, it will open the properties window.. Set "Embed interop types" to false.
That should work.
Related
I am able to schedule a webi report using C#. But can't able to pass prompt/parameter into the report. Please help
public string GetReport(int _reportId)
{
EnterpriseSession ceSession = EntSession;
EnterpriseService ceEnterpriseService;
InfoStore ceInfoStore;
CrystalDecisions.Enterprise.InfoObjects ceReportObjects;
CrystalDecisions.Enterprise.InfoObject ceReportObject;
Report ceReport;
string sQuery;
try
{
//grab the Enterprise session
if (ceSession != null)
{
// ceSession = (EnterpriseSession)Session["ceSession"];
//Create the infostore object
ceEnterpriseService = ceSession.GetService("", "InfoStore");
ceInfoStore = new InfoStore(ceEnterpriseService);
//Create query to grab the desired report
sQuery = "Select top 1 SI_ID, SI_PROCESSINFO.SI_PROMPTS,* From CI_INFOOBJECTS Where SI_ID=" + _reportId + " AND SI_INSTANCE=0 ";
ceReportObjects = ceInfoStore.Query(sQuery);
//check for returned reports
if (ceReportObjects.Count > 0)
{
ceReportObject = ceReportObjects[1];
//ceReport = (Report)ceReportObject;
//Create an interface to the scheduling options for the report.
CrystalDecisions.Enterprise.SchedulingInfo ceSchedulingInfo;
ceSchedulingInfo = ceReportObject.SchedulingInfo;
//run the report right now
ceSchedulingInfo.RightNow = true;
//run the report once only
ceSchedulingInfo.Type = CeScheduleType.ceScheduleTypeOnce;
//When scheduling to all destinations except the printer, you must first retrieve
//the appropriate destination object. Each destination InfoObject is stored in the
//CMS system table (CI_SYSTEMOBJECTS) under the Destination Plugins folder
//Retrieve the DiskUnmanaged Plugin from CI_SYSTEMOBJECTS
CrystalDecisions.Enterprise.InfoObjects ceDestinationObjects;
CrystalDecisions.Enterprise.InfoObject ceDestinationObject;
ceDestinationObjects = ceInfoStore.Query("Select * from CI_SYSTEMOBJECTS Where SI_NAME = 'CrystalEnterprise.DiskUnmanaged'");
ceDestinationObject = ceDestinationObjects[1];
//ReportFormatOptions ceReportFormatOpts;
//ceReportFormatOpts = ceReportObject.ReportFormatOptions;
//Create the DestinationPlugin object
DestinationPlugin ceDisk = new DestinationPlugin(ceDestinationObject.PluginInterface);
DiskUnmanagedOptions ceDiskOpts = new DiskUnmanagedOptions(ceDisk.ScheduleOptions);
ceDiskOpts.DestinationFiles.Add(#"" + Utility.BO.BOReportFolder + DateTime.Now.ToString("yyyy_MM_dd") + "_" + ceReportObject.Title.ToString() + ".pdf");
CrystalDecisions.Enterprise.Destination ceDestination;
ceDestination = ceSchedulingInfo.Destination;
ceDestination.SetFromPlugin(ceDisk);
List<string> reportParameterList = new List<string>();
Report rpt = ceReportObject as Report;
if (rpt != null)
{
//for each (CrystalDecisions.Enterprise.Desktop.Internal.ISReportParameter parameter in (CrystalDecisions.Enterprise.Desktop.Internal.ISReportParameter)rpt.ReportParameters)
//{
// reportParameterList.Add(new ReportParameter(parameter));
//}
for (int i = 0; i < rpt.ReportParameters.Count; i++)
{
rpt.ReportParameters[i].DefaultValues[0].SingleValue.Value = "";
// ISReportParameter isp =(ISReportParameter) rpt.ReportParameters[i];
// reportParameterList.Add(rpt.ReportParameters[i].ToString());
}
}
//ReportParameters ceParameters;
//ReportParameterValue ceParamValue;
//ReportParameters rpt = ceReportObject as ReportParameters ;
//if (rpt != null)
//{
// //ceParameters = ((Report)ceReportObject).ReportParameters;
// foreach (ReportParameter ceParameter in rpt.ReportParameters)
// {
// ceParamValue = ceParameter.CreateSingleValue();
// // ceParamValue.SingleValue.Value = "Time(12,15,15)";
// //ceParameter.CurrentValues.Add(ceParamValue);
// }
//}
//schedule report
ceInfoStore.Schedule(ceReportObjects);
return "Report Scheduled Successfully with an Object ID of : " + ceDestinationObject.ID.ToString()
+ "<br>Report Scheduled to the following location: " + ceDiskOpts.DestinationFiles[1].ToString();
}
}
else
{
//no Enterprise session available
return ("No Valid Enterprise Session Found!<br>"
+ "Please click <a href='Index.aspx'>here</a> to return to the logon page.<br>");
}
}
catch (Exception err)
{
throw new Exception(
"There was an error scheduling the report: <br>" +
err.Message.ToString() + "<br>" +
"Please click <a href='Index.aspx'>here</a> to return to the logon page.<br>");
}
return "";
}
Please help to pass paramater to WEBI Report.
I got response from SAP Team
In BI4.0, ReportEngine is deprecated for scheduling webi report with prompt, the replacement solution is RESTful Web Service SDK.
You can check detailed description in the link: https://blogs.sap.com/2014/03/13/migration-guide-for-businessobjects-enterprise-sdk-custom-applications/
About the RESTful Web Service SDK, you can find more useful information in this link: https://archive.sap.com/documents/docs/DOC-51800
I’m working on an ASP webpage that uses a Minitab DCOM object. My problem is that this DCOM object stops responding (hangs) if the Identity is set as “This User” under Component Services (DCONCNFG) but if I log into windows with the user that I used under “This User” and set the Identity as “Interactive user” everything works fine.
My question is what is different between DCOM Identity “The interactive user” and “This user” if the username is the same (Administrator)?
Mainly this webpage uses Minitab to generate graphs. Before it hangs it does generate graphs but only 5 or 6 graphs then it stops responding.
Here is the C# code incase you are wondering where it hangs:
using System;
using System.Web;
using System.Web.UI.WebControls;
using Mtb; // Minitab Library (Mtb 16.0 Type Library)
using System.IO;
using System.Data;
using System.Runtime.InteropServices;
using System.Threading;
namespace TRWebApp.TestDetails
{
public partial class TestDetails : System.Web.UI.Page
{
// MiniTab Stuff
Mtb.IApplication g_MtbApp;
Mtb.IProject g_MtbProj;
Mtb.IUserInterface g_MtbUI;
Mtb.IWorksheets g_MtbWkShts;
Mtb.ICommands g_MtbCommands;
Mtb.IOutputs g_MtbOutputs;
Mtb.IGraph g_MtbGraph;
Mtb.IOutputs g_MtbOutputs2;
Mtb.IGraph g_MtbGraph2;
int g_GraphIdx = 1;
int g_Loop = 1;
// Tests Table
enum testsTable { TestIdx, TestSeq, ParamName, LSL, USL, Units };
Tools tools = new Tools();
string g_SessionID = "";
Mtb_DataSetTableAdapters.XBarTableAdapter xbarTA = new Mtb_DataSetTableAdapters.XBarTableAdapter();
protected void Page_Init(object sender, EventArgs e)
{
g_MtbApp = new Application();
g_MtbProj = g_MtbApp.ActiveProject;
g_MtbUI = g_MtbApp.UserInterface;
g_MtbWkShts = g_MtbProj.Worksheets;
g_MtbCommands = g_MtbProj.Commands;
g_MtbUI.DisplayAlerts = false;
g_MtbUI.Interactive = false;
g_MtbUI.UserControl = false;
lblProductDesc.Text = ""; // Start with a clear variable
g_SessionID = HttpContext.Current.Session.SessionID;
string imgFolder = "Images/Mtb/";
string mtbSessionPath = Server.MapPath(ResolveUrl("~/" + imgFolder)) + g_SessionID;
Directory.CreateDirectory(mtbSessionPath);
Array.ForEach(Directory.GetFiles(mtbSessionPath), File.Delete); // Delete all the files from the directory
Session["MtbSessionPath"] = mtbSessionPath; // Store the Session Path so we can later delete it
// Add the two image columns to the grid view
GridView1.AutoGenerateColumns = false;
ImageField imgColumn = new ImageField();
imgColumn.HeaderText = "Scatterplot";
imgColumn.DataImageUrlField = "TestIdx";
imgColumn.DataImageUrlFormatString = "~\\Images\\Mtb\\" + g_SessionID + "\\{0}.GIF";
imgColumn.ControlStyle.CssClass = "MtbImgDetail";
GridView1.Columns.Add(imgColumn);
ImageField img2Column = new ImageField();
img2Column.HeaderText = "Histogram";
img2Column.DataImageUrlField = "TestIdx";
img2Column.DataImageUrlFormatString = "~\\Images\\Mtb\\" + g_SessionID + "\\H{0}.GIF";
img2Column.ControlStyle.CssClass = "MtbImgDetail";
GridView1.Columns.Add(img2Column);
}
protected void Page_Load(object sender, EventArgs e)
{
try
{
lblErrMsg.Text = "";
// Fill dates if they are empty
if (String.IsNullOrEmpty(tbxFromDate.Text))
tbxFromDate.Text = String.Format("{0:MM/01/yy}", DateTime.Today, null, DateTime.Today);
if (String.IsNullOrEmpty(tbxToDate.Text))
tbxToDate.Text = String.Format("{0:MM/dd/yy}", DateTime.Today);
}
catch (Exception ex)
{
lblErrMsg.Text = ex.Message;
}
}
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowIndex >= 0)
{
// Get the data for the parameter name
DataTable dt = xbarTA.GetXBarData(lbxProduct.SelectedValue, Convert.ToDateTime(tbxFromDate.Text), Convert.ToDateTime(tbxToDate.Text), e.Row.Cells[(int)testsTable.ParamName].Text);
// Pass the data to an object array so we can pass it to minitab
object[] data = new object[dt.Rows.Count];
object[] time = new object[dt.Rows.Count];
int i = 0;
foreach (DataRow dr in dt.Rows)
{
if (tools.IsNumeric(dr["ParamValue"]))
{
data[i] = Convert.ToDouble(dr["ParamValue"]);
time[i] = i;
}
i++;
}
if (dt.Rows.Count > 1) // Do graphs with at least two measurements
{
// Only pass it to minitab if we have numeric data
if (!ReferenceEquals(data[0], null)) // if it is not null it means it has a numeric value
{
g_MtbWkShts.Item(1).Columns.Add().SetData(data);
g_MtbWkShts.Item(1).Columns.Add().SetData(time);
g_MtbWkShts.Item(1).Columns.Item(1).Name = e.Row.Cells[(int)testsTable.ParamName].Text + " (" + e.Row.Cells[(int)testsTable.Units].Text + ")";
g_MtbWkShts.Item(1).Columns.Item(2).Name = "Time";
//// H E R E
////
//// FOLLOWING LINE HANGS AFTER GENERATING 6 GRAPHS WHEN THE IDENTITY "THIS USER" IS SET
////
g_MtbProj.ExecuteCommand("Plot C1*C2;\nSymbol;\nConnect.", g_MtbWkShts.Item(1));
// Convert LSL and USL to Decimal
if (tools.IsNumeric(e.Row.Cells[(int)testsTable.LSL].Text.Trim()) && tools.IsNumeric(e.Row.Cells[(int)testsTable.USL].Text.Trim()))
{
if (Convert.ToDouble(e.Row.Cells[(int)testsTable.LSL].Text) < Convert.ToDouble(e.Row.Cells[(int)testsTable.USL].Text))
{
g_MtbProj.ExecuteCommand("Capa C1 " + dt.Rows.Count.ToString() + ";\nLspec " + e.Row.Cells[(int)testsTable.LSL].Text + ";\nUspec " + e.Row.Cells[(int)testsTable.USL].Text + ";\nPooled;\nAMR;\nUnBiased;\nOBiased;\nToler 6;\nWithin;\nOverall;\nCStat.", g_MtbWkShts.Item(1));
}
else
{
g_MtbProj.ExecuteCommand("Histogram C1;\nBar;\nDistribution;\nNormal.", g_MtbWkShts.Item(1));
}
}
else
{
g_MtbProj.ExecuteCommand("Histogram C1;\nBar;\nDistribution;\nNormal.", g_MtbWkShts.Item(1));
}
try
{
g_MtbOutputs = g_MtbCommands.Item(g_GraphIdx).Outputs;
g_GraphIdx++;
g_MtbOutputs2 = g_MtbCommands.Item(g_GraphIdx).Outputs;
g_GraphIdx++;
string graphPath = "";
if (g_MtbOutputs.Count > 0)
{
g_MtbGraph = g_MtbOutputs.Item(1).Graph;
graphPath = Server.MapPath(ResolveUrl("~/Images/Mtb/")) + g_SessionID + Path.DirectorySeparatorChar + e.Row.Cells[(int)testsTable.TestIdx].Text + ".gif";
g_MtbGraph.SaveAs(graphPath, true, MtbGraphFileTypes.GFGIF, 600, 400, 96);
}
if (g_MtbOutputs2.Count > 0)
{
g_MtbGraph2 = g_MtbOutputs2.Item(1).Graph;
graphPath = Server.MapPath(ResolveUrl("~/Images/Mtb/")) + g_SessionID + Path.DirectorySeparatorChar + "H" + e.Row.Cells[(int)testsTable.TestIdx].Text + ".gif";
g_MtbGraph2.SaveAs(graphPath, true, MtbGraphFileTypes.GFGIF, 600, 400, 96);
}
}
catch (Exception ex)
{
lblErrMsg.Text = "Test Idx: " + e.Row.Cells[(int)testsTable.TestIdx].Text + " seems to have problems.<BR />Error: " + ex.Message;
}
g_MtbWkShts.Item(1).Columns.Delete(); // Delete all the columns (This line of code is needed otherwise the Mtb.exe will still running on the server side task manager
}
else
{
// Copy the No numeric image as a graph
File.Copy(Server.MapPath("~\\Images\\Mtb\\NaN.gif"), Server.MapPath("~\\Images\\Mtb\\" + g_SessionID + "\\" + e.Row.Cells[(int)testsTable.TestIdx].Text + ".gif"));
File.Copy(Server.MapPath("~\\Images\\Mtb\\NaN.gif"), Server.MapPath("~\\Images\\Mtb\\" + g_SessionID + "\\H" + e.Row.Cells[(int)testsTable.TestIdx].Text + ".gif"));
}
}
}
}
protected void GridView1_Unload(object sender, EventArgs e)
{
// All these lines of code are needed otherwise the Mtb.exe will not be close on the task manager (server side)
GC.Collect();
GC.WaitForPendingFinalizers();
if (g_MtbGraph != null)
Marshal.ReleaseComObject(g_MtbGraph); g_MtbGraph = null;
if (g_MtbOutputs != null)
Marshal.ReleaseComObject(g_MtbOutputs); g_MtbOutputs = null;
if (g_MtbGraph2 != null)
Marshal.ReleaseComObject(g_MtbGraph2); g_MtbGraph2 = null;
if (g_MtbOutputs2 != null)
Marshal.ReleaseComObject(g_MtbOutputs2); g_MtbOutputs2 = null;
if (g_MtbCommands != null)
Marshal.ReleaseComObject(g_MtbCommands); g_MtbCommands = null;
if (g_MtbWkShts != null)
Marshal.ReleaseComObject(g_MtbWkShts); g_MtbWkShts = null;
if (g_MtbUI != null)
Marshal.ReleaseComObject(g_MtbUI); g_MtbUI = null;
if (g_MtbProj != null)
Marshal.ReleaseComObject(g_MtbProj); g_MtbProj = null;
if (g_MtbApp != null)
{
g_MtbApp.Quit();
Marshal.ReleaseComObject(g_MtbApp); g_MtbApp = null;
}
}
}
}
I'm using:
Windows Server 2008 R2 Standard (SP 1)
IIS 7.5.7600.16385
Framework 4.0.30319
Visual Studio 2010 Version 10.0.30319.1
Minitab 16.1.0
Thank you,
Pablo
Just a guess, based on something that happened to me ages ago:
For some reason, Minitab is displaying a modal error dialog of some kind. When you configure DCOM to launch as some user (not the interactive user), the process gets its own "windows station" which is not actually visible to you as the logged in user. So there is a dialog popped up somewhere invisible, waiting for input forever, hence the hang. Why the dialog is displaying is a different matter, likely a permissions issue. Sometimes, certain parts of the registry are available or not available in different activation contexts, for example.
Thanks Jlew for the link. It helped me to solve the problem by changing a register value from “Shared Section=1024,20480,768” to “Shared Section=1024,20480,2304” (3 times bigger) on this register key: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\SubSystems\Windows
This value specifies a memory heap size when the user is not logged on. I guess it was not enough to handle all the MiniTab graphs.
Pablo
I am trying to create a shortcut to a folder that my program creates when the user adds a profile to the device. The shortcut link to the folder and is supposed to appear in the users Favorites (the library to the side in Windows 7 Explorer) and have the logo.ico from our project. I thought I had to use the IWshRuntimeLibrary, but the code randomly stops on me and does not return any errors... any help?
Note: The profilePath, profileName, and executablePath all return the correct data and point to the correct locations for the items I am trying to access and modify.
public static bool CreateProfileShortcut(string profilePath, string profileName, string executablePath)
{
bool success = false;
string favoritesPath = "";
IWshRuntimeLibrary.IWshShell wsh;
IWshRuntimeLibrary.IWshShortcut shortcut;
try
{
if (!String.IsNullOrWhiteSpace(profilePath) && Directory.Exists(profile.Path))
{
favoritesPath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
if (!File.Exists(favoritesPath + "\\Links\\" + profileName + ".lnk"))
{
wsh = new IWshRuntimeLibrary.WshShell();
shortcut = (IWshRuntimeLibrary.IWshShortcut)wsh.CreateShortcut(favoritesPath + "\\Links\\" + profileName + ".lnk");
shortcut.TargetPath = profilePath;
shortcut.IconLocation = executablePath + "\\Icons\\logo.ico";
shortcut.Save();
}
}
}
catch (Exception e)
{
MessageBox.Show(MessageBoxError(new string[] { e.TargetSite.Name, e.Message, "MinorError" }));
success = false;
}
return success;
}
Try looking at both this question and this question. If I'm understanding, I think you want to be able to create a shortcut in the "favorite" area of Windows 7.
I am having some problems with a piece of code, I am trying to import data from a source (at this time an access database) into a custom form but i keep getting the above error.
When i use a VBscript inside the source database all contacts import correctly.
When i repair the PST it still gives this error.
When i add a delay of 450 ms. the error also occurs but later on in the process.
Having Outlook opened or closed does not matter.
I am using the following method
string[] arrFolders = strFolders.Split('\\');
Outlook.Application app = null;
Outlook.MAPIFolder folder = null;
try {
app = new Outlook.Application();
folder = app.GetNamespace("MAPI").Folders[arrFolders[0]];
} catch (Exception ex) {
writeLogLine("Error creating Outlook instance: " + ex.Message);
MessageBox.Show("Error creating Outlook instance\r\n" + ex.Message);
intErrorCount++;
blnHasErrors = true;
blnAbort = true;
}
try {
for (int i = 1; i < arrFolders.Length; i++) {
folder = folder.Folders[arrFolders[i]];
}
} catch (Exception ex) {
writeLogLine("Error navigating to DRM folder: " + ex.Message);
MessageBox.Show("Error navigating to DRM folder\r\n" + ex.Message);
intErrorCount++;
blnHasErrors = true;
blnAbort = true;
}
setProgressbarMaximum(dtResults.Rows.Count);
setProgressbarMode(ProgressBarStyle.Continuous);
//int intRowCount = 0;
foreach (DataRow drItem in dtResults.Rows) {
if (strDRMType == "Contact") {
try {
Outlook.ContactItem x = (Outlook.ContactItem)folder.Items.Add("IPM.Contact." + strFormName);
for (int i = 0; i < arrMappings.GetLength(0); i++) {
if (arrMappings[i, 1] != null && drItem[arrMappings[i, 0]].ToString() != "") {
x.UserProperties[arrMappings[i, 1]].Value = drItem[arrMappings[i, 0]].ToString();
}
}
x.Save();
} catch (Exception ex) {
writeLogLine("Error importing contact: " + ex.Message);
intErrorCount++;
blnHasErrors = true;
}
}
as i said, when i loop the code it will throw exceptions after 100 to 200 contacts, when i add a delay it will get to contact 400/500 before failing.
This code is supposed to be for a generic import tool for this specific form so there is no need for hardcoding the source column names to the form fields in the import code.
Any help is appreciated.
I'm assuming this is not an Outlook add-in, since you say it doesn't matter if OL is open or closed, right?
One thing you may want to do is ensure you are releasing the COM objects once you are done with them, using System.Runtime.InteropServices.Marshal.ReleaseComObject(...). Also, when you use dot notation like "namespace.Folders[..].Name" you are actually leaking a reference to both the Folders collection object and a Folder object.
When you do folders.Items.Add(...) inside a loop, that leaks a lot of objects.
So, clean up your COM references first, and see how that affects your situation.
Here's how I typically use COM objects:
MyComLib.Foo foo = null;
try
{
foo = new MyComLib.Foo();
foo.DoSomething();
} catch(COMException exc)
{
// handle error, or rethrow
}
finally
{
if(foo != null)
Marshal.ReleaseComObject(foo);
}
I'm trying to user Redemption to update a user's Outlook contacts. The user I'm affecting is passed in the exchangeUser, call him "Target User".
This code works when I run it logged in as myself:
public OutlookFolders(string outlookRootFolder, string exchangeUser, string mailServer)
{
var session = new RDOSessionClass();
session.LogonExchangeMailbox(exchangeUser, mailServer);
session.Stores.FindExchangePublicFoldersStore();
var store = session.GetSharedMailbox(exchangeUser);
//...
}
I tried to log in as a 3rd user "Test User" who is not me and is not "Target User". My program brings up a password prompt at runtime when it gets to FindExchangePublicFoldersStore, and if I don't fill in my credentials it fails with the error:
System.Runtime.InteropServices.COMException (0x8004011D): Error in
IMAPISession.OpenMsgStore(pbExchangeProviderPrimaryUserGuid):
MAPI_E_FAILONEPROVIDER
ulVersion: 0
Error: Microsoft Exchange is not available. Either there are network
problems or the Exchange computer is down for maintenance.
Component: Microsoft Exchange Information Store
ulLowLevelError: 2147746069
ulContext: 1318
I tried giving "Test User" owner permission on "Target User's" Mailbox and Contacts folder. Doesn't seem to make a difference. What other permissions need to be set for this to work?
The rule of thumb is to run your code as a user who can access the mailboxes in question, call LogonExchangeMailbox for the current user, then open other users' mailboxes using GetSharedMailbox.
Here's the code for Dmitry's answer.
It also uses a function from Milan's blog.
public OutlookFolders(string exchangeUser, string mailServer)
{
var session = new RDOSessionClass();
var userFullName = GetFullName("DOMAIN-NT\\" + Environment.UserName);
session.LogonExchangeMailbox(userFullName, mailServer);
session.Stores.FindExchangePublicFoldersStore();
var store = session.GetSharedMailbox(exchangeUser);
rootFolder = store.GetDefaultFolder((rdoDefaultFolders)OlDefaultFolders.olFolderContacts);
}
public static string GetFullName(string strLogin)
{
string str = "";
string strDomain;
string strName;
// Parse the string to check if domain name is present.
int idx = strLogin.IndexOf('\\');
if (idx == -1)
{
idx = strLogin.IndexOf('#');
}
if (idx != -1)
{
strDomain = strLogin.Substring(0, idx);
strName = strLogin.Substring(idx + 1);
}
else
{
strDomain = Environment.MachineName;
strName = strLogin;
}
DirectoryEntry obDirEntry = null;
try
{
obDirEntry = new DirectoryEntry("WinNT://" + strDomain + "/" + strName);
PropertyCollection coll = obDirEntry.Properties;
object obVal = coll["FullName"].Value;
str = obVal.ToString();
}
catch (System.Exception ex)
{
str = ex.Message;
}
return str;
}