I am getting an Exception while running the following PoweShell command:
Get-mailboxPermission -Identity MAILBOX_EMAIL |
fl User,AccessRights,IsInherited,Deny | Out-String -Width 300
Exception:
Exception calling "GetSteppablePipeline" with "1" argument(s): "Cannot find the type for custom attribute 'Parameter'.
Make sure that the assembly that contains this type is loaded."
Followed by this
Get-mailboxPermission -Identity "mailboxidentity" |
fl User,AccessRights,IsInherited,Deny | Out-String -Width 300
Which is getting me a ParameterBindingException
A parameter cannot be found that matches parameter name 'CommandName'.
This is the part of my code:
I will send the above command to executeRemoteCommand function for all the users one by one.
private void initializeRunspace() {
runSpace = RunspaceFactory.CreateRunspace();
runSpace.Open();
createRemotePowershell();
executeRemoteCommand("Set-ExecutionPolicy -ExecutionPolicy RemoteSigned",true);
executeRemoteCommand("Import-PSSession -Session $session -CommandName 'Get-MailboxPermission' ,'Get-MailboxDatabase','Add-ADPermission', 'Get-ADPermission', 'Set-EventLogLevel', 'Get-EventLogLevel'",true);
log("Remote powershell initialization ends");
}
public void createRemotePowershell() {
powershell = PowerShell.Create();
powershell.Runspace = runSpace;
PSCommand rmcommand = new PSCommand();
rmcommand.AddCommand("New-PSSession");
rmcommand.AddParameter("ConfigurationName", "Microsoft.Exchange");
rmcommand.AddParameter("ConnectionUri", uri);
if (creds != null) {
rmcommand.AddParameter("Credential", creds);
}
rmcommand.AddParameter("Authentication", "kerberos");
PSSessionOption sessionOption = new PSSessionOption();
sessionOption.SkipCACheck = true;
sessionOption.SkipCNCheck = true;
sessionOption.SkipRevocationCheck = true;
rmcommand.AddParameter("SessionOption", sessionOption);
powershell.Commands = rmcommand;
Collection<PSSession> result = powershell.Invoke<PSSession>();
log("Remote Powershell Count: "+result.Count);
if (result.Count != 1) {
throw new Exception("Unexpected number of Remote Runspace connections returned.");
}
rmcommand = new PSCommand();
rmcommand.AddCommand("Set-Variable");
rmcommand.AddParameter("Name", "session");
rmcommand.AddParameter("Value", result[0]);
powershell.Commands = rmcommand;
powershell.Invoke();
}
private String executeRemoteCommand(String shellcommand,bool retryOnSessionExpiry) {
try {
if (runSpace == null) {
initializeRunspace();
}
rmcommand = new PSCommand();
rmcommand.AddScript(shellcommand);
rmcommand.Commands.Add("Out-String");
powershell.Commands = rmcommand;
Collection<PSObject> results = powershell.Invoke();
StringBuilder sb = new StringBuilder();
foreach (PSObject obj in results) {
sb.Append(obj.ToString());
}
return sb.ToString();
} catch (CmdletInvocationException ex) {
log("RemotePowershell: CmdletInvocationException - " + shellcommand + " - " +ex.Message);
return "Invalid";
} catch (ParseException ex) {
log("RemotePowershell: ParseException - " + shellcommand + " - " +ex.Message);
return "Invalid";
} catch (ParameterBindingException ex) {
log("RemotePowershell: ParameterBindingException - " + shellcommand + " - " +ex.Message);
return "Invalid";
} catch (CommandNotFoundException ex) {
log("RemotePowershell: CommandNotFoundException - " + shellcommand + " - " +ex.Message);
return "Invalid";
} catch (PSArgumentException ex) {
log("RemotePowershell: PSArgumentException - " + shellcommand + " - " +ex.Message);
return "EMS";
} catch (Exception e) {
if(e.Message.Equals("Unexpected number of Remote Runspace connections returned.")) {
log("remoteShell cannot be established");
return "remoteShell Failed";
} else if(e.Message.Contains("PromptForCredential") && retryOnSessionExpiry) {
log("Session Expired reinitializing runspace");
try {
closeRunSpace();
initializeRunspace();
log("Session Expired runspace reinitialized");
executeRemoteCommand(shellcommand,false);
} catch(Exception ex) {
if(ex.Message.Equals("Unexpected number of Remote Runspace connections returned.")) {
log("Session Expired: remoteShell cannot be established - " + shellcommand + " - " +ex.Message);
closeRunSpace();
return "remoteShell Failed";
}
}
}
log("RemotePowershell: Exception - " + shellcommand + " - " +e.Message);
return "EMSError" + e;
}
}
Related
Short description of what I`m trying to do:
I am working on a .Net WinForm application from where I am trying to run multiple PowerShell scripts on a remote server and display results on the form.
At this moment I`m executing the scripts synchronously and this is causing me problems with long running scripts.
Any idea on how I could make this function to be executed Asynchronously?
public string NewPsSession(string ServerName, string command)
{
Runspace runspace = RunspaceFactory.CreateRunspace();
runspace.Open();
PowerShell psSession = PowerShell.Create();
psSession.Commands.AddScript("$sessions = New-PSSession -ComputerName " + ServerName + Environment.NewLine
+ "Invoke-Command -session $sessions -ScriptBlock {" + command + "}" + Environment.NewLine
+ "Remove-PSSession -Session $sessions" + Environment.NewLine);
psSession.Commands.AddCommand("Out-String");
Collection<PSObject> results = new Collection<PSObject>();
try
{
results = psSession.Invoke();
}
catch (Exception ex)
{
results.Add(new PSObject((object)ex.Message));
}
runspace.Close();
StringBuilder stringBuilder = new StringBuilder();
foreach (PSObject obj in results)
{
stringBuilder.AppendLine(obj.ToString());
}
return stringBuilder.ToString();
}
Any suggestion would be much appreciated. Thanks!
Change your NewPsSesson method to async and return a Task<string>. Then move your code into a Task<string>.Run() block and await it. Then you can either await your NewPsSession() method or monitor it as a task as I have done in Main()
class Program
{
public static void Main(string[] args)
{
Task<string> task = NewPsSession("", "");
while (!task.IsCompleted)
{
Task.Delay(500).Wait();
Console.WriteLine("Waiting...");
}
Console.WriteLine(task.Result);
Console.WriteLine("Done");
}
public static async Task<string> NewPsSession(string ServerName, string command)
{
var result = await Task<string>.Run(() =>
{
Runspace runspace = RunspaceFactory.CreateRunspace();
runspace.Open();
PowerShell psSession = PowerShell.Create();
psSession.Commands.AddScript("$sessions = New-PSSession -ComputerName " + ServerName + Environment.NewLine
+ "Invoke-Command -session $sessions -ScriptBlock {" + command + "}" + Environment.NewLine
+ "Remove-PSSession -Session $sessions" + Environment.NewLine);
psSession.Commands.AddCommand("Out-String");
Collection<PSObject> results = new Collection<PSObject>();
try
{
results = psSession.Invoke();
}
catch (Exception ex)
{
results.Add(new PSObject((object)ex.Message));
}
runspace.Close();
StringBuilder stringBuilder = new StringBuilder();
foreach (PSObject obj in results)
{
stringBuilder.AppendLine(obj.ToString());
}
return stringBuilder.ToString();
});
return result;
}
}
I am trying to read messages from MQ all at once by iterating through it. Currently I am only able to read one message at a time. I want to have a counter which will control how many times the loop will get executed or something like a while loop which will terminate when the queue is empty or else will continue reading message.
public string ReadMessages()
{
MQQueue mqDestination;
String Readmessage = null;
QueueManagerName = ConfigurationManager.AppSettings["QueueManagername"];
Hashtable properties = new Hashtable();
properties.Add(MQC.HOST_NAME_PROPERTY, ConfigurationManager.AppSettings["Connection"]);
properties.Add(MQC.PORT_PROPERTY, ConfigurationManager.AppSettings["PortNo"]);
properties.Add(MQC.CHANNEL_PROPERTY, ConfigurationManager.AppSettings["Channelname"]);
properties.Add(MQC.MQCA_TOPIC_NAME, ConfigurationManager.AppSettings["Queuename"]);
properties.Add(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_MANAGED);
queueManager = new MQQueueManager(QueueManagerName, properties);
int openOptionsForGet = (MQC.MQSO_CREATE
+ (MQC.MQSO_FAIL_IF_QUIESCING
+ (MQC.MQSO_MANAGED
+ (MQC.MQSO_NON_DURABLE + MQC.MQMO_NONE))));
MQGetMessageOptions Gmo;
MQMessage RetrievedMessage;
RetrievedMessage = new MQMessage();
try
{
RetrievedMessage = new MQMessage();
Gmo = new MQGetMessageOptions();
//Queue Name
mqDestination = queueManager.AccessQueue(ConfigurationManager.AppSettings["QueueName"], openOptionsForGet);
mqDestination.Get(RetrievedMessage, Gmo);
string message = RetrievedMessage.ReadString(RetrievedMessage.MessageLength);
queueManager.Disconnect();
}
catch (MQException ex)
{
switch (ex.ReasonCode)
{
case IBM.WMQ.MQC.MQRC_NO_MSG_AVAILABLE:
Library.ErrorLogs("error" + "No message available.");
break;
case IBM.WMQ.MQC.MQRC_Q_MGR_QUIESCING:
case IBM.WMQ.MQC.MQRC_Q_MGR_STOPPING:
Library.ErrorLogs("error" + "Queue Manager Stopping: " + ConfigurationManager.AppSettings["QueueManagername"] + "\t" + ex.Message);
break;
case IBM.WMQ.MQC.MQRC_Q_MGR_NOT_ACTIVE:
case IBM.WMQ.MQC.MQRC_Q_MGR_NOT_AVAILABLE:
Library.ErrorLogs("error" + "Queue Manager not available: " + ConfigurationManager.AppSettings["QueueManagername"] + "\t" + ex.Message);
break;
default:
Library.ErrorLogs("error" + " Error reading topic: " + ConfigurationManager.AppSettings["Queuename"] + "\t" + ex.Message);
break;
}
}
catch (Exception ex)
{
// Console.WriteLine("MQException caught. " + mqE.ToString());
Library.ErrorLogs("error" + ex.Message);
queueManager.Disconnect();
}
return Readmessage;
}
(1) You cannot get all the messages from a queue at once. You need to retrieve each message individually. MQ is not a database.
(2) You have topic code in your sample. Are you getting messages from a queue or topic. There is a difference.
Here is a fully functioning CS/.NET/MQ sample program to retrieve all messages on a queue:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Text;
using IBM.WMQ;
/// <summary> Program Name
/// MQTest72
///
/// Description
/// This C# class will connect to a remote queue manager
/// and get messages from a queue using a managed .NET environment.
///
/// </summary>
/// <author> Roger Lacroix
/// </author>
namespace MQTest72
{
class MQTest72
{
private Hashtable qMgrProp = null;
private System.String qManager;
private System.String inputQName;
/*
* The constructor
*/
public MQTest72()
: base()
{
}
/// <summary> Make sure the required parameters are present.</summary>
/// <returns> true/false
/// </returns>
private bool allParamsPresent()
{
bool b = false;
if ( (ConfigurationManager.AppSettings["ConnectionName"] != null) &&
(ConfigurationManager.AppSettings["Port"] != null) &&
(ConfigurationManager.AppSettings["ChannelName"] != null) &&
(ConfigurationManager.AppSettings["QMgrName"] != null) &&
(ConfigurationManager.AppSettings["QueueName"] != null) )
{
try
{
System.Int32.Parse(ConfigurationManager.AppSettings["Port"]);
b = true;
}
catch (System.FormatException e)
{
b = false;
}
}
return b;
}
/// <summary> Extract the configuration applicaiton settings and initialize the MQ variables.</summary>
/// <param name="args">
/// </param>
/// <throws> IllegalArgumentException </throws>
private void init(System.String[] args)
{
if (allParamsPresent())
{
qManager = ConfigurationManager.AppSettings["QMgrName"];
inputQName = ConfigurationManager.AppSettings["QueueName"];
qMgrProp = new Hashtable();
qMgrProp.Add(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_MANAGED);
qMgrProp.Add(MQC.HOST_NAME_PROPERTY, ConfigurationManager.AppSettings["ConnectionName"]);
qMgrProp.Add(MQC.CHANNEL_PROPERTY, ConfigurationManager.AppSettings["ChannelName"]);
try
{
qMgrProp.Add(MQC.PORT_PROPERTY, System.Int32.Parse(ConfigurationManager.AppSettings["Port"]));
}
catch (System.FormatException e)
{
qMgrProp.Add(MQC.PORT_PROPERTY, 1414);
}
if (ConfigurationManager.AppSettings["UserId"] != null)
qMgrProp.Add(MQC.USER_ID_PROPERTY, ConfigurationManager.AppSettings["UserId"]);
if (ConfigurationManager.AppSettings["Password"] != null)
qMgrProp.Add(MQC.PASSWORD_PROPERTY, ConfigurationManager.AppSettings["Password"]);
logger("Parameters:");
logger(" QMgrName ='" + qManager + "'");
logger(" Queue Name ='" + inputQName + "'");
logger("Connection values:");
foreach (DictionaryEntry de in qMgrProp)
{
logger(" " + de.Key + " = '" + de.Value + "'");
}
}
else
{
throw new System.ArgumentException();
}
}
/// <summary> Connect, open queue, retrieve all messages, close queue and disconnect.</summary>
/// <throws> MQException </throws>
private void handleIt()
{
MQQueueManager qMgr = null;
MQQueue inQ = null;
int openOptions = MQC.MQOO_INPUT_AS_Q_DEF + MQC.MQOO_FAIL_IF_QUIESCING;
try
{
qMgr = new MQQueueManager(qManager, qMgrProp);
logger("MQTest72 successfully connected to " + qManager);
inQ = qMgr.AccessQueue(inputQName, openOptions);
logger("MQTest72 successfully opened " + inputQName);
retrieveAll(inQ);
}
catch (MQException mqex)
{
logger("MQTest72 CC=" + mqex.CompletionCode + " : RC=" + mqex.ReasonCode);
}
catch (System.IO.IOException ioex)
{
logger("MQTest72 ioex=" + ioex);
}
finally
{
try
{
if (inQ != null)
{
inQ.Close();
logger("MQTest72 closed: " + inputQName);
}
}
catch (MQException mqex)
{
logger("MQTest72 CC=" + mqex.CompletionCode + " : RC=" + mqex.ReasonCode);
}
try
{
if (qMgr != null)
{
qMgr.Disconnect();
logger("MQTest72 disconnected from " + qManager);
}
}
catch (MQException mqex)
{
logger("MQTest72 CC=" + mqex.CompletionCode + " : RC=" + mqex.ReasonCode);
}
}
}
/// <summary> Retrieve all messages from a queue or until a 'QUIT' message is received.</summary>
/// <param name="inQ">
/// </param>
private void retrieveAll(MQQueue inQ)
{
bool flag = true;
MQGetMessageOptions gmo = new MQGetMessageOptions();
gmo.Options |= MQC.MQGMO_NO_WAIT | MQC.MQGMO_FAIL_IF_QUIESCING;
MQMessage msg = null;
while (flag)
{
try
{
msg = new MQMessage();
inQ.Get(msg, gmo);
if (msg.Feedback == MQC.MQFB_QUIT)
{
flag = false;
logger("received quit message - exiting loop");
}
else
logger("Message Data: " + msg.ReadString(msg.MessageLength));
}
catch (MQException mqex)
{
logger("CC=" + mqex.CompletionCode + " : RC=" + mqex.ReasonCode);
if (mqex.Reason == MQC.MQRC_NO_MSG_AVAILABLE)
{
// no meesage - life is good
flag = false;
logger("no more meesages - exiting loop");
}
else
{
flag = false; // severe error - time to exit
}
}
catch (System.IO.IOException ioex)
{
logger("ioex=" + ioex);
}
}
}
/// <summary> Output the log message to stdio.</summary>
/// <param name="data">
/// </param>
private void logger(String data)
{
DateTime myDateTime = DateTime.Now;
System.Console.Out.WriteLine(myDateTime.ToString("yyyy/MM/dd HH:mm:ss.fff") + " " + this.GetType().Name + ": " + data);
}
/// <summary> main line</summary>
/// <param name="args">
/// </param>
// [STAThread]
public static void Main(System.String[] args)
{
MQTest72 mqt = new MQTest72();
try
{
mqt.init(args);
mqt.handleIt();
}
catch (System.ArgumentException e)
{
System.Console.Out.WriteLine("Usage: MQTest72 -h host -p port -c channel -m QueueManagerName -q QueueName [-u userID] [-x passwd]");
System.Environment.Exit(1);
}
catch (MQException e)
{
System.Console.Out.WriteLine(e);
System.Environment.Exit(1);
}
System.Environment.Exit(0);
}
}
}
Modify the code to read the messages in loop as below. Also note that the options you have used for opening queue are not correct.
public string ReadMessages()
{
MQQueue mqDestination;
String Readmessage = null;
QueueManagerName = ConfigurationManager.AppSettings["QueueManagername"];
Hashtable properties = new Hashtable();
properties.Add(MQC.HOST_NAME_PROPERTY, ConfigurationManager.AppSettings["Connection"]);
properties.Add(MQC.PORT_PROPERTY, ConfigurationManager.AppSettings["PortNo"]);
properties.Add(MQC.CHANNEL_PROPERTY, ConfigurationManager.AppSettings["Channelname"]);
properties.Add(MQC.MQCA_TOPIC_NAME, ConfigurationManager.AppSettings["Queuename"]);
properties.Add(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_MANAGED);
try
{
queueManager = new MQQueueManager(QueueManagerName, properties);
int openOptionsForGet = MQC.MQOO_INPUT + MQC.MQSO_FAIL_IF_QUIESCING;
//Queue Name
mqDestination = queueManager.AccessQueue(ConfigurationManager.AppSettings["QueueName"],openOptionsForGet);
//Read messages with a wait of 30 seconds. Break out of the loop when there are no messages (MQRC 2033) or any other reason code is received.
while (true) {
try {
MQGetMessageOptions Gmo = new MQGetMessageOptions();
Gmo.WaitInterval = 30
Gmo.Options |= MQC.MQGMO_WAIT;
MQMessage RetrievedMessage = new MQMessage();
mqDestination.Get(RetrievedMessage, Gmo);
string message = RetrievedMessage.ReadString(RetrievedMessage.MessageLength);
} catch(MQException ex) {
// Display the exception and break;
break;
}
}
mqDestination.Close();
queueManager.Disconnect();
}
catch (MQException ex)
{
switch (ex.ReasonCode)
{
case IBM.WMQ.MQC.MQRC_NO_MSG_AVAILABLE:
Library.ErrorLogs("error" + "No message available.");
break;
case IBM.WMQ.MQC.MQRC_Q_MGR_QUIESCING:
case IBM.WMQ.MQC.MQRC_Q_MGR_STOPPING:
Library.ErrorLogs("error" + "Queue Manager Stopping: " + ConfigurationManager.AppSettings["QueueManagername"] + "\t" + ex.Message);
break;
case IBM.WMQ.MQC.MQRC_Q_MGR_NOT_ACTIVE:
case IBM.WMQ.MQC.MQRC_Q_MGR_NOT_AVAILABLE:
Library.ErrorLogs("error" + "Queue Manager not available: " + ConfigurationManager.AppSettings["QueueManagername"] + "\t" + ex.Message);
break;
default:
Library.ErrorLogs("error" + " Error reading topic: " + ConfigurationManager.AppSettings["Queuename"] + "\t" + ex.Message);
break;
}
}
catch (Exception ex)
{
// Console.WriteLine("MQException caught. " + mqE.ToString());
Library.ErrorLogs("error" + ex.Message);
queueManager.Disconnect();
}
return Readmessage;
}
I trying to create a shared-folder using Wmi , every-time i trying to do so i get this exception :
Error from CreateSharedFolder(localPath=C:\BaseFolder). Ex=>Failed to open access to network share on xxx.xx.x.xxx.
trying to search for solution for days...
CreateSharedFolder:
private bool CreateSharedFolder(string localPath)
{
try
{
string sharedName = shareName(localPath);
Connection conn = Connection.GetConnection(this);
if (conn == null)
{
SetAllProcessStatus(ProcessStates.ServerConnectionFailure, DetecorProcessStatuses.ServerDisconnected); ;
Globals.WriteLog(LogTypes.Error, "Aborting CreateSharedFolder(machineInfo=" + this.ToString() + ", localPath=" + localPath + "). Got NO connecion!");
throw new Exception("Create shared folder failed because get connection failed");
}
string cmd = string.Format(#"cmd.exe /c md ""{0}""", localPath);
Run_Remote_Process_Using_WMI(conn, cmd, true);
cmd = string.Format(#"net share {0}=""{1}"" /GRANT:Everyone,FULL", sharedName, localPath);
bool success1 = Run_Remote_Process_Using_WMI(conn, cmd, true) > 0;
System.Threading.Thread.Sleep(400);
string cmd2 = string.Format(#"net share {0}=""{1}""", sharedName, localPath);
bool success2 = Run_Remote_Process_Using_WMI(conn, cmd2, true) > 0;
// Open access to network share (requires username & password)
Process process = new Process();
string args = string.Format("/c net use \\\\{0} {1} /USER:{2}", this.Address, this.Password, this.Username);
process.StartInfo = new ProcessStartInfo("cmd.exe", args);
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
if (!process.Start() ||
!process.WaitForExit(5000) ||
process.ExitCode < 0)
{
string error = string.Format("Failed to open access to network share on {0}", this.Address);
throw new Exception(error);
}
return true;
}
catch (Exception ex)
{
Globals.WriteLog(LogTypes.Error, "Error from CreateSharedFolder(localPath=" + localPath + "). Ex=>" + ex.Message, ex);
throw ex;
}
}
and Run_Remote_Process_Using_WMI function :
try
{
ObjectGetOptions objectGetOptions = new ObjectGetOptions();
ManagementPath managementPath = new ManagementPath("Win32_Process");
ManagementClass processClass = new ManagementClass(conn.ManagementScope, managementPath, objectGetOptions);
ManagementClass startup;
startup = new ManagementClass("WIN32_ProcessStartup");
startup.Scope = conn.ManagementScope;
startup["ShowWindow"] = (Int32)3;
ManagementBaseObject inParams = processClass.GetMethodParameters("Create");
inParams["CommandLine"] = cmd;
inParams["ProcessStartupInformation"] = startup;
ManagementBaseObject outParams = processClass.InvokeMethod("Create", inParams, null);
bool success = Convert.ToInt32(outParams["returnValue"]) == 0;
if (!success)
{
Globals.WriteLog(LogTypes.Error, "Failed to run remote process [" + cmd + "] on " + this.Address +
". return value=" + outParams["returnValue"]);
if (throwIfError)
throw new Exception("Failed to run WMI command: " + cmd);
}
if (success)
{
processID = Convert.ToInt32(outParams["processId"]);
Globals.WriteLog(LogTypes.Info, "Process [" + cmd + "] on " + this.Address + " was started successfully");
}
}
catch (Exception ex)
{
Globals.WriteLog(LogTypes.Error, "Error from Run_Remote_Process_Using_WMI(). Ex=>" + ex.Message, ex);
throw ex;
}
return processID;
}
How I can't attach to splited string file name from DB row (I need for "mode = 2" and "case 2:").
In my log file error:
FILE TO ATTACH ERR : Could not find file
'C:\inetpub\wwwroot\PLATFORM_700_NTFSRV\PLATFORM_700_NTFSRV_LAB\Attachments\text.txt,text2.txt'.
Here my example code and my row in DB
Row in db:
|FILE_TO_ATTACH |
|text1.txt,text2.txt|
public DataTable GetAttachmentFiles(int mode , string fileIDList)
{
try
{
DataTable DTB = new DataTable();
if (mode == 1)
{
SqlCommand TheCommand = GetCommand("application_MessageAttachFiles", CommandType.StoredProcedure,
GetConnection("APP"));
TheCommand.Parameters.Add("FILEIDLIST", SqlDbType.VarChar, 8000);
TheCommand.Parameters["FILEIDLIST"].Value = fileIDList;
SqlDataAdapter SDA = new SqlDataAdapter();
SDA.SelectCommand = TheCommand;
SDA.Fill(DTB);
}
else if(mode == 2)
{
try
{
DTB.Columns.Add("FILENAME");
string[] fileList = fileIDList.Split(',');
for (int c = 0; c < fileList.Length; c++)
{
DataRow DR = DTB.NewRow();
DR["FILENAME"] = fileList[c];
DTB.Rows.Add(DR);
}
}
catch (Exception ex)
{
RecordLine("ERROR Reading GetAttachmentFiles: " + ex.Message);
}
}
return DTB;
}
catch (Exception eX)
{
RecordLine("ERROR GetAttachmentFiles : " + eX.Message);
return null;
}
}
public Attachment AttachmentFile(int mode, string fileNameString, int fileID, DataRow DRA)
{
// mode.ToString(ConfigurationSettings.AppSettings["MODE"]);
try
{
switch (mode)
{
case 1: /*from Database*/
if (DRA != null)
{
Attachment messageAttachment;
int fileDataSize = int.Parse(DRA["FileSize"].ToString());
string fileType = DRA["FileType"].ToString();
string fileName = DRA["FileName"].ToString();
byte[] fileBuffer = (DRA["FileData"]) as byte[];
MemoryStream ms = new MemoryStream(fileBuffer);
RecordLine("DEBUG 2 - " + fileName + " " + fileType + " " + fileDataSize.ToString() + " " + ms.Length.ToString() + " buffer size:" + fileBuffer.Length.ToString());
messageAttachment = new Attachment(ms, fileName, fileType);
return messageAttachment;
}
break;
case 2: /*from Local Machin */
{
Attachment messageAttachment;
try
{
fileNameString = String.Format("{0}\\{1}", ConfigurationSettings.AppSettings["SOURCE_FILE"],
fileNameString);
messageAttachment = new Attachment(fileNameString);
RecordLine("DEBUG 2.1 - " + messageAttachment.Name);
return messageAttachment;
}
catch (Exception ex)
{
RecordLine("FILE TO ATTACH ERR : " + ex.Message);
}
}
break;
default:
return null;
break;
}
return null;
}
catch (Exception eX)
{
RecordLine("ERROR AttachmentFile : " + eX.Message);
return null;
}
}
I had add this code and it is worked:
foreach (DataRow DRA in DTBA.Rows)
{
message.Attachments.Add(AttachmentFile(2, DRA["FILENAME"].ToString().Trim(), 0, null));
RecordLine("DEBUG 3.1 - " + message.Attachments.Count.ToString());
}
I'm using the busyIndicator in my program that works with MVVM pattern, I found out that there is a problem with background worker and dealing with objects that are binded in the view so I used the Dispacher.Invoke method on all of the functions that use binded properties, after I used the Dispacher the busyIndicator showed up, but when the backgoundWorker finished my view had no elements inside, what am I doing wrong?
I know it's a little low in code but i didn't know what (and if) will help, if necessary please let me know and I'll edit this message with the desired code.
EDIT:
Here is some code that might help:
This is the creation of the BW, it happens on the viewModel constructor
bw = new BackgroundWorker();
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
bw.RunWorkerAsync(false);
This is the BW functions
void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.IsBusy = false;
}
void bw_DoWork(object sender, DoWorkEventArgs e)
{
this.BusyContent = "Please Wait...";
this.IsBusy = true;
ShowSystem((bool)e.Argument);
}
The method showSystem is very long so I'll add just the part that using UI elemnts
List<NodeViewModel> nodes = null;
Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => nodes = new List<NodeViewModel>()));
int width = 0;
int height = 0;
foreach (var system in MainNet.Systems)
{
Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => nodes.Add(CreateNode(system.Name, new Point(width, height), false, system.InputNum, system.OutputNum, system.Interfaces, system.Enums, system.Structs, update))));
width += 150;
if (width >= 700)
{
width = 0;
height += 100;
}
}
if (MainWindow.IsFlow)
{
Object[] getInterfacesWithGuidToFlowParam = new Object[1];
getInterfacesWithGuidToFlowParam[0] = MainWindow.GuidToFlow;
interfacesForFlow = (List<String>)getInterfacesWithGuidToFlow.Invoke(sqlDB, getInterfacesWithGuidToFlowParam);
}
foreach (var system in MainNet.Systems)
{
if (system.OutputNum > 0) //this system has an output connector
{
int i = 0;
foreach (var outId in system.Outputs) //loop throw all systems ids that current system is connected to
{;
ConnectionViewModel connection = null;
Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => connection = new ConnectionViewModel()));
Object[] getSystemNameParams = new Object[1];
getSystemNameParams[0] = outId;
string destSystemName = "";
destSystemName = (String)getSystemName.Invoke(sqlDB, getSystemNameParams);
NodeViewModel sourceItem = null;
NodeViewModel destItem = null;
Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => sourceItem = nodes.Find(x => x.Name == system.Name)));
Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => destItem = nodes.Find(x => x.Name == destSystemName)));
Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => destItem.InputSystems.Add(sourceItem.Name)));
Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => sourceItem.OutputSystems.Add(destItem.Name)));
Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => connection.SourceConnector = sourceItem.OutputConnectors[i++]));
Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => connection.DestConnector = destItem.InputConnectors[destItem.InputConnectors.Count - 1]));
// Add the connection to the view-model.
//
Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => connection.Type = ConnectionViewModel.ConnectorType.REGULAR));
Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => this.Network.Connections.Add(connection)));
if (MainWindow.IsFlow)
{
foreach (var #interface in interfacesForFlow)
{
String[] systems = #interface.Split('_');
if(systems[0].Equals(sourceItem.Name) && systems[1].Equals(destItem.Name))
Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => connection.Type = ConnectionViewModel.ConnectorType.FLOW));
}
}
}
}
}
Edit:
This is the part of getting the data from Database:
MainNet = Common.Model.Network.getNetwork();
Debug.WriteLine("MainNet.Systems.Count = " + MainNet.Systems.Count);
if (MainNet.Systems.Count == 0)
update = true;
List<String> systemNames = new List<string>();
if (update)
{
if(MainNet.Systems.Count > 0)
MainNet.Systems.Clear();
if (this.Network.Nodes.Count > 0)
{
this.Network.Nodes.Clear();
this.Network.Connections.Clear();
}
try
{
systemNames = (List<String>)getAllSystemMethod.Invoke(sqlDB, null);
Debug.WriteLine("Success getAllSystemMethod");
}
catch (Exception ex)
{
logger.addMessage("Error in getAllSystemMethod: " + ex.Message + " Inner: " + ex.InnerException.Message);
Debug.WriteLine("Error in getAllSystemMethod: " + ex.Message + " Inner: " + ex.InnerException.Message);
}
#region CreateSystems
foreach (var sysName in systemNames)
{
#region Intializating
ObservableCollection<Common.Model.Enum> enums = new ObservableCollection<Common.Model.Enum>();
ObservableCollection<Common.Model.Struct> structs = new ObservableCollection<Common.Model.Struct>();
ObservableCollection<Common.Model.Interface> interfaces = new ObservableCollection<Common.Model.Interface>();
//List<Model.Enum> enums = new List<Model.Enum>();
//List<Model.Struct> structs = new List<Model.Struct>();
//List<Model.Interface> interfaces = new List<Model.Interface>();
int systemId = -1;
Object[] getSystemIdParams = new Object[1];
getSystemIdParams[0] = sysName;
try
{
systemId = (int)getSystemId.Invoke(sqlDB, getSystemIdParams);
Debug.WriteLine("Success getSystemId systemId = " + systemId);
}
catch (Exception ex)
{
logger.addMessage("Error in getSystemId: " + ex.Message + " Inner: " + ex.InnerException.Message);
Debug.WriteLine("Error in getSystemId: " + ex.Message + " Inner: " + ex.InnerException.Message);
}
List<int> sysEnumsIds = new List<int>();
List<int> sysStructsIds = new List<int>();
List<int> sysInterfacesIds = new List<int>();
Object[] getSysEnumsIdParams = new Object[1];
getSysEnumsIdParams[0] = systemId;
try
{
sysEnumsIds = (List<int>)getSysEnumsId.Invoke(sqlDB, getSysEnumsIdParams); //return List<int> all system Enums ids
if (sysEnumsIds.Count > 0)
Debug.WriteLine("Success getSysEnumsId first count is " + sysEnumsIds.Count);
else
Debug.WriteLine("success getSysEnumsId but no ids found");
}
catch (Exception ex)
{
logger.addMessage("Error in getSysEnumsId: " + ex.Message + " Inner: " + ex.InnerException.Message);
Debug.WriteLine("Error in getSysEnumsId: " + ex.Message + " Inner: " + ex.InnerException.Message);
}
Object[] getSysStructsIdParams = new Object[1];
getSysStructsIdParams[0] = systemId;
try
{
sysStructsIds = (List<int>)getSysStructsId.Invoke(sqlDB, getSysStructsIdParams);
if (sysStructsIds.Count > 0)
Debug.WriteLine("success getSysStructsId count = " + sysStructsIds.Count);
else
Debug.WriteLine("success getSysStructsId but no ids found");
}
catch (Exception ex)
{
logger.addMessage("Error in getSysStructsId: " + ex.Message + " Inner: " + ex.InnerException.Message);
Debug.WriteLine("Error in getSysStructsId: " + ex.Message + " Inner: " + ex.InnerException.Message);
}
Object[] getSysInterfacesIdParams = new Object[1];
getSysInterfacesIdParams[0] = systemId;
try
{
sysInterfacesIds = (List<int>)getSysInterfacesId.Invoke(sqlDB, getSysInterfacesIdParams);
if (sysInterfacesIds.Count > 0)
Debug.WriteLine("Success getSysInterfacesId count = " + sysInterfacesIds.Count);
else
Debug.WriteLine("success getSysInterfacesId but no ids found");
}
catch (Exception ex)
{
logger.addMessage("Error in getSysInterfacesId: " + ex.Message + " Inner: " + ex.InnerException.Message);
Debug.WriteLine("Error in getSysInterfacesId: " + ex.Message + " Inner: " + ex.InnerException.Message);
}
#endregion
Object[] getStructFromIdParam = new Object[1];
getStructFromIdParam[0] = #struct;
List<Object> tempStruct = new List<object>();
try
{
tempStruct = (List<Object>)getStructFromId.Invoke(sqlDB, getStructFromIdParam);
Debug.WriteLine("Success getStructFromId " + tempStruct.Count);
}
catch (Exception ex)
{
logger.addMessage("Error in getStructFromIdParam : " + ex.Message + " Inner: " + ex.InnerException.Message);
Debug.WriteLine("Error in getStructFromIdParam : " + ex.Message + " Inner: " + ex.InnerException.Message);
}
structs.Add(new Common.Model.Struct(Convert.ToString(tempStruct[0]), Convert.ToString(tempStruct[1]), Convert.ToString(tempStruct[2]), fields, bitFields));
Debug.WriteLine("Success adding new struct: " + structs.Last().Name);
}
#endregion
#region GetInterfaces
foreach (var #interface in sysInterfacesIds) //get interface
{
ObservableCollection<Common.Model.Message> messages = new ObservableCollection<Common.Model.Message>();
ObservableCollection<Common.Model.Definition> definitions = new ObservableCollection<Common.Model.Definition>();
ObservableCollection<Common.Model.Include> includes = new ObservableCollection<Common.Model.Include>();
List<int> includesIds = new List<int>();
List<int> definitionsIds = new List<int>();
List<int> messagesIds = new List<int>();
#region getIncludes
Object[] getIncludesIdsParams = new object[1];
getIncludesIdsParams[0] = #interface;
try
{
includesIds = (List<int>)getIncludesIds.Invoke(sqlDB, getIncludesIdsParams);
Debug.WriteLine("Success getIncludesIds " + includesIds.Count);
}
catch (Exception ex)
{
logger.addMessage("Error in getIncludesIds: " + ex.Message + " Inner: " + ex.InnerException.Message);
Debug.WriteLine("Error in getIncludesIds: " + ex.Message + " Inner: " + ex.InnerException.Message);
}
foreach (var id in includesIds)
{
Object[] getIncludeParams = new object[1];
getIncludeParams[0] = id;
string includeName = "";
try
{
includeName = (string)getInclude.Invoke(sqlDB, getIncludeParams);
Debug.WriteLine("Success get include name = " + includeName);
}
catch (Exception ex)
{
logger.addMessage("Error in getInclude " + ex.Message + " Inner: " + ex.InnerException.Message);
Debug.WriteLine("Error in getInclude " + ex.Message + " Inner: " + ex.InnerException.Message);
}
includes.Add(new Common.Model.Include(includeName));
}
#endregion
#region getdefinitions
Object[] getdefinitionsIdsParams = new object[1];
getdefinitionsIdsParams[0] = #interface;
try
{
definitionsIds = (List<int>)getDefinitionsIds.Invoke(sqlDB, getdefinitionsIdsParams);
Debug.WriteLine("Success getDefinitionsIds " + definitionsIds.Count);
}
catch (Exception ex)
{
logger.addMessage("Error in getDefinitionsIds: " + ex.Message + " Inner: " + ex.InnerException.Message);
Debug.WriteLine("Error in getDefinitionsIds: " + ex.Message + " Inner: " + ex.InnerException.Message);
}
foreach (var id in definitionsIds)
{
List<Object> definition = new List<object>();
Object[] getDefinitionParams = new object[1];
getDefinitionParams[0] = id;
string includeName = "";
try
{
definition = (List<Object>)getDefinition.Invoke(sqlDB, getDefinitionParams);
Debug.WriteLine("Success getDefinisions " + definition[0]);
}
catch (Exception ex)
{
logger.addMessage("Error in getInclude " + ex.Message + " Inner: " + ex.InnerException.Message);
Debug.WriteLine("Error in getInclude " + ex.Message + " Inner: " + ex.InnerException.Message);
}
definitions.Add(new Common.Model.Definition(Convert.ToString(definition[0]), Convert.ToInt32(definition[1])));
}
#endregion
#region getMessages
Object[] getMessagesIdsParams = new object[1];
getMessagesIdsParams[0] = #interface;
Debug.WriteLine("Trying to get messages for interface #" + #interface);
try
{
messagesIds = (List<int>)getMessagesIds.Invoke(sqlDB, getMessagesIdsParams);
Debug.WriteLine("Success getMessagesIds " + messagesIds.Count);
}
catch (Exception ex)
{
logger.addMessage("Error in getMessagesIds: " + ex.Message + " Inner: " + ex.InnerException.Message);
Debug.WriteLine("Error in getMessagesIds: " + ex.Message + " Inner: " + ex.InnerException.Message);
}
foreach (var id in messagesIds)
{
//List<Model.MType> types = new List<Model.MType>();
ObservableCollection<Common.Model.MType> types = new ObservableCollection<Common.Model.MType>();
List<int> typesIds = new List<int>();
Object[] getMessageTypesIdsParams = new Object[1];
getMessageTypesIdsParams[0] = id;
try
{
typesIds = (List<int>)getMessageTypesIds.Invoke(sqlDB, getMessageTypesIdsParams);
Debug.WriteLine("Success getMessageTypesIds " + typesIds.Count);
}
catch (Exception ex)
{
logger.addMessage("Error in getMessageTypesIds: " + ex.Message + " Inner: " + ex.InnerException.Message);
Debug.WriteLine("Error in getMessageTypesIds: " + ex.Message + " Inner: " + ex.InnerException.Message);
}
foreach (var typeId in typesIds)
{
List<Object> type = new List<object>();
Object[] getTypeParams = new object[1];
getTypeParams[0] = typeId;
//string includeName = "";
try
{
type = (List<Object>)getType.Invoke(sqlDB, getTypeParams);
Debug.WriteLine("Success getType");
}
catch (Exception ex)
{
logger.addMessage("Error in getType " + ex.Message + " Inner: " + ex.InnerException.Message);
Debug.WriteLine("Error in getType " + ex.Message + " Inner: " + ex.InnerException.Message);
}
types.Add(new Common.Model.MType((string)type[0], (string)type[1], (string)type[2], (string)type[3], (string)type[4], (string)type[5], (Guid)type[6]));
Debug.WriteLine("Success adding new type: " + (string)type[0] + " " + (string)type[1] + " " + (string)type[2] + " " + (string)type[3] + " " + (string)type[4] + " " + (string)type[5] + " " + (Guid)type[6]);
}
string sourceSystem = "";
string destSystem = "";
List<Object> message = new List<object>();
Object[] getMessageParams = new Object[1];
getMessageParams[0] = id;
try
{
message = (List<Object>)getMessage.Invoke(sqlDB, getMessageParams);
Debug.WriteLine("Success getMessageParams");
}
catch (Exception ex)
{
logger.addMessage("Error in getMessageTypesIds: " + ex.Message + " Inner: " + ex.InnerException.Message);
Debug.WriteLine("Error in getMessageTypesIds: " + ex.Message + " Inner: " + ex.InnerException.Message);
}
messages.Add(new Common.Model.Message(types, message[0].ToString(), (int)message[1], message[2].ToString(), message[3].ToString(), message[4].ToString(), message[5].ToString(), message[6].ToString(), message[7].ToString(), message[8].ToString(), message[9].ToString()));
Debug.WriteLine("Success adding new Message: " + message[0].ToString() + " " + (int)message[1] + " " + message[2].ToString() + " " + message[3].ToString() + " " + message[4].ToString() + " " + message[5].ToString() + " " + message[6].ToString() + " " + message[7].ToString() + " " + message[8].ToString() + " " + message[9].ToString());
}
#endregion
Object[] getInterfaceFromIdParam = new Object[1];
getInterfaceFromIdParam[0] = #interface;
List<Object> tempInterface = new List<object>();
try
{
tempInterface = (List<Object>)getInterfaceFromId.Invoke(sqlDB, getInterfaceFromIdParam);
Debug.WriteLine("Success getInterfaceFromId " + tempInterface.Count);
}
catch (Exception ex)
{
logger.addMessage("Error in getInterfaceFromId : " + ex.Message + " Inner: " + ex.InnerException.Message);
Debug.WriteLine("Error in getInterfaceFromId : " + ex.Message + " Inner: " + ex.InnerException.Message);
}
interfaces.Add(new Common.Model.Interface(messages, definitions, includes, Convert.ToString(tempInterface[0]), Convert.ToString(tempInterface[1]), Convert.ToInt32(tempInterface[2]), Convert.ToInt32(tempInterface[3]), Convert.ToBoolean(tempInterface[4])));
Debug.WriteLine("Success adding new interface: " + interfaces.Last().Name);
}
#endregion
#region InputOutputNumber
List<int> inputs = new List<int>();
List<int> outputs = new List<int>();
int inputCount = 0;
int outputCount = 0;
Object[] getSysInputNumParams = new Object[1];
getSysInputNumParams[0] = systemId;
try
{
inputs = (List<int>)getSysInputs.Invoke(sqlDB, getSysInputNumParams);
if (inputs != null)
{
inputCount = inputs.Count;
Debug.WriteLine("Success getSysInputNum inputs = " + inputCount);
}
else
Debug.WriteLine("Success getSysInputNum inputs = 0");
}
catch (Exception ex)
{
logger.addMessage("Error in getSysInputNum: " + ex.Message + " Inner: " + ex.InnerException.Message);
Debug.WriteLine("Error in getSysInputNum: " + ex.Message + " Inner: " + ex.InnerException.Message);
}
Object[] getSysOutputNumParams = new Object[1];
getSysOutputNumParams[0] = systemId;
try
{
outputs = (List<int>)getSysOutputs.Invoke(sqlDB, getSysOutputNumParams);
if (outputs != null)
{
outputCount = outputs.Count;
Debug.WriteLine("Success getSysOutputNum outputs = " + outputCount);
}
else
Debug.WriteLine("Success getSysOutputNum outputs = 0");
}
catch (Exception ex)
{
logger.addMessage("Error in getSysOutputNum: " + ex.Message + " Inner: " + ex.InnerException.Message);
Debug.WriteLine("Error in getSysOutputNum: " + ex.Message + " Inner: " + ex.InnerException.Message);
}
#endregion
Common.Model.System system = null;
try
{
system = new Common.Model.System(interfaces, enums, structs, sysName, inputCount, outputCount, inputs, outputs);
Debug.WriteLine("Success adding new system");
}
catch (Exception ex)
{
logger.addMessage("Error in creating new system: " + ex.Message);
Debug.WriteLine("Error in creating new system: " + ex.Message);
}
MainNet.Systems.Add(system);
Debug.WriteLine("Done! you now have a new system with: " + interfaces.Count + " interfaces And " + enums.Count + " Enums and " + structs.Count + " Structs, The name is: " + sysName + " numOfInput: " + inputCount + " numOfOutput: " + outputCount);
#endregion
}
#endregion
The dispatcher is being used incorrectly here
The Dispatcher can be used to marshal code onto the UI thread, at a specified priority if desired. The code does not get executed and return immediately, but instead gets run at the priority specified according to the DispatcherPriority order.
Basically your code is saying
Create a List
>> Queue code to populate the list on the UI thread at a later time
If list is not null, execute some code
The list will always be null because the code to populate it hasn't been run yet. Its only been queued to run once when available.
The correct way to do this would be to populate your data on the background worker, and then marshal the results back onto the UI thread to populate your UI.
Note that objects can only be modified on the thread at which they were created on. So if you have some objects you plan on using and/or modifying from the UI later on, you should see something like this:
Create objects
Start BackgroundWorker to get data
BackgroundWorker obtains data on background thread without locking up UI
BackgroundWorker finishes and uses Dispatcher to run code on the UI thread that will update objects created at the first step with results