<?xml version="1.0" encoding="UTF-8"?>

<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
	<channel>
		<title>AXForum - Блоги - b_nosoff</title>
		<link>//axforum.info/forums/blog.php?u=3759</link>
		<description>Microsoft Dynamics: Axapta, CRM, Navision. Форум, Вопросы и помощь специалистов.</description>
		<language>ru</language>
		<lastBuildDate>Fri, 24 Apr 2026 15:50:48 GMT</lastBuildDate>
		<generator>vBulletin</generator>
		<ttl>15</ttl>
		<image>
			<url>http://axforum.info//img.axforum.info/misc/rss.jpg</url>
			<title>AXForum - Блоги - b_nosoff</title>
			<link>//axforum.info/forums/blog.php?u=3759</link>
		</image>
		<item>
			<title>VCS sync: TreeNode not initialized</title>
			<link>//axforum.info/forums/blog.php?b=8279</link>
			<pubDate>Tue, 22 Oct 2019 18:38:13 GMT</pubDate>
			<description>При стечении определенных обстоятельств синхронизация с TFS выпадает с ошибкой TreeNode not initialized.

Добавление следующих двух строчек в метод fromFile класса SysTreeNodeVSItem решает эту проблему


public void fromFile(FilenameOpen _filename)
{
    VSProjectFileNode vsItemNode = this.parmTreeNode() as VSItemNode;
    str treeNodePath = SysTreeNode::getPath(vsItemNode); //fix
    SysTreeNodeVSItem::importFromFile(_filename, vsItemNode);
    this.parmTreeNode(TreeNode::findNode(treeNodePath)); // fix
}
</description>
			<content:encoded><![CDATA[<div>При стечении определенных обстоятельств синхронизация с TFS выпадает с ошибкой TreeNode not initialized.<br />
<br />
Добавление следующих двух строчек в метод fromFile класса SysTreeNodeVSItem решает эту проблему<br />
<br />
<div class="xpp"><div class="smallfont xpp_title">X++:</div><pre class="alt2 xpp_code"><span style="color: blue">public</span> <span style="color: blue">void</span> fromFile(FilenameOpen _filename)
{
    VSProjectFileNode vsItemNode = this.parmTreeNode() as VSItemNode;
    <span style="color: blue">str</span> treeNodePath = SysTreeNode::getPath(vsItemNode); <span style="color: green">//fix
</span>    SysTreeNodeVSItem::importFromFile(_filename, vsItemNode);
    this.parmTreeNode(TreeNode::findNode(treeNodePath)); <span style="color: green">// fix
</span>}</pre></div></div>

]]></content:encoded>
			<dc:creator>b_nosoff</dc:creator>
			<guid isPermaLink="true">//axforum.info/forums/blog.php?b=8279</guid>
		</item>
		<item>
			<title>Excel Add-In - Update Ledger journals</title>
			<link>//axforum.info/forums/blog.php?b=8265</link>
			<pubDate>Sun, 07 Oct 2018 01:08:48 GMT</pubDate>
			<description><![CDATA[To enable update on LedgerGeneralJournalService perform the following steps:

Add RecId field to the LedgerJournalTrans datasource of the AxdLedgerGeneralJournal query.

Изображение: https://www.axforum.info/forums/blog_attachment.php?attachmentid=435&stc=1&d=1538874098 

Set Update property of both LedgerJournalTable and LedgerJournalTrans datasources of the AxdLedgerGeneralJournal query to Yes.

Set Validate Property of the CustEPRemitInfo_BR relation of the LedgerJournalTrans table to No.

Implement bypass to super of update and updateList methods of the AxdLedgerGeneralJournal class.

Implement update method on the LedgerGeneralJournalService class

Изображение: https://www.axforum.info/forums/blog_attachment.php?attachmentid=436&stc=1&d=1538874453 

Add update method on the LedgerGeneralJournalService service and perform Register service on the service.

Deploy LedgerServices service group.

Open Organization administration \ Setup \ Document management \ Document data sources form and make sure LedgerGeneralJournalService is activated

Изображение: https://www.axforum.info/forums/blog_attachment.php?attachmentid=437&stc=1&d=1538874453 ]]></description>
			<content:encoded><![CDATA[<div>To enable update on LedgerGeneralJournalService perform the following steps:<br />
<br />
Add RecId field to the LedgerJournalTrans datasource of the AxdLedgerGeneralJournal query.<br />
<br />
<img src="https://www.axforum.info/forums/blog_attachment.php?attachmentid=435&amp;stc=1&amp;d=1538874098" border="0" alt="" /><br />
<br />
Set Update property of both LedgerJournalTable and LedgerJournalTrans datasources of the AxdLedgerGeneralJournal query to Yes.<br />
<br />
Set Validate Property of the CustEPRemitInfo_BR relation of the LedgerJournalTrans table to No.<br />
<br />
Implement bypass to super of update and updateList methods of the AxdLedgerGeneralJournal class.<br />
<br />
Implement update method on the LedgerGeneralJournalService class<br />
<br />
<img src="https://www.axforum.info/forums/blog_attachment.php?attachmentid=436&amp;stc=1&amp;d=1538874453" border="0" alt="" /><br />
<br />
Add update method on the LedgerGeneralJournalService service and perform Register service on the service.<br />
<br />
Deploy LedgerServices service group.<br />
<br />
Open Organization administration \ Setup \ Document management \ Document data sources form and make sure LedgerGeneralJournalService is activated<br />
<br />
<img src="https://www.axforum.info/forums/blog_attachment.php?attachmentid=437&amp;stc=1&amp;d=1538874453" border="0" alt="" /></div>


<!-- attachments -->
	<div style="margin-top:10px">

		
			<fieldset class="fieldset">
				<legend>Миниатюры</legend>
				<div style="padding:3px">
				
	<a href="//axforum.info/forums/blog_attachment.php?attachmentid=435&amp;d=1538874095" target="attachment" rel="Lightbox" id="attachment435"><img class="thumbnail" src="//axforum.info/forums/blog_attachment.php?attachmentid=435&amp;stc=1&amp;thumb=1&amp;d=1538874095" border="0" alt="Нажмите на изображение для увеличения
Название: recid.png
Просмотров: 2291
Размер:	41.0 Кб
ID:	435" /></a>
	&nbsp;
	

	<a href="//axforum.info/forums/blog_attachment.php?attachmentid=436&amp;d=1538874450" target="attachment" rel="Lightbox" id="attachment436"><img class="thumbnail" src="//axforum.info/forums/blog_attachment.php?attachmentid=436&amp;stc=1&amp;thumb=1&amp;d=1538874450" border="0" alt="Нажмите на изображение для увеличения
Название: update.png
Просмотров: 1762
Размер:	23.7 Кб
ID:	436" /></a>
	&nbsp;
	
		<br /><br />
	

	<a href="//axforum.info/forums/blog_attachment.php?attachmentid=437&amp;d=1538874450" target="attachment" rel="Lightbox" id="attachment437"><img class="thumbnail" src="//axforum.info/forums/blog_attachment.php?attachmentid=437&amp;stc=1&amp;thumb=1&amp;d=1538874450" border="0" alt="Нажмите на изображение для увеличения
Название: ds.png
Просмотров: 1730
Размер:	11.1 Кб
ID:	437" /></a>
	&nbsp;
	

				</div>
			</fieldset>
		
		
		
		

	</div>
<!-- / attachments -->
]]></content:encoded>
			<dc:creator>b_nosoff</dc:creator>
			<guid isPermaLink="true">//axforum.info/forums/blog.php?b=8265</guid>
		</item>
		<item>
			<title>Setup MPOS product image source</title>
			<link>//axforum.info/forums/blog.php?b=8245</link>
			<pubDate>Thu, 17 Aug 2017 20:57:00 GMT</pubDate>
			<description><![CDATA[[DRAFT]

Setup channel profile
Вложение 393 (//axforum.info/forums/attachment.php?attachmentid=393)

The path to images should be as follows
Вложение 394 (//axforum.info/forums/attachment.php?attachmentid=394)

Create website in IIS
Вложение 395 (//axforum.info/forums/attachment.php?attachmentid=395)]]></description>
			<content:encoded><![CDATA[<div>[DRAFT]<br />
<br />
Setup channel profile<br />
<a href="//axforum.info/forums/blog_attachment.php?attachmentid=393&amp;d=1503003103" rel="Lightbox" id="attachment393" ><img src="//axforum.info/forums/blog_attachment.php?attachmentid=393&amp;thumb=1&amp;d=1503003103" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: channel profiles.png
Просмотров: 1820
Размер:	19.6 Кб
ID:	393" style="margin: 2px" /></a><br />
<br />
The path to images should be as follows<br />
<a href="//axforum.info/forums/blog_attachment.php?attachmentid=394&amp;d=1503003103" rel="Lightbox" id="attachment394" ><img src="//axforum.info/forums/blog_attachment.php?attachmentid=394&amp;thumb=1&amp;d=1503003103" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: path.png
Просмотров: 1987
Размер:	15.4 Кб
ID:	394" style="margin: 2px" /></a><br />
<br />
Create website in IIS<br />
<a href="//axforum.info/forums/blog_attachment.php?attachmentid=395&amp;d=1503003123" rel="Lightbox" id="attachment395" ><img src="//axforum.info/forums/blog_attachment.php?attachmentid=395&amp;thumb=1&amp;d=1503003123" class="thumbnail" border="0" alt="Нажмите на изображение для увеличения
Название: IIS1.png
Просмотров: 1796
Размер:	89.0 Кб
ID:	395" style="margin: 2px" /></a></div>

]]></content:encoded>
			<dc:creator>b_nosoff</dc:creator>
			<guid isPermaLink="true">//axforum.info/forums/blog.php?b=8245</guid>
		</item>
		<item>
			<title>Падает клиент при передаче файла с клиента на сервер</title>
			<link>//axforum.info/forums/blog.php?b=8219</link>
			<pubDate>Fri, 21 Oct 2016 11:36:05 GMT</pubDate>
			<description>Не новая проблема, уже обсуждалась не раз (http://axforum.info/forums/showthread.php?t=41813). Понравилась идея (http://axforum.info/forums/showthread.php?p=267350#post267350) *someOne* передавать файл по кускам, только решил объединить классы в один и переписать на .NET. Заодно подумал, что неплохо было бы немного сжимать данные. Может, кому-то пригодится.</description>
			<content:encoded><![CDATA[<div>Не новая проблема, уже обсуждалась не <a href="http://axforum.info/forums/showthread.php?t=41813" target="_blank">раз</a>. Понравилась <a href="http://axforum.info/forums/showthread.php?p=267350#post267350" target="_blank">идея</a> <b>someOne</b> передавать файл по кускам, только решил объединить классы в один и переписать на .NET. Заодно подумал, что неплохо было бы немного сжимать данные. Может, кому-то пригодится.</div>


<!-- attachments -->
	<div style="margin-top:10px">

		
		
		
		
			<fieldset class="fieldset">
				<legend>Вложения</legend>
				<table cellpadding="0" cellspacing="3" border="0">
				<tr>
	<td><img class="inlineimg" src="http://axforum.info//img.axforum.info/attach/xpo.gif" alt="Тип файла: xpo" width="16" height="16" border="0" style="vertical-align:baseline" /></td>
	<td><a href="//axforum.info/forums/blog_attachment.php?attachmentid=391&amp;d=1481830987">SysFileTransfer.xpo</a> (7.6 Кб, 1655 просмотров)</td>
</tr>
				</table>
			</fieldset>
		

	</div>
<!-- / attachments -->
]]></content:encoded>
			<dc:creator>b_nosoff</dc:creator>
			<guid isPermaLink="true">//axforum.info/forums/blog.php?b=8219</guid>
		</item>
		<item>
			<title>Обновление CU11 AX2012R3 ModernPOS</title>
			<link>//axforum.info/forums/blog.php?b=8215</link>
			<pubDate>Sat, 17 Sep 2016 23:48:40 GMT</pubDate>
			<description>При обновлении ModernPOS на CU11 внезапно столкнулся с неожиданной проблемой. Несмотря на настройку Direct database connection при активации MPOS требовал указать адрес Retail Server. После продолжительных изысканий оказалось, что по какой-то причине при установке не был зарегистрировал COM компонент Microsoft.Dynamics.Commerce.ClientBrokerProxy.dll. Регистрация с помощью regsvr32 решила проблему.</description>
			<content:encoded><![CDATA[<div>При обновлении ModernPOS на CU11 внезапно столкнулся с неожиданной проблемой. Несмотря на настройку Direct database connection при активации MPOS требовал указать адрес Retail Server. После продолжительных изысканий оказалось, что по какой-то причине при установке не был зарегистрировал COM компонент Microsoft.Dynamics.Commerce.ClientBrokerProxy.dll. Регистрация с помощью regsvr32 решила проблему.</div>

]]></content:encoded>
			<dc:creator>b_nosoff</dc:creator>
			<guid isPermaLink="true">//axforum.info/forums/blog.php?b=8215</guid>
		</item>
		<item>
			<title>Excel OXML Book Protection</title>
			<link>//axforum.info/forums/blog.php?b=8172</link>
			<pubDate>Mon, 20 Jul 2015 21:27:11 GMT</pubDate>
			<description><![CDATA[Защита книги и/или листа Excel паролем оказалась занимательной задачей. Статья на MSDN (https://msdn.microsoft.com/en-us/library/documentformat.openxml.spreadsheet.workbookprotection.aspx) говорит, что для защиты книги требуется указать целых четыре параметра - workbookAlgorithmName, workbookHashValue, workbookSaltValue, workbookSpinCount. Excel при установке защиты через интерфейс использует алгоритм SHA-512 и 100000 раундов, будем использовать аналогичные параметры. 

Для установки защиты книги на классы OxmlWorkBook_RU и Oxml_RU достаточно добавить два метода:

OxmlWorkBook_RUpublic void protect(
    str _password = "",
    boolean _structure = false,
    boolean _windows = false)
{
    DocumentFormat.OpenXml.Spreadsheet.WorkbookProtection workbookProtection;
    str hashValue, saltValue;
    int spinCount;

    workbookProtection = workbook.get_WorkbookProtection();

    if (!workbookProtection)
    {
        workbookProtection = new DocumentFormat.OpenXml.Spreadsheet.WorkbookProtection();

        workbook.set_WorkbookProtection(workbookProtection);
    }

    [hashValue, saltValue, spinCount] = Oxml_RU::calcHash(_password, saltValue, spinCount);

    workbookProtection.set_WorkbookAlgorithmName(OXML_RU::setStringValue("SHA-512"));
    workbookProtection.set_WorkbookHashValue(DocumentFormat.OpenXml.Base64BinaryValue::FromString(hashValue));
    workbookProtection.set_WorkbookSaltValue(DocumentFormat.OpenXml.Base64BinaryValue::FromString(saltValue));
    workbookProtection.set_WorkbookSpinCount(DocumentFormat.OpenXml.UInt32Value::FromUInt32(System.Convert::ToUInt32(spinCount)));
    workbookProtection.set_LockStructure(OXML_RU::setBooleanValue(_structure));
    workbookProtection.set_LockWindows(OXML_RU::setBooleanValue(_windows));
}

Oxml_RUprivate static server container calcHash(container _params)
{
    System.Text.Encoding encoding = System.Text.Encoding::GetEncoding("UTF-16LE");
    System.Security.Cryptography.SHA512Managed sha512 = new System.Security.Cryptography.SHA512Managed();
    System.Byte[] buffer, hash, salt;
    System.UInt32 uint32;
    str password, hashValue, saltValue;
    int i, spinCount, hashLength, bufferLength, saltLength;

    str createSalt()
    {
        System.DateTime randomValue = System.DateTime::get_Now();

        buffer = encoding.GetBytes(randomValue.ToString());

        hash = sha512.ComputeHash(buffer);

        buffer = new System.Byte[16]();

        System.Array::Copy(hash, 0, buffer, 0, buffer.get_Length());

        saltValue = System.Convert::ToBase64String(buffer);

        return saltValue;
    }

    [password, saltValue, spinCount] = _params;

    saltValue = saltValue ? saltValue : createSalt();

    spinCount = spinCount > 0 ? spinCount : 100000;

    salt = System.Convert::FromBase64String(saltValue);

    saltLength = salt.get_Length();

    buffer = encoding.GetBytes(password);

    bufferLength = buffer.get_Length();

    hash = new System.Byte[bufferLength + saltLength]();

    System.Array::Copy(salt, 0, hash, 0, salt.get_Length());

    System.Array::Copy(buffer, 0, hash, salt.get_Length(), buffer.get_Length());

    hashLength = hash.get_Length();

    buffer = new System.Byte[hashLength]();

    bufferLength = buffer.get_Length();

    System.Array::Copy(hash, 0, buffer, 0, buffer.get_Length());

    sha512.Initialize();

    hash = new System.Byte[0]();

    for (i = 0; i <= spinCount; i++)
    {
        hash = sha512.ComputeHash(buffer);

        hashLength = hash.get_Length();
        bufferLength = buffer.get_Length();

        if (bufferLength != hashLength + 4)
        {
            bufferLength = hashLength + 4;

            buffer = new System.Byte[bufferLength]();
        }

        uint32 = System.Convert::ToUInt32(i);

        System.Array::Copy(hash, 0, buffer, 0, hash.get_Length());

        System.Array::Copy(System.BitConverter::GetBytes(uint32), 0, buffer, hash.get_Length(), 4);
    }

    hashValue = System.Convert::ToBase64String(hash);

    encoding = null;

    sha512.Clear();
    sha512 = null;

    return [hashValue, saltValue, spinCount];
}

Стоит заметить, что расчет ста тысяч раундов хэша лучше проводить в CIL ;)]]></description>
			<content:encoded><![CDATA[<div>Защита книги и/или листа Excel паролем оказалась занимательной задачей. <a href="https://msdn.microsoft.com/en-us/library/documentformat.openxml.spreadsheet.workbookprotection.aspx" target="_blank">Статья на MSDN</a> говорит, что для защиты книги требуется указать целых четыре параметра - workbookAlgorithmName, workbookHashValue, workbookSaltValue, workbookSpinCount. Excel при установке защиты через интерфейс использует алгоритм SHA-512 и 100000 раундов, будем использовать аналогичные параметры. <br />
<br />
Для установки защиты книги на классы OxmlWorkBook_RU и Oxml_RU достаточно добавить два метода:<br />
<br />
OxmlWorkBook_RU<div class="xpp"><div class="smallfont xpp_title">X++:</div><pre class="alt2 xpp_code"><span style="color: blue">public</span> <span style="color: blue">void</span> protect(
    <span style="color: blue">str</span> _password = <span style="color: red">&quot;&quot;</span>,
    boolean _structure = <span style="color: blue">false</span>,
    boolean _windows = <span style="color: blue">false</span>)
{
    DocumentFormat.OpenXml.Spreadsheet.WorkbookProtection workbookProtection;
    <span style="color: blue">str</span> hashValue, saltValue;
    <span style="color: blue">int</span> spinCount;

    workbookProtection = workbook.get_WorkbookProtection();

    <span style="color: blue">if</span> (!workbookProtection)
    {
        workbookProtection = <span style="color: blue">new</span> DocumentFormat.OpenXml.Spreadsheet.WorkbookProtection();

        workbook.set_WorkbookProtection(workbookProtection);
    }

    [hashValue, saltValue, spinCount] = Oxml_RU::calcHash(_password, saltValue, spinCount);

    workbookProtection.set_WorkbookAlgorithmName(OXML_RU::setStringValue(<span style="color: red">&quot;SHA-512&quot;</span>));
    workbookProtection.set_WorkbookHashValue(DocumentFormat.OpenXml.Base64BinaryValue::FromString(hashValue));
    workbookProtection.set_WorkbookSaltValue(DocumentFormat.OpenXml.Base64BinaryValue::FromString(saltValue));
    workbookProtection.set_WorkbookSpinCount(DocumentFormat.OpenXml.UInt32Value::FromUInt32(System.Convert::ToUInt32(spinCount)));
    workbookProtection.set_LockStructure(OXML_RU::setBooleanValue(_structure));
    workbookProtection.set_LockWindows(OXML_RU::setBooleanValue(_windows));
}</pre></div><br />
Oxml_RU<div class="xpp"><div class="smallfont xpp_title">X++:</div><pre class="alt2 xpp_code"><span style="color: blue">private</span> <span style="color: blue">static</span> <span style="color: blue">server</span> <span style="color: blue">container</span> calcHash(<span style="color: blue">container</span> _params)
{
    System.Text.Encoding encoding = System.Text.Encoding::GetEncoding(<span style="color: red">&quot;UTF-16LE&quot;</span>);
    System.Security.Cryptography.SHA512Managed sha512 = <span style="color: blue">new</span> System.Security.Cryptography.SHA512Managed();
    System.Byte[] buffer, hash, salt;
    System.UInt32 uint32;
    <span style="color: blue">str</span> password, hashValue, saltValue;
    <span style="color: blue">int</span> i, spinCount, hashLength, bufferLength, saltLength;

    <span style="color: blue">str</span> createSalt()
    {
        System.DateTime randomValue = System.DateTime::get_Now();

        buffer = encoding.GetBytes(randomValue.ToString());

        hash = sha512.ComputeHash(buffer);

        buffer = <span style="color: blue">new</span> System.Byte[16]();

        System.Array::Copy(hash, 0, buffer, 0, buffer.get_Length());

        saltValue = System.Convert::ToBase64String(buffer);

        <span style="color: blue">return</span> saltValue;
    }

    [password, saltValue, spinCount] = _params;

    saltValue = saltValue ? saltValue : createSalt();

    spinCount = spinCount &gt; 0 ? spinCount : 100000;

    salt = System.Convert::FromBase64String(saltValue);

    saltLength = salt.get_Length();

    buffer = encoding.GetBytes(password);

    bufferLength = buffer.get_Length();

    hash = <span style="color: blue">new</span> System.Byte[bufferLength + saltLength]();

    System.Array::Copy(salt, 0, hash, 0, salt.get_Length());

    System.Array::Copy(buffer, 0, hash, salt.get_Length(), buffer.get_Length());

    hashLength = hash.get_Length();

    buffer = <span style="color: blue">new</span> System.Byte[hashLength]();

    bufferLength = buffer.get_Length();

    System.Array::Copy(hash, 0, buffer, 0, buffer.get_Length());

    sha512.Initialize();

    hash = <span style="color: blue">new</span> System.Byte[0]();

    <span style="color: blue">for</span> (i = 0; i &lt;= spinCount; i++)
    {
        hash = sha512.ComputeHash(buffer);

        hashLength = hash.get_Length();
        bufferLength = buffer.get_Length();

        <span style="color: blue">if</span> (bufferLength != hashLength + 4)
        {
            bufferLength = hashLength + 4;

            buffer = <span style="color: blue">new</span> System.Byte[bufferLength]();
        }

        uint32 = System.Convert::ToUInt32(i);

        System.Array::Copy(hash, 0, buffer, 0, hash.get_Length());

        System.Array::Copy(System.BitConverter::GetBytes(uint32), 0, buffer, hash.get_Length(), 4);
    }

    hashValue = System.Convert::ToBase64String(hash);

    encoding = <span style="color: blue">null</span>;

    sha512.Clear();
    sha512 = <span style="color: blue">null</span>;

    <span style="color: blue">return</span> [hashValue, saltValue, spinCount];
}</pre></div><br />
Стоит заметить, что расчет ста тысяч раундов хэша лучше проводить в CIL ;)</div>

]]></content:encoded>
			<dc:creator>b_nosoff</dc:creator>
			<guid isPermaLink="true">//axforum.info/forums/blog.php?b=8172</guid>
		</item>
		<item>
			<title>Определение SysOperationController в диалоге</title>
			<link>//axforum.info/forums/blog.php?b=8110</link>
			<pubDate>Thu, 08 May 2014 10:29:36 GMT</pubDate>
			<description><![CDATA[Класс SysSetupForm в AX2012 по какой-то причине не подвергся доработке после внедрения SysOperationFramework, и стало невозможно определить, что за класс вызвал диалог. Хотя доработка-то всего в пять строк:

public ClassName determineCallerName()
{
    #aot
    Object caller = editFormRun.args().caller();

    if (caller)
    {
        switch (true)
        {
            // fix -->
            case caller is SysOperationDialog:
                caller       = caller.controller();
                callerName   = classId2Name(classidget(caller));
                callerPath   = #classesPath;
                break;
            // fix <--
       ...

]]></description>
			<content:encoded><![CDATA[<div>Класс SysSetupForm в AX2012 по какой-то причине не подвергся доработке после внедрения SysOperationFramework, и стало невозможно определить, что за класс вызвал диалог. Хотя доработка-то всего в пять строк:<br />
<br />
<div class="xpp"><div class="smallfont xpp_title">X++:</div><pre class="alt2 xpp_code"><span style="color: blue">public</span> ClassName determineCallerName()
{
    #aot
    Object caller = editFormRun.args().caller();

    <span style="color: blue">if</span> (caller)
    {
        <span style="color: blue">switch</span> (<span style="color: blue">true</span>)
        {
            <span style="color: green">// fix --&gt;
</span>            <span style="color: blue">case</span> caller is SysOperationDialog:
                caller       = caller.controller();
                callerName   = classId2Name(classidget(caller));
                callerPath   = #classesPath;
                <span style="color: blue">break</span>;
            <span style="color: green">// fix &lt;--
</span>       ...</pre></div></div>

]]></content:encoded>
			<dc:creator>b_nosoff</dc:creator>
			<guid isPermaLink="true">//axforum.info/forums/blog.php?b=8110</guid>
		</item>
		<item>
			<title>Daily AccountingDistribution WTF</title>
			<link>//axforum.info/forums/blog.php?b=8097</link>
			<pubDate>Fri, 25 Apr 2014 12:34:21 GMT</pubDate>
			<description>Случилось разбираться с очень странной ошибкой при разноске корректирующей накладной:

---Цитата---
Не удается вставить несколько записей в Распределение по бухгалтерским счетам (AccountingDistribution). Сумма в валюте проводки: 0,00, RUB.
Запись уже существует.
---Конец цитаты---
Раскопки показали, что в методе DimensionDerivationDistributionRule.resetAllocationFactorOfMatchDistribution() кто-то забыл одну маленькую, но важную строку дописать:
if (totalAllocationFactor != 1)
{
    accountingDistributionListEnumerator = finalAccountingDistributionList.getEnumerator();

    while (accountingDistributionListEnumerator.moveNext())
    {
        accountingDistribution = accountingDistributionListEnumerator.current();

        if (maxDistributionRecId == accountingDistribution.RecId)
        {
            accountingDistribution.AllocationFactor = accountingDistribution.AllocationFactor + 1 - totalAllocationFactor;
            finalAccountingDistributionList.addEnd(accountingDistribution); //fix
            break;
        }
    }
}</description>
			<content:encoded><![CDATA[<div>Случилось разбираться с очень странной ошибкой при разноске корректирующей накладной:<br />
<div class="q">
	<div class="smallfont q_title">Цитата:</div>
	<div class="alt2 q_body">
		
			Не удается вставить несколько записей в Распределение по бухгалтерским счетам (AccountingDistribution). Сумма в валюте проводки: 0,00, RUB.<br />
Запись уже существует.
		
	</div>
</div>Раскопки показали, что в методе DimensionDerivationDistributionRule.resetAllocationFactorOfMatchDistribution() кто-то забыл одну маленькую, но важную строку дописать:<br />
<div class="xpp"><div class="smallfont xpp_title">X++:</div><pre class="alt2 xpp_code"><span style="color: blue">if</span> (totalAllocationFactor != 1)
{
    accountingDistributionListEnumerator = finalAccountingDistributionList.getEnumerator();

    <span style="color: blue">while</span> (accountingDistributionListEnumerator.moveNext())
    {
        accountingDistribution = accountingDistributionListEnumerator.current();

        <span style="color: blue">if</span> (maxDistributionRecId == accountingDistribution.RecId)
        {
            accountingDistribution.AllocationFactor = accountingDistribution.AllocationFactor + 1 - totalAllocationFactor;
            finalAccountingDistributionList.addEnd(accountingDistribution); <span style="color: green">//fix
</span>            <span style="color: blue">break</span>;
        }
    }
}</pre></div></div>

]]></content:encoded>
			<dc:creator>b_nosoff</dc:creator>
			<guid isPermaLink="true">//axforum.info/forums/blog.php?b=8097</guid>
		</item>
		<item>
			<title><![CDATA[AX 2012 R2 CU7 Setup "Searching for updates..."]]></title>
			<link>//axforum.info/forums/blog.php?b=6408</link>
			<pubDate>Thu, 06 Feb 2014 15:03:27 GMT</pubDate>
			<description><![CDATA[Столкнулся сегодня с необычным поведением инсталлятора AX - завис почти на час в состоянии "Searching for updates..." и не подавал никаких признаков, что он из него выйдет. 
Понятно было, что он пытается найти какие-либо обновления, но сервер не имел выхода в интернет и, видимо, это было для него необычным состоянием окружающей среды. 
Вывести его из этого состояния удалось, как ни странно, остановкой службы Windows Update, после чего установка сразу же двинулась дальше.]]></description>
			<content:encoded><![CDATA[<div>Столкнулся сегодня с необычным поведением инсталлятора AX - завис почти на час в состоянии &quot;Searching for updates...&quot; и не подавал никаких признаков, что он из него выйдет. <br />
Понятно было, что он пытается найти какие-либо обновления, но сервер не имел выхода в интернет и, видимо, это было для него необычным состоянием окружающей среды. <br />
Вывести его из этого состояния удалось, как ни странно, остановкой службы Windows Update, после чего установка сразу же двинулась дальше.</div>

]]></content:encoded>
			<dc:creator>b_nosoff</dc:creator>
			<guid isPermaLink="true">//axforum.info/forums/blog.php?b=6408</guid>
		</item>
		<item>
			<title>Настройка AX 2012 R2 Retail Synch Service</title>
			<link>//axforum.info/forums/blog.php?b=423</link>
			<pubDate>Mon, 09 Sep 2013 17:57:28 GMT</pubDate>
			<description>В поисках сакральных знаний о том, как заставить работать Retail Synch Service, нашел два полезных документа:
Retail Solution for AX 2012 - Deployment (http://ranaimahmood.blogspot.ru/2012/06/retail-solution-for-ax-2012-deployment.html) и Implementation guide for Commerce Data Exchange (http://download.microsoft.com/download/3/9/D/39D659F1-D4A2-4374-9464-4451BC627DB1/Implementation%20guide%20for%20Commerce%20Data%20Exchange_AX%202012.pdf)

Отмечу два нюанса, на которые новичку следует обратить внимание при установке - для всех экземпляров Synch Service, установленных в системе, необходимо создавать записи в форме настроек, но в профиле баз данных необходимо указывать именно конечные экземпляры, установленные на сервере магазина. И второе - если вы устанавливаете POS на WinXP, то у вас не будет работать IPSec, и, соответственно, во всей цепочке от центральной Synch Service, до магазина, придется его выключать.</description>
			<content:encoded><![CDATA[<div>В поисках сакральных знаний о том, как заставить работать Retail Synch Service, нашел два полезных документа:<br />
<a href="http://ranaimahmood.blogspot.ru/2012/06/retail-solution-for-ax-2012-deployment.html" target="_blank">Retail Solution for AX 2012 - Deployment</a> и <a href="http://download.microsoft.com/download/3/9/D/39D659F1-D4A2-4374-9464-4451BC627DB1/Implementation%20guide%20for%20Commerce%20Data%20Exchange_AX%202012.pdf" target="_blank">Implementation guide for Commerce Data Exchange</a><br />
<br />
Отмечу два нюанса, на которые новичку следует обратить внимание при установке - для всех экземпляров Synch Service, установленных в системе, необходимо создавать записи в форме настроек, но в профиле баз данных необходимо указывать именно конечные экземпляры, установленные на сервере магазина. И второе - если вы устанавливаете POS на WinXP, то у вас не будет работать IPSec, и, соответственно, во всей цепочке от центральной Synch Service, до магазина, придется его выключать.</div>

]]></content:encoded>
			<dc:creator>b_nosoff</dc:creator>
			<guid isPermaLink="true">//axforum.info/forums/blog.php?b=423</guid>
		</item>
		<item>
			<title>SSAS strange error</title>
			<link>//axforum.info/forums/blog.php?b=395</link>
			<pubDate>Tue, 16 Apr 2013 09:59:03 GMT</pubDate>
			<description>На одном из проектов столкнулся с редко, но метко появляющейся ошибкой Analysis Server при использовании прогнозных моделей

---Цитата---
Ошибка (Интеллектуальный анализ данных): Набор вариантов временных рядов должен быть разреженным, если он содержит только один вариант.
---Конец цитаты---
Как оказалось, сервер выпадает в такую ошибку если в исходном ряду содержится только одно значение. А при попытке воспроизведения исходные данные обычно уже менялись, и значений уже было несколько. Сюрприз-сюрприз ))</description>
			<content:encoded><![CDATA[<div>На одном из проектов столкнулся с редко, но метко появляющейся ошибкой Analysis Server при использовании прогнозных моделей<br />
<div class="q">
	<div class="smallfont q_title">Цитата:</div>
	<div class="alt2 q_body">
		
			Ошибка (Интеллектуальный анализ данных): Набор вариантов временных рядов должен быть разреженным, если он содержит только один вариант.
		
	</div>
</div>Как оказалось, сервер выпадает в такую ошибку если в исходном ряду содержится только одно значение. А при попытке воспроизведения исходные данные обычно уже менялись, и значений уже было несколько. Сюрприз-сюрприз ))</div>

]]></content:encoded>
			<dc:creator>b_nosoff</dc:creator>
			<guid isPermaLink="true">//axforum.info/forums/blog.php?b=395</guid>
		</item>
		<item>
			<title><![CDATA[Serializing & deserializing CLR objects in X++]]></title>
			<link>//axforum.info/forums/blog.php?b=268</link>
			<pubDate>Mon, 11 Jul 2011 15:14:44 GMT</pubDate>
			<description><![CDATA[string serializeClrObject(ClrObject _clrObject)
{
    System.Xml.Serialization.XmlSerializer  serializer;
    System.IO.StringWriter                  xml;
    ;

    xml = new ClrObject("System.IO.StringWriter", new System.Text.StringBuilder());

    serializer = new clrObject("System.Xml.Serialization.XmlSerializer", _clrObject.GetType());

    serializer.Serialize(xml, _clrObject);

    return xml.ToString();
}
ClrObject deserializeClrObject(string _className, string _serializedClass)
{
    System.Xml.Serialization.XmlSerializer  serializer;
    System.IO.StringReader                  xml;
    ClrObject                               clrObject;
    ;

    xml = new ClrObject("System.IO.StringReader", _serializedClass);

    clrObject = new ClrObject(_className);

    serializer = new clrObject("System.Xml.Serialization.XmlSerializer", clrObject.GetType());

    return serializer.Deserialize(xml);
}]]></description>
			<content:encoded><![CDATA[<div><div class="xpp"><div class="smallfont xpp_title">X++:</div><pre class="alt2 xpp_code">string serializeClrObject(ClrObject _clrObject)
{
    System.Xml.Serialization.XmlSerializer  serializer;
    System.IO.StringWriter                  xml;
    ;

    xml = <span style="color: blue">new</span> ClrObject(<span style="color: red">&quot;System.IO.StringWriter&quot;</span>, <span style="color: blue">new</span> System.Text.StringBuilder());

    serializer = <span style="color: blue">new</span> clrObject(<span style="color: red">&quot;System.Xml.Serialization.XmlSerializer&quot;</span>, _clrObject.GetType());

    serializer.Serialize(xml, _clrObject);

    <span style="color: blue">return</span> xml.ToString();
}</pre></div><br />
<div class="xpp"><div class="smallfont xpp_title">X++:</div><pre class="alt2 xpp_code">ClrObject deserializeClrObject(string _className, string _serializedClass)
{
    System.Xml.Serialization.XmlSerializer  serializer;
    System.IO.StringReader                  xml;
    ClrObject                               clrObject;
    ;

    xml = <span style="color: blue">new</span> ClrObject(<span style="color: red">&quot;System.IO.StringReader&quot;</span>, _serializedClass);

    clrObject = <span style="color: blue">new</span> ClrObject(_className);

    serializer = <span style="color: blue">new</span> clrObject(<span style="color: red">&quot;System.Xml.Serialization.XmlSerializer&quot;</span>, clrObject.GetType());

    <span style="color: blue">return</span> serializer.Deserialize(xml);
}</pre></div></div>

]]></content:encoded>
			<dc:creator>b_nosoff</dc:creator>
			<guid isPermaLink="true">//axforum.info/forums/blog.php?b=268</guid>
		</item>
		<item>
			<title>Yet another way to use serial port devices in DAX</title>
			<link>//axforum.info/forums/blog.php?b=248</link>
			<pubDate>Sat, 07 May 2011 07:00:00 GMT</pubDate>
			<description><![CDATA[Не думал я, что когда-нибудь буду что-либо писать в блог на АксФоруме... Вообще, больше читать люблю )) Но тут на днях столкнулся с темой, по которой не нашел чего почитать, вообще практически ничего по ней нет. Похоже тема столь древняя, что когда она гремела, интернетов еще толком не было. 
Тема эта - написание сервисного объекта для OPOS (была такая технология). Почему она меня заинтересовала спустя десять лет, как она была актуальна? А понадобилось мне привязать к Аксапте сканер прокси-карт. Сканер российского производства. Естественно, никаких драйверов, кроме виртуального последовательного порта. Что делать? Писать ActiveX не хотелось. Тем более, что есть готовые ocx для OPOS от Curtiss Monroe, отлаженные и внушающие доверие, спасибо ему за них. Единственное, чего не было, так это сервисного объекта, но его написание не казалось большой проблемой. До тех пор, пока не начал его писать )) Информации в сети о том, как это делать - около нуля. Единственный сайт, где есть хоть что-то - Monroe Consulting Services (http://monroecs.com/opos.htm).
В общем, разработка темы заняла около трех дней, что на мой взгляд многовато. И я решил поделиться полученным результатом, вдруг у кого-нибудь тоже обострится некрофилия )) По крайней мере, три дня назад мне бы эта информация сохранила бы три дня спокойной жизни. Вот такой сумбурный каламбур. 
Прошу судить не строго -  в C# я еще тот нуб, если будет у кого желание внести исправления, нет проблем.

В общем, я пришел к выводу, что для того, чтобы написать хоть как-то работающий Service object  для OPOS, необходимо реализовать следующий интерфейс (пример для SmartCardRW) 
Код:
---------
[Guid("your GUID here"), InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface OPOSSmartCardRWServiceObject_Interface
{
    [DispId(0)]    
    long COFreezeEvents(
        [MarshalAs(UnmanagedType.Bool)]
        bool Freeze);

    [DispId(1)]
    [return: MarshalAs(UnmanagedType.I8)]
    long GetPropertyNumber(long PropIndex);
        
    [DispId(2)]
    void SetPropertyNumber(
        long PropIndex, 
        [MarshalAs(UnmanagedType.I8)] 
        long Number);
        
    [DispId(3)]
    [return: MarshalAs(UnmanagedType.BStr)]
    string GetPropertyString(long PropIndex);
        
    [DispId(4)]    
    void SetPropertyString(
        long PropIndex, 
        [MarshalAs(UnmanagedType.BStr)] 
        String String);
        
    [DispId(5)]
    long OpenService( 
        [MarshalAs(UnmanagedType.BStr)] String DeviceClass,
        [MarshalAs(UnmanagedType.BStr)] String DeviceName,
        [MarshalAs(UnmanagedType.IDispatch)] object pDispatch);


    [DispId(6)]
    long CheckHealth(long Level);

    [DispId(7)]
    long ClaimDevice(long Timeout);

    [DispId(8)]
    long ClearInput();
        
    [DispId(9)]
    long ClearOutput();

    [DispId(10)]
    long CloseService();
        
    [DispId(11)]
    long DirectIO(
        long Command, 
        ref long pData, 
        [MarshalAs(UnmanagedType.BStr)]
        out String pString);

    [DispId(12)]
    long ReleaseDevice();

    [DispId(13)]
    long ResetStatistics(
        [MarshalAs(UnmanagedType.BStr)]
        String StatisticsBuffer);        

    [DispId(14)]
    long RetrieveStatistics(
        [MarshalAs(UnmanagedType.BStr)]
        ref String StatisticsBuffer);

    [DispId(15)]
    long UpdateStatistics(
        [MarshalAs(UnmanagedType.BStr)]
        String StatisticsBuffer);
        
    [DispId(16)]
    long BeginInsertion(long Timeout);

    [DispId(17)]
    long BeginRemoval(long Timeout);

    [DispId(18)]
    long EndInsertion();

    [DispId(19)]
    long EndRemoval();

    [DispId(20)]
    long ReadData(
        long Action,
        ref long pCount,
        [MarshalAs(UnmanagedType.BStr)]
        ref String pData);      
        
    [DispId(21)]
    long WriteData(
        long Action,
        long Count,
        [MarshalAs(UnmanagedType.BStr)]
        String Data);   

    [DispId(22)]
    long CompareFirmwareVersion(
        [MarshalAs(UnmanagedType.BStr)]
        String FirmwareFileName,
        out long pResult); 
  
    [DispId(23)]
    long UpdateFirmware(
        [MarshalAs(UnmanagedType.BStr)]
        String FirmwareFileName); 
 
    [DispId(24)]
    long ClearInputProperties();   
}
---------
И это было самое сложное.Потому как у MCS исходники на C++, и они описывают объект управления. Пришлось изучать сначала их, а потом уже думать, как они будут работать с моим кодом. Вот к чему приводит отсутствие примеров кода в интернетах )) Самое веселое в работе по созданию этого интерфейса было найти значения DispId для всех этих методов и осознать, что есть еще и набор идентификаторов для получения доступа к свойствам сервисного объекта через методы GetProperty и SetProperty, и это разные наборы констант )) Но это все детали. После создания интерфейса остальное уже пошло как по маслу. Готовый код для сервисного объекта SmartCardRW прилагаю. Это, конечно, ужасный код, но вдруг он кому-нибудь сбережет три дня. В общем, надеюсь, не зря я здесь виртуальную бумагу мараю. Конечно, поначалу хотелось написать больше, но куча работы бьет по рукам, поэтому закругляюсь. Если вдруг будет у кого интерес к этому посту, по возможности постараюсь ответить на вопросы. Спасибо за внимание.

Пользуясь случаем, выражаю благодарность Curtiss Monroe, MSDN, RSDN и некоторым другим сайтам, на которые меня забросила судьба (точнее поисковик), и где я почерпнул бесценную информацию для реализации вышеописанного чуда!

UPD: интерфейс для Scanner (сканер штрихового кода) несколько отличается 
Код:
---------
public interface OPOSScannerServiceObject_Interface
{
    [DispId(0)]
    long COFreezeEvents(
        [MarshalAs(UnmanagedType.Bool)]
        bool Freeze);

    [DispId(1)]
    [return: MarshalAs(UnmanagedType.I8)]
    long GetPropertyNumber(long PropIndex);

    [DispId(2)]
    void SetPropertyNumber(
        long PropIndex,
        [MarshalAs(UnmanagedType.I8)] 
        long Number);

    [DispId(3)]
    [return: MarshalAs(UnmanagedType.BStr)]
    string GetPropertyString(long PropIndex);

    [DispId(4)]
    void SetPropertyString(
        long PropIndex,
        [MarshalAs(UnmanagedType.BStr)] 
        String String);

    [DispId(5)]
    long OpenService(
        [MarshalAs(UnmanagedType.BStr)] String DeviceClass,
        [MarshalAs(UnmanagedType.BStr)] String DeviceName,
        [MarshalAs(UnmanagedType.IDispatch)] object pDispatch);


    [DispId(6)]
    long CheckHealth(long Level);

    [DispId(7)]
    long ClaimDevice(long Timeout);

    [DispId(8)]
    long ClearInput();

    [DispId(9)]
    long CloseService();

    [DispId(10)]
    long DirectIO(
        long Command,
        ref long pData,
        [MarshalAs(UnmanagedType.BStr)]
        out String pString);

    [DispId(11)]
    long ReleaseDevice();

    [DispId(12)]
    long ResetStatistics(
        [MarshalAs(UnmanagedType.BStr)]
        String StatisticsBuffer);

    [DispId(13)]
    long RetrieveStatistics(
        [MarshalAs(UnmanagedType.BStr)]
        ref String StatisticsBuffer);

    [DispId(14)]
    long UpdateStatistics(
        [MarshalAs(UnmanagedType.BStr)]
        String StatisticsBuffer);

    [DispId(15)]
    long CompareFirmwareVersion(
        [MarshalAs(UnmanagedType.BStr)]
        String FirmwareFileName,
        out long pResult);

    [DispId(16)]
    long UpdateFirmware(
        [MarshalAs(UnmanagedType.BStr)]
        String FirmwareFileName);

    [DispId(17)]
    long ClearInputProperties();
}
---------
UPD2: ну и добавил вроде ничего так работающий код для сканера штриховых кодов]]></description>
			<content:encoded><![CDATA[<div>Не думал я, что когда-нибудь буду что-либо писать в блог на АксФоруме... Вообще, больше читать люблю )) Но тут на днях столкнулся с темой, по которой не нашел чего почитать, вообще практически ничего по ней нет. Похоже тема столь древняя, что когда она гремела, интернетов еще толком не было. <br />
Тема эта - написание сервисного объекта для OPOS (была такая технология). Почему она меня заинтересовала спустя десять лет, как она была актуальна? А понадобилось мне привязать к Аксапте сканер прокси-карт. Сканер российского производства. Естественно, никаких драйверов, кроме виртуального последовательного порта. Что делать? Писать ActiveX не хотелось. Тем более, что есть готовые ocx для OPOS от Curtiss Monroe, отлаженные и внушающие доверие, спасибо ему за них. Единственное, чего не было, так это сервисного объекта, но его написание не казалось большой проблемой. До тех пор, пока не начал его писать )) Информации в сети о том, как это делать - около нуля. Единственный сайт, где есть хоть что-то - <a href="http://monroecs.com/opos.htm" target="_blank">Monroe Consulting Services</a>.<br />
В общем, разработка темы заняла около трех дней, что на мой взгляд многовато. И я решил поделиться полученным результатом, вдруг у кого-нибудь тоже обострится некрофилия )) По крайней мере, три дня назад мне бы эта информация сохранила бы три дня спокойной жизни. Вот такой сумбурный каламбур. <br />
Прошу судить не строго -  в C# я еще тот нуб, если будет у кого желание внести исправления, нет проблем.<br />
<br />
В общем, я пришел к выводу, что для того, чтобы написать хоть как-то работающий Service object  для OPOS, необходимо реализовать следующий интерфейс (пример для SmartCardRW) <div class="xpp"><div class="smallfont xpp_title">Код:</div><pre class="alt2 xpp_code">[Guid(&quot;your GUID here&quot;), InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface OPOSSmartCardRWServiceObject_Interface
{
    [DispId(0)]    
    long COFreezeEvents(
        [MarshalAs(UnmanagedType.Bool)]
        bool Freeze);

    [DispId(1)]
    [return: MarshalAs(UnmanagedType.I8)]
    long GetPropertyNumber(long PropIndex);
        
    [DispId(2)]
    void SetPropertyNumber(
        long PropIndex, 
        [MarshalAs(UnmanagedType.I8)] 
        long Number);
        
    [DispId(3)]
    [return: MarshalAs(UnmanagedType.BStr)]
    string GetPropertyString(long PropIndex);
        
    [DispId(4)]    
    void SetPropertyString(
        long PropIndex, 
        [MarshalAs(UnmanagedType.BStr)] 
        String String);
        
    [DispId(5)]
    long OpenService( 
        [MarshalAs(UnmanagedType.BStr)] String DeviceClass,
        [MarshalAs(UnmanagedType.BStr)] String DeviceName,
        [MarshalAs(UnmanagedType.IDispatch)] object pDispatch);


    [DispId(6)]
    long CheckHealth(long Level);

    [DispId(7)]
    long ClaimDevice(long Timeout);

    [DispId(8)]
    long ClearInput();
        
    [DispId(9)]
    long ClearOutput();

    [DispId(10)]
    long CloseService();
        
    [DispId(11)]
    long DirectIO(
        long Command, 
        ref long pData, 
        [MarshalAs(UnmanagedType.BStr)]
        out String pString);

    [DispId(12)]
    long ReleaseDevice();

    [DispId(13)]
    long ResetStatistics(
        [MarshalAs(UnmanagedType.BStr)]
        String StatisticsBuffer);        

    [DispId(14)]
    long RetrieveStatistics(
        [MarshalAs(UnmanagedType.BStr)]
        ref String StatisticsBuffer);

    [DispId(15)]
    long UpdateStatistics(
        [MarshalAs(UnmanagedType.BStr)]
        String StatisticsBuffer);
        
    [DispId(16)]
    long BeginInsertion(long Timeout);

    [DispId(17)]
    long BeginRemoval(long Timeout);

    [DispId(18)]
    long EndInsertion();

    [DispId(19)]
    long EndRemoval();

    [DispId(20)]
    long ReadData(
        long Action,
        ref long pCount,
        [MarshalAs(UnmanagedType.BStr)]
        ref String pData);      
        
    [DispId(21)]
    long WriteData(
        long Action,
        long Count,
        [MarshalAs(UnmanagedType.BStr)]
        String Data);   

    [DispId(22)]
    long CompareFirmwareVersion(
        [MarshalAs(UnmanagedType.BStr)]
        String FirmwareFileName,
        out long pResult); 
  
    [DispId(23)]
    long UpdateFirmware(
        [MarshalAs(UnmanagedType.BStr)]
        String FirmwareFileName); 
 
    [DispId(24)]
    long ClearInputProperties();   
}</pre></div>И это было самое сложное.Потому как у MCS исходники на C++, и они описывают объект управления. Пришлось изучать сначала их, а потом уже думать, как они будут работать с моим кодом. Вот к чему приводит отсутствие примеров кода в интернетах )) Самое веселое в работе по созданию этого интерфейса было найти значения DispId для всех этих методов и осознать, что есть еще и набор идентификаторов для получения доступа к свойствам сервисного объекта через методы GetProperty и SetProperty, и это разные наборы констант )) Но это все детали. После создания интерфейса остальное уже пошло как по маслу. Готовый код для сервисного объекта SmartCardRW прилагаю. Это, конечно, ужасный код, но вдруг он кому-нибудь сбережет три дня. В общем, надеюсь, не зря я здесь виртуальную бумагу мараю. Конечно, поначалу хотелось написать больше, но куча работы бьет по рукам, поэтому закругляюсь. Если вдруг будет у кого интерес к этому посту, по возможности постараюсь ответить на вопросы. Спасибо за внимание.<br />
<br />
Пользуясь случаем, выражаю благодарность Curtiss Monroe, MSDN, RSDN и некоторым другим сайтам, на которые меня забросила судьба (точнее поисковик), и где я почерпнул бесценную информацию для реализации вышеописанного чуда!<br />
<br />
UPD: интерфейс для Scanner (сканер штрихового кода) несколько отличается <div class="xpp"><div class="smallfont xpp_title">Код:</div><pre class="alt2 xpp_code">public interface OPOSScannerServiceObject_Interface
{
    [DispId(0)]
    long COFreezeEvents(
        [MarshalAs(UnmanagedType.Bool)]
        bool Freeze);

    [DispId(1)]
    [return: MarshalAs(UnmanagedType.I8)]
    long GetPropertyNumber(long PropIndex);

    [DispId(2)]
    void SetPropertyNumber(
        long PropIndex,
        [MarshalAs(UnmanagedType.I8)] 
        long Number);

    [DispId(3)]
    [return: MarshalAs(UnmanagedType.BStr)]
    string GetPropertyString(long PropIndex);

    [DispId(4)]
    void SetPropertyString(
        long PropIndex,
        [MarshalAs(UnmanagedType.BStr)] 
        String String);

    [DispId(5)]
    long OpenService(
        [MarshalAs(UnmanagedType.BStr)] String DeviceClass,
        [MarshalAs(UnmanagedType.BStr)] String DeviceName,
        [MarshalAs(UnmanagedType.IDispatch)] object pDispatch);


    [DispId(6)]
    long CheckHealth(long Level);

    [DispId(7)]
    long ClaimDevice(long Timeout);

    [DispId(8)]
    long ClearInput();

    [DispId(9)]
    long CloseService();

    [DispId(10)]
    long DirectIO(
        long Command,
        ref long pData,
        [MarshalAs(UnmanagedType.BStr)]
        out String pString);

    [DispId(11)]
    long ReleaseDevice();

    [DispId(12)]
    long ResetStatistics(
        [MarshalAs(UnmanagedType.BStr)]
        String StatisticsBuffer);

    [DispId(13)]
    long RetrieveStatistics(
        [MarshalAs(UnmanagedType.BStr)]
        ref String StatisticsBuffer);

    [DispId(14)]
    long UpdateStatistics(
        [MarshalAs(UnmanagedType.BStr)]
        String StatisticsBuffer);

    [DispId(15)]
    long CompareFirmwareVersion(
        [MarshalAs(UnmanagedType.BStr)]
        String FirmwareFileName,
        out long pResult);

    [DispId(16)]
    long UpdateFirmware(
        [MarshalAs(UnmanagedType.BStr)]
        String FirmwareFileName);

    [DispId(17)]
    long ClearInputProperties();
}</pre></div>UPD2: ну и добавил вроде ничего так работающий код для сканера штриховых кодов</div>


<!-- attachments -->
	<div style="margin-top:10px">

		
		
		
		
			<fieldset class="fieldset">
				<legend>Вложения</legend>
				<table cellpadding="0" cellspacing="3" border="0">
				<tr>
	<td><img class="inlineimg" src="http://axforum.info//img.axforum.info/attach/zip.gif" alt="Тип файла: zip" width="16" height="16" border="0" style="vertical-align:baseline" /></td>
	<td><a href="//axforum.info/forums/blog_attachment.php?attachmentid=127&amp;d=1304780027">Service.zip</a> (8.5 Кб, 140 просмотров)</td>
</tr><tr>
	<td><img class="inlineimg" src="http://axforum.info//img.axforum.info/attach/zip.gif" alt="Тип файла: zip" width="16" height="16" border="0" style="vertical-align:baseline" /></td>
	<td><a href="//axforum.info/forums/blog_attachment.php?attachmentid=131&amp;d=1309765383">OPOSScannerSO.zip</a> (11.9 Кб, 106 просмотров)</td>
</tr>
				</table>
			</fieldset>
		

	</div>
<!-- / attachments -->
]]></content:encoded>
			<dc:creator>b_nosoff</dc:creator>
			<guid isPermaLink="true">//axforum.info/forums/blog.php?b=248</guid>
		</item>
	</channel>
</rss>
