I am working on Word AddIns and using Interop library of Word and i want to assign a name(string) to Shape but word.shape.name throwing Exception:
"System.UnauthorizedAccessException: Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))".
My code is:
bool blnRetVal = false;
string strModel = ndModel.Name;
int lngModel = 0;
int lngNextModel = 0;
int lngStart;
int lngEnd;
Alias.Document objTemp;
Microsoft.Office.Interop.Word.Range objRange;
Shape objShape;
Object[] astr;
int n;
bool bLastModel;
/*'--------------------------------------------------------------------------------------------------
' 1. Find model's model marker and the next marker (if any)
'--------------------------------------------------------------------------------------------------*/
astr = dicMarkers.Keys();
for (n = astr.GetLowerBound(0); n <= astr.GetUpperBound(0); n++)
{
if (string.Compare(astr[n].ToString(), strModel, true) == 0)
{
lngModel = (int)dicMarkers.get_Item(astr[n]); //PNDC //dicMarkers.Item(astr(n))
if (n < astr.GetUpperBound(0))
{
if (string.Compare(astr[n + 1].ToString(), "#end", true) == 0)
{
lngNextModel = 0;
bLastModel = true;
}
else
{
lngNextModel = (int)dicMarkers.get_Item(astr[n + 1]);
bLastModel = false;
}
}
else
{
lngNextModel = 0;
}
break;
}
}
/*'--------------------------------------------------------------------------------------------------
' 2. Copy model from original document to new document
'--------------------------------------------------------------------------------------------------*/
if (lngModel > 0)
{
lngStart = objSourceDocument.Sections[lngModel].Range.Start;
if (lngNextModel == 0)
{
var key = "#end";
var value = dicMarkers.get_Item(key);
lngEnd = value;
}
else
lngEnd = objSourceDocument.Sections[lngNextModel].Range.Start; //objSourceDocument.Sections.Last.Index;
//--------------------------------------------------------------------------------------------------
//copy original
objSourceDocument.ActiveWindow.Selection.SetRange(lngStart, lngEnd);
objSourceDocument.ActiveWindow.Selection.Copy();
bool bInsertSection = false;
//paste (append) copied model to the document
if (objTargetDocument.Sections.First.Index == objTargetDocument.Sections.Last.Index)
{
//Target document only has 1 (default) section
bInsertSection = true;
}
else
{
if (objTargetDocument.Sections.Last.PageSetup.SectionStart == WdSectionStart.wdSectionNewPage)
{
//Last section is a nextpage section
if ((objTargetDocument.Sections.Last.Range.End - (objTargetDocument.Sections.Last.Range.Start) <= 1))
//Empty section
bInsertSection = false;
else
bInsertSection = true;
}
else
{
//Last section isn't a nextpage
bInsertSection = true;
}
}
objTargetDocument.ActiveWindow.Selection.Start = objTargetDocument.Range().End;
if (bInsertSection)
{
objTargetDocument.ActiveWindow.Selection.InsertBreak(WdBreakType.wdSectionBreakNextPage);
objTargetDocument.ActiveWindow.Selection.Start = objTargetDocument.Range().End;
}
objTargetDocument.ActiveWindow.Selection.Collapse();
objRange = objTargetDocument.ActiveWindow.Selection.Range.Duplicate; //remember range for model marker anchor
objTargetDocument.ActiveWindow.Selection.Paste();
//place model marker (so that we can find our model again)
objShape = objTargetDocument.Shapes.AddTextbox(Microsoft.Office.Core.MsoTextOrientation.msoTextOrientationUpward, 0, 0, 0, 0, objRange);
objShape.Name = m_strModelMarker + strModel;
objShape.Visible = Microsoft.Office.Core.MsoTriState.msoFalse;
UpdateFields(ref objTargetDocument, ref ndModel);
blnRetVal = true;
}
else
new Modules.Globals().MsgBoxEx("Kan het bestaande model '" + strModel + "' niet kopieren.", MessageBoxButtons.OK);
return blnRetVal;
}
I am unable to duplicate your error, however I am able to get your code to run with a few changes. Let me know if I've misinterpreted.
Note the Missing variable used instead of objRange. I've also removed variables that were not applicable.
using Word = Microsoft.Office.Interop.Word;
using Alias = Microsoft.Office.Interop.Word;
public Test()
{
var doc = new Alias.Document();
var doc2 = new Alias.Document();
var t = this.CloneModel(ref doc, ref doc2);
}
private bool CloneModel(ref Alias.Document objTargetDocument, ref Alias.Document objSourceDocument)
{
var missing = Type.Missing;
Word.Shape objShape;
objShape = objTargetDocument.Shapes.AddTextbox(
Microsoft.Office.Core.MsoTextOrientation.msoTextOrientationUpward, 0, 0, 0, 0, ref missing); <== note the missing here instead of objRange
objShape.Name = "Carma DocSys~Brief"; // no longer throwing exceptions (hard coded string)
objShape.Visible = Microsoft.Office.Core.MsoTriState.msoFalse;
return true;
}
If this is NOT the problem, then I would suggest that you are having trouble with permissions to the file as the error message suggests.
Related
I need to select a specific block/border on the drawing and print that block/border as a PDF. I can find border by name but I can not take border coordination or at least one point to select the border and then print only that border. I will insert a code snippet that I have. It's messy - in development. Not familiar with DraftSight and DraftSight API.
I'm sure it's several different ways to do it.
Any help will be appreciated.
public static void BlockSelection()
{
DraftSight.Interop.dsAutomation.Application dsApp;
Document dsDoc = default(Document);
PrintManager dsPrintMgr = null;
//Connect to DraftSight application
dsApp = (DraftSight.Interop.dsAutomation.Application)Marshal.GetActiveObject("DraftSight.Application");
dsApp.AbortRunningCommand(); // abort any command currently running in DraftSight to avoid nested commands
//Get active document
dsPrintMgr = dsApp.GetPrintManager();
dsDoc = (Document)dsApp.GetActiveDocument();
object[] dsVarBlkDefinitions = null;
BlockDefinition dsBlkDefinition = default(BlockDefinition);
object[] dsBlock = null;
DraftSight.Interop.dsAutomation.Viewport dsViewport = default(DraftSight.Interop.dsAutomation.Viewport);
MathUtility dsMathUtility = default(MathUtility);
MathPoint startCorner = default(MathPoint);
MathPoint oppositeCorner = default(MathPoint);
Model dsModel = default(Model);
SketchManager dsSketchManeger = default(SketchManager);
ViewManager dsViewManager = default(ViewManager);
object[] dsSheets = null;
Sheet dsSheet = default(Sheet);
string SheetName = null;
int count = 0;
string blockName = "BLOCK1";
string outputFileLocationName = $#"C:\\TestOutput\\fileName";
//Get all Block definitions in the drawing
dsVarBlkDefinitions = (object[])dsDoc.GetBlockDefinitions();
dsBlock = new object[dsVarBlkDefinitions.Length];
for (int index = 0; index < dsVarBlkDefinitions.Length; index++)
{
for (index = dsVarBlkDefinitions.GetLowerBound(0); index <= dsVarBlkDefinitions.GetUpperBound(0); index++)
{
dsBlkDefinition = (BlockDefinition)dsVarBlkDefinitions[index];
var name = dsBlkDefinition.GetName();
Debug.Print($#"Block name: {name}");
// found block that I need to select and print
if (dsBlkDefinition.GetName().Contains(blockName))
{
object[] blocks = dsBlkDefinition.GetBlockInstances();
SelectionManager dsSelectionManager = dsDoc.GetSelectionManager();
SelectionFilter dsSelectionFilter = dsSelectionManager.GetSelectionFilter();
dsSelectionFilter.Clear();
dsSelectionFilter.AddEntityType(dsObjectType_e.dsBlockInstanceType);
dsSelectionFilter.Active = true;
dsSelectionManager.ClearSelections(dsSelectionSetType_e.dsSelectionSetType_Previous);
//if (dsCommandMessage.PromptForSelection(true, "Select dynamic block", errorMessage)) //
count = 0;
count = dsSelectionManager.GetSelectedObjectCount(dsSelectionSetType_e.dsSelectionSetType_Previous);
dsObjectType_e entityType = dsObjectType_e.dsObjectUndefinedType;
//object selObject = dsSelectionManager.GetSelectedObject(dsSelectionSetType_e.dsSelectionSetType_Previous, index, out entityType);
// tried to find any point of the block - not sure how to do that..
MathPoint point = ;
// Pathing that point into the SelectByPoint method.
object selObject = dsSelectionManager.SelectByPoint(point);
BlockInstance dsBlockInstance = selObject as BlockInstance;
// Printer set up
double top = .25;
double bottom = .25;
double left = .25;
double right = .25;
/////dsPrintMgr.PaperSize = "ANSI_A_(8.50_x_11.00_Inches)"; //this overrides the paper size of "Letter" DO NOT USE FOR NITRO
dsPrintMgr.PaperSize = "Letter";
dsPrintMgr.Quality = 4000;
dsPrintMgr.PrintOnCenter = true;
dsPrintMgr.PrintInBackground = true;
dsPrintMgr.ScaleLineWeight = false;
dsPrintMgr.UseAssignedLineWeight = false;
dsPrintMgr.StyleTable = "monochrome.ctb";
dsPrintMgr.SetPrintRange(dsPrintRange_e.dsPrintRange_SpecifyWindow, "", true, 0D, 0D, 0D, 0D);
dsPrintMgr.ScaleToFit = true;
dsPrintMgr.SetPrintMargins(top, bottom, left, right);
dsPrintMgr.PrintOut(1, outputFileLocationName);
// end of printer set up
}
}
}
}// end of BlockSelection method
I've made a small tool bar that sits in a transparent form, it loads a variable sized menu from a text file and can be changed on the fly. Each button is a type of Label, the bar is just a list of buttons and adds/removes them in the correct spots. Width of the form is only a little bigger than the menu bar so that sub menu isn't cut off
Everything is working sweet except, when I reload everything part of the toolbar is lost. I've attempted to change the width so many ways, I've cleared and removed the controls from the form, refreshing the form/menu, updating it etc however nothing seems to make it work as intended EXCEPT if I call the reload function twice in a row, it works. I can't see why calling it once doesn't work but calling it twice works.
I'm fine with calling reload twice in a row as it would only be called a couple times a week.
Question: what on earth is causing this?
photo of issues first photo shows what it should look like, second is after removing a menu button and reloading, third is after adding a button and reloading
//calling this.reload() doesn't work
//calling this.reload();this.reload() works
void reload(Object o = null, EventArgs e = null)
{
this._menuBar.clear();
this.loadFromFile();
}
void loadFromFile(Object o = null, EventArgs e = null)
{
try
{
if (File.Exists("kpi.txt"))
{
string cline = "", cmenu = "", lhs = "";
menuList mb = null;
StreamReader sr = new StreamReader("kpi.txt");
while (!sr.EndOfStream)
{
cline = sr.ReadLine(); //get current line
if (cline.Length > 0 && cline[0] != ';')
{
//check if main menu/command
if (cline[0] == '[')
{
cmenu = Regex.Match(cline, #"(?<=^\[)[a-zA-Z -\#_{-~\^\r\n]+(?=\])").Value;
if (cmenu != "")
{
mb = this._menuBar.addMenuButton(cmenu);
mb.data["options"] = Regex.Match(cline, #"\/\w+$").Value;
var match = Regex.Match(cline, #"(?<=<)([^>\[\]\r\n]+)(?=>)");
mb.data["count"] = (match.Success ? match.Value : "0");
mb.data["copy"] = "";
applyMenuOptions(mb, false);
}
}
//just a standard line
else
{
cline = cline.Trim();
lhs = Regex.Match(cline, #"^[^\;\<\[\]\r\n]+(?=$|\<|\;)").Value;
if (mb.getSubMenuItem(lhs) == null)
{
var newButton = mb.addSubMenu(lhs);
if (newButton != null)
{
newButton.parent = mb;
newButton.data["options"] = mb.data["options"];
newButton.data["copy"] = Regex.Match(cline, #"((?<=\;)[^\[\]\<\r\n]+(?=<|$))").Value;
var matches = Regex.Match(cline, #"(?<=<)([^>\[\]\r\n]+)(?=>)");
int intout = 0;
if (int.TryParse(matches.Value, out intout))
{//no description
newButton.data["description"] = "";
newButton.data["count"] = intout.ToString();
}
else
{
newButton.data["description"] = matches.Value;
newButton.data["count"] = (matches.NextMatch().Success ? matches.NextMatch().Value : "0");
}
applyMenuOptions(newButton);
newButton.addMiddleClick(this.addcopy);
if (newButton.data["options"].Contains("i"))
{
newButton.addRightClick(this.appendInfo);
newButton.addRightClick(this.increment);
}
}
}
}
}
}
sr.Close();
this._menuBar.squish();
this.Width = this._menuBar.Width+50;
}
else
{
menuList mb = this._menuBar.addMenuButton("menu");
mb.data["options"] = "\\m";
mb.data["count"] = "0";
mb.data["copy"] = "";
mb.data["description"] = "";
applyMenuOptions(mb, false);
saveDictonary();
}
}
catch (Exception ex)
{
MessageBox.Show("Failed to load data " + ex);
//ILog log = LogManager.GetLogger(typeof(Program));
//log.Info(ex);
}
}
public menuList addMenuButton(string s, int w = 0, int h = 0, int x = -1, int y = -1)
{
menuList mb = new menuList(this._form, s);
if (this.menuItems.Exists(z => z.Text == s)) return null;
mb.Width = (w==0?settings.intOf("ButtonWidth"):w);
mb.Height = (h==0?settings.IntOf("ButtonHeight"):h);
if (x == -1 || y == -1)
mb.Location = new Point(this.menuItems.Count > 0 ? this.menuItems.Last().Location.X + this.menuItems.Last().Width : padding);
else mb.Location = new Point(x, y);
mb.BringToFront();
mb.Show();
this.menuItems.Add(mb);
// this.Refresh();
return mb;
}
internal void clear()
{
foreach(var i in this.menuItems)
{
this._form.Controls.Remove(i);
i.clear();
i.Dispose();
}
this.menuItems.Clear();
this._form.Controls.Remove(this);
this.menuItems = new List<menuList>();
this._form.Controls.Add(this);
}
internal void squish()
{
try
{
this.Width = (this.menuItems.Count * this.menuItems.First().Width) + (2 * padding);
}
catch(Exception ex) { MessageBox.Show(""+ex); }
}
Found the culprit, bother the button class and the tool bar class were both adding themselves to the form control instead of button class adding to the tool bar (picture box) controls!
Removing transparency showed the buttons not moving when the tool bar was moved!
I get this error. Later I searched and found out the reason of illegal characters in my XML and its solution. But I don't have the access to edit any of these files. My job is to read and fetch the tag value, attribute value and similar stuff. SO I can't replace the binary characters with escapes like '\x01' with . Also I tried to include CheckCharacters =false in XMLreader settings. It doesn't take this. Still it is throwing the same error.
Is it not possible to fix in XMLreader? I read about XMLtextReader. It can skip the exception. But already I have coded for all my features using XMLreader. It would be good if I can find a solution for this. Otherwise I would have to change all my code.
My code:
private void button1_Click(object sender, EventArgs e)
{
int i = 0;
var filenames = System.IO.Directory
.EnumerateFiles(textBox1.Text, "*.xml", System.IO.SearchOption.AllDirectories)
.Select(System.IO.Path.GetFullPath);
foreach (var f in filenames)
{
var resolver = new XmlUrlOverrideResolver();
resolver.DtdFileMap[#"X1.DTD"] = #"\\location\X1.DTD";
resolver.DtdFileMap[#"R2.DTD"] = #"\\location\X2.DTD";
resolver.DtdFileMap[#"R5.DTD"] = #"\\location\R5.DTD";
XmlReaderSettings settings = new XmlReaderSettings();
settings.DtdProcessing = DtdProcessing.Parse;
settings.XmlResolver = resolver;
XmlReader doc = XmlReader.Create(f, settings);
while (doc.Read())
{
if ((doc.NodeType == XmlNodeType.Element) && (doc.Name == "ap"))
{
if (doc.HasAttributes)
{
String fin = doc.GetAttribute("ap");
if (fin == "no")
{
String[] array = new String[10000];
array[i] = (f);
File.AppendAllText(#"\\location\NAPP.txt", array[i] + Environment.NewLine);
i++;
}
else
{
String[] abs = new String[10000];
abs[i] = (f);
File.AppendAllText(#"\\location\APP.txt", abs[i] + Environment.NewLine);
i++;
}
}
}
}
}
MessageBox.Show("Done");
}
This is a very simple example of character "filter" that will replae the 0x06 character with a space:
public class MyStreamReader : StreamReader {
public MyStreamReader(string path)
: base(path) {
}
public override int Read(char[] buffer, int index, int count) {
int res = base.Read(buffer, index, count);
for (int i = 0; i < res; i++) {
if (buffer[i] == 0x06) {
buffer[i] = ' ';
}
}
return res;
}
}
You use it this way:
using (var sr = new MyStreamReader(f)) {
var doc = XmlReader.Create(sr, settings);
Note that it's very simple because it's replacing a character (the 0x06) with another character of the same "length" (the space). If you wanted to replace a character with a "sequence" of characters (to escape it), it would get more complex (not impossible, 30 minutes of work difficult)
(I have checked and it seems the XmlTextReader only uses that method and not the Read() method)
As always, when a programmer tells you 30 minutes, it means 0 minutes or 2 hours :-)
This is the "more complex" ReplacingStreamReader:
/// <summary>
/// Only the Read methods are supported!
/// </summary>
public class ReplacingStreamReader : StreamReader
{
public ReplacingStreamReader(string path)
: base(path)
{
}
public Func<char, string> ReplaceWith { get; set; }
protected char[] RemainingChars { get; set; }
protected int RemainingCharsIndex { get; set; }
public override int Read()
{
int ch;
if (RemainingChars != null)
{
ch = RemainingChars[RemainingCharsIndex];
RemainingCharsIndex++;
if (RemainingCharsIndex == RemainingChars.Length)
{
RemainingCharsIndex = 0;
RemainingChars = null;
}
}
else
{
ch = base.Read();
if (ch != -1)
{
string replace = ReplaceWith((char)ch);
if (replace == null)
{
// Do nothing
}
else if (replace.Length == 1)
{
ch = replace[0];
}
else
{
ch = replace[0];
RemainingChars = replace.ToCharArray(1, replace.Length - 1);
RemainingCharsIndex = 0;
}
}
}
return ch;
}
public override int Read(char[] buffer, int index, int count)
{
int res = 0;
// We leave error handling to the StreamReader :-)
// We handle only "working" parameters
if (RemainingChars != null && buffer != null && index >= 0 && count > 0 && index + count <= buffer.Length)
{
int remainingCharsCount = RemainingChars.Length - RemainingCharsIndex;
res = Math.Min(remainingCharsCount, count);
Array.Copy(RemainingChars, RemainingCharsIndex, buffer, index, res);
RemainingCharsIndex += res;
if (RemainingCharsIndex == RemainingChars.Length)
{
RemainingCharsIndex = 0;
RemainingChars = null;
}
if (res == count)
{
return res;
}
index += res;
count -= res;
}
while (true)
{
List<char> sb = null;
int res2 = base.Read(buffer, index, count);
if (res2 == 0 || ReplaceWith == null)
{
return res;
}
int j = 0;
for (int i = 0; i < res2; i++)
{
char ch = buffer[index + i];
string replace = ReplaceWith(ch);
if (sb != null)
{
if (replace == null)
{
sb.Add(ch);
}
else
{
sb.AddRange(replace);
}
}
else if (replace == null)
{
buffer[j] = ch;
j++;
}
else if (replace.Length == 1)
{
buffer[j] = replace[0];
j++;
}
else if (replace.Length == 0)
{
// We do not advance
}
else
{
sb = new List<char>();
sb.AddRange(replace);
}
}
res2 = j;
if (sb != null)
{
int res3 = Math.Min(sb.Count, count - res2);
sb.CopyTo(0, buffer, index + res2, res3);
if (res3 < sb.Count)
{
RemainingChars = new char[sb.Count - res3];
RemainingCharsIndex = 0;
sb.CopyTo(res3, RemainingChars, 0, RemainingChars.Length);
}
res += res3;
}
else
{
res2 = j;
// Can't happen if sb != null (at least a character must
// have been added)
if (res2 == 0)
{
continue;
}
}
res += res2;
return res;
}
}
}
Use it like:
using (var sr = new ReplacingStreamReader(f))
{
sr.ReplaceWith = x =>
{
return x == 0x6 ? " " : null;
// return x == '.' ? " " : null; // Replace all . with
};
var doc = XmlReader.Create(sr, settings);
Be aware that the ReplacingStreamReader doesn't "know" which part of the xml it is modifying, so rarely a "blind" replace is ok :-) Other than this limitation, you can replace any character with any string (null in the ReplaceWith means "keep the current character", equivalent to x.ToString() in the example given. Returning string.Empty is valid, means remove the current character).
The class is quite interesting: it keeps a char[] RemainingChars with the chars that have been read (and filtered by ReplaceWith) but that haven't been returned by a Read() method because the passed buffer was too much small (the ReplaceWith method could "enlarge" the read string, making it too much big for the buffer!). Note that sb is a List<char> instead of a StringBuilder. Probably using one or the other would be nearly equivalent, code-wise.
You could first read the content into a string replace (escape) the content, and then load it into a XmlReader:
foreach (var f in filenames) {
string text;
using (StreamReader s = new StreamReader(f,Encoding.UTF8)) {
text = s.ReadToEnd();
}
text = text.Replace("\x01",#""); //replace the content
//load some settings
var resolver = new XmlUrlOverrideResolver();
resolver.DtdFileMap[#"X1.DTD"] = #"\\location\X1.DTD";
resolver.DtdFileMap[#"R2.DTD"] = #"\\location\X2.DTD";
resolver.DtdFileMap[#"R5.DTD"] = #"\\location\R5.DTD";
XmlReaderSettings settings = new XmlReaderSettings();
settings.DtdProcessing = DtdProcessing.Parse;
settings.XmlResolver = resolver;
XmlReader doc = XmlReader.Create(text, settings);
//perform processing task
//...
}
I am trying to create a program which can sort the number of results associated with any specified google search. I need a big table very fast so I thought about using a loop. Each time I try it though, the debugger crashes due to a "System.Windows.Markup.XamlParseException".
public long resultStat(string a)
{
var req = (HttpWebRequest)WebRequest.Create("https://www.google.ca/search?hl=fr&output=search&sclient=psy-ab&q=a" + a + "&btnK=");
using (req as IDisposable)
{
WebResponse rep = req.GetResponse();
Stream str = rep.GetResponseStream();
StreamReader rdr = new StreamReader(str);
string res = rdr.ReadToEnd();
rdr.Close();
//This is my code to get the number results (it works perfectly)
int index = res.IndexOf(">Environ");
int cond = 0;
string final = "";
try
{
while (res[++index] != '<')
{
if (cond-- == 0 && res[index] != '&')
{ final += res[index]; cond = 0; }
else if (res[index] == '&') cond = 5;
}
}
catch { return 0; }
string temp = "";
foreach (char i in final) if (i < 48 && i > 58) temp += i;
return Int64.Parse(temp);
}
}
This whole method is simply used in the main in a for loop such as :
public void main()
{
//Other code
for (int i = 0; i < 3; i++) resultStat(i.ToString()); // For example
//Other code
}
I know it's the problem because as soon as I comment the loop, or lower it to one rep, nothing goes wrong. I've tried:
HttpWebRequest().Abort();
HttpWebRequest().KeepAlive = false;
It didn't work
I don't think the away you are doing is the correct way to do this. The simple one i can tell you is use Lib curl c#. You can send in an array of urls and get response as an array. That would be perfect for what you require here. Here is a sample class code below that does the multitasking itself. You just send in the urls.
public class MultiHttp
{
public static string UserAgent = "Mozilla 5.0";
public static string Header = "Content-Type: application/x-www-form-urlencoded; charset=UTF-8";
private static string[] Result;
public static string[] MultiPost(string[] Url, string post, int timeOut)
{
Result = new string[post.Length];
try
{
Curl.GlobalInit((int)CURLinitFlag.CURL_GLOBAL_ALL);
Easy.WriteFunction wf = new Easy.WriteFunction(OnWriteData);
//Easy.HeaderFunction hf = new Easy.HeaderFunction(OnHeaderData);
Easy[] easy = new Easy[Url.Length];
Multi multi = new Multi();
for (int i = 0; i < Url.Length; i++)
{
if (Url[i] != null)
{
easy[i] = new Easy();
easy[i].SetOpt(CURLoption.CURLOPT_URL, Url[i]);
easy[i].SetOpt(CURLoption.CURLOPT_WRITEFUNCTION, wf);
easy[i].SetOpt(CURLoption.CURLOPT_WRITEDATA, i);
//easy[i].SetOpt(CURLoption.CURLOPT_HEADERFUNCTION, hf);
//easy[i].SetOpt(CURLoption.CURLOPT_HEADERDATA, i);
easy[i].SetOpt(CURLoption.CURLOPT_TIMEOUT, timeOut);
easy[i].SetOpt(CURLoption.CURLOPT_USERAGENT, UserAgent);
Slist sl = new Slist();
sl.Append(Header);
easy[i].SetOpt(CURLoption.CURLOPT_HTTPHEADER, sl);
easy[i].SetOpt(CURLoption.CURLOPT_POSTFIELDS, post);
easy[i].SetOpt(CURLoption.CURLOPT_FOLLOWLOCATION, true);
easy[i].SetOpt(CURLoption.CURLOPT_POST, true);
//easy[i].SetOpt(CURLoption.CURLOPT_NOBODY, true);
if (Url[i].Contains("https"))
{
easy[i].SetOpt(CURLoption.CURLOPT_SSL_VERIFYHOST, 1);
easy[i].SetOpt(CURLoption.CURLOPT_SSL_VERIFYPEER, 0);
}
multi.AddHandle(easy[i]);
}
}
int stillRunning = 1;
while (multi.Perform(ref stillRunning) == CURLMcode.CURLM_CALL_MULTI_PERFORM) ;
while (stillRunning != 0)
{
multi.FDSet();
int rc = multi.Select(1000); // one second
switch (rc)
{
case -1:
stillRunning = 0;
break;
case 0:
default:
{
while (multi.Perform(ref stillRunning) == CURLMcode.CURLM_CALL_MULTI_PERFORM) ;
break;
}
}
}
// various cleanups
multi.Cleanup();
for (int i = 0; i < easy.Length; i++)
{
easy[i].Cleanup();
}
Curl.GlobalCleanup();
}
catch (Exception)
{
//r = ex+"";
}
return Result;
}
public static Int32 OnWriteData(Byte[] buf, Int32 size, Int32 nmemb,
Object extraData)
{
int tmp = Convert.ToInt32(extraData.ToString()); ;
Result[tmp] += System.Text.Encoding.UTF8.GetString(buf);
return size * nmemb;
}
}
Call it like :
String[] url= new String[2];
url[1]="https://www.google.ca/search?hl=fr&output=search&sclient=psy-ab&q=a1&btnK=";
url[2]="https://www.google.ca/search?hl=fr&output=search&sclient=psy-ab&q=a2&btnK=";
string postString=""; // IF YOU DO NOT WANT TO POST ANYTHING YOU CAN DO THE SAME THING KEEP URL THE SAME SEND POST ARRAY AND CHANGE THE CLASS IT WORKS BOTH WAYS
String[] result = MultiHttp.MultiPost(url, postString, timeOut);
Its just a sample but will get you the working idea to sort out your problem.
I' have a Project that needs to do a mailmerge, I'm performing this with VSTO. I need to check if all records on the MailMerge.DataSource.DataFields are ok. i'm doing that with this code.
public void verificarPersonas(Word.Document Doc)
{
ThisAddIn ThisAddIn = Globals.ThisAddIn;
List<Personas> miListaPersonas = new List<Personas>();
decimal nRecords = Doc.MailMerge.DataSource.RecordCount;
if (nRecords == 0)
{
cambiarEstado("Empty db or documento does'n prepared for mail merge", false);
}
else
{
string fieldIdentificacion = persParm("Identificacion");
string fieldNombre = persParm("Nombres");
string fieldApellido = persParm("Apellidos");
string fieldEmail = persParm("Email");
string fieldDireccion = persParm("Direccion");
string fieldTelefono = persParm("Telefono");
if (String.IsNullOrEmpty(fieldIdentificacion) || String.IsNullOrEmpty(fieldNombre))
{
cambiarEstado("", false);
return;
}
else
{
for (int i = 1; i <= nRecords; i++)
{
Doc.MailMerge.DataSource.FirstRecord = i;
Doc.MailMerge.DataSource.LastRecord = i;
// Here Allways get the first record
dynamic fields = Doc.MailMerge.DataSource.DataFields;
// ________________________________
Personas personaActual = new Personas();
personaActual.IdPersona = 0;
try
{
personaActual.Identificacion = fields(fieldIdentificacion).value;
personaActual.Nombres = fields(fieldNombre).value;
personaActual.Apellidos = (String.IsNullOrEmpty(fieldApellido) ? "" : fields(fieldApellido).value);
personaActual.Email = (String.IsNullOrEmpty(fieldEmail) ? "" : fields(fieldEmail).value);
personaActual.Direccion = (String.IsNullOrEmpty(fieldDireccion) ? "" : fields(fieldDireccion).value);
personaActual.Telefono = (String.IsNullOrEmpty(fieldTelefono) ? "" : fields(fieldTelefono).value);
miListaPersonas.Add(personaActual);
}
catch (Exception e)
{
cambiarEstado(""+e.Message, false);
return;
}
}
string listaPersonasJson = JsonConvert.SerializeObject(miListaPersonas);
string respuesta = wt.getWebData("Personas", "verificarPersonasVSTO", new { personas = listaPersonasJson });
}
}
}
My problem is that dynamic fields = Doc.MailMerge.DataSource.DataFields; allways get the first record.
How can I do to get datafields for the active record ?
After some hours of research and some tries. get that the fields collection of datasource dont move the pointer when you set FirstRecord and Lastrecord, it must be moved using activerecords, using WdMailMergeActiveRecord enumeration, sonething like this:
int nRecords = Doc.MailMerge.DataSource.RecordCount;
for (int i = 1; i <= nRecords; i++)
{
Doc.MailMerge.DataSource.FirstRecord = i; //It doesn't work
Doc.MailMerge.DataSource.LastRecord = i; // it doesn't work
Doc.MailMerge.DataSource.ActiveRecord = (i == 1 ?
Word.WdMailMergeActiveRecord.wdFirstDataSourceRecord :Word.WdMailMergeActiveRecord.wdNextDataSourceRecord);
Doc.MailMerge.DataSource.ActiveRecord = (i == nRecords ? Word.WdMailMergeActiveRecord.wdLastDataSourceRecord : Doc.MailMerge.DataSource.ActiveRecord);
dynamic fields = Doc.MailMerge.DataSource.DataFields;
}