Tuesday, October 18, 2016

.NET Error: Side-By-Side Configuration is Incorrect

By Steve Endow

A client recently installed a new .NET eConnect integration for Dynamics GP.  After configuring the integration, they received this error when they ran the EXE file:


They also saw this message in Event Viewer, which helped narrow down the cause.


I quickly reviewed the exe.config file, but couldn't find any obvious errors.  I tried opening the XML file in Internet Explorer as a quick test, and did see that it didn't load properly, so there did appear to be an issue with the file format.

I then opened the config file in UltraEdit and used it's XML validation, but while it did say there was an error, it gave me a misleading description of the error, pointing to a node that was valid.

So I finally resorted to opening both the customer's config file and my dev config file and flipped between the two to compare line by line.  I finally found the problem.


One of the closing value tags had been accidentally deleted when the file was edited.
Once I added back the close value (< / value >) tag, the import worked properly.



You can also find him on Google+ and Twitter






Friday, October 14, 2016

Conversations from Summit- Security and Asking Why?

Sitting on a plane flying home from Tampa is a great time to reflect. I have always enjoyed Summit for a variety of reasons beyond the sessions like...
  1. Reconnecting with long-time consulting friends, vendors I have known longer than I have been married, former students, and clients
  2. Inspired  conversations about what we do, how we do it better, and why we are so collectively passionate about how software can help businesses grow and individuals prosper
  3. I always leave having learned something, some years it is functional/technical know-how and other years it might be a perspective change or a piece of software that solves a common issue
One of these inspired conversations happened this week when I was sitting with a group of MVPs and others in the Mekorma HUB discussing who is trusted in an organization.  So I wanted to share a few of those points, and expand the question a bit.


It is not uncommon for us (as consultants) to get requests to restrict security for users.  Totally common.  What gives us pause from time to time is the role of some of the individuals that are being restricted like...


  • Payroll processors
  • Business analysts
  • HR managers
  • Financial managers
It is not so unusual to have security in place to protect processes and demonstrate the process control that auditors like to see in organizations.  But sometimes it is the specifics of what is restricted that makes me think.


For example...
  • With payroll processors- restrict their ability to see any dollar values
  • For business analysts- restrict their ability to see certain financial numbers, or detail information behind them
  • For HR managers- restrict their ability to see payroll information
  • For Financial managers- restrict their ability to use reporting tools, like Smartlist
I don't mean to suggest that there are not valid reasons to do all of the above.  But I do think that if you find yourself doing (or requesting these things), you should pause for a moment to ask "why" and do a little due diligence on the goal.  Often times, when we have these "pause" conversations, we find that the reason falls in to one of two primary categories: trust or training.  Here are some of the specific reasons we hear, categorized accordingly..


  • Trust
    • Concerns that employee will not be discrete/act professionally with information
    • Executive level edicts that certain data be restricted to limited individuals
    • Internal behavior that suggests employee would be upset with what they learn
    • Employee is new to organization
  • Training
    • Concerns that the reporting that will be created will be incomplete/invalid
    • Experiences where individuals "messed up" the system inadvertently
    • Wanting to avoid unnecessary questions or "busy-body" behavior
In the cases above, I encourage organizations to address  the root cause.  Limiting access doesn't address these gaps or behaviors, it just eliminates the opportunity.  If we are in the business of growing employees (which I think all organizations are), we need to have these coaching conversations, provide the training and guidance they need, to be better professionals (which in turn benefits the business in not only outcomes, but also in loyalty).


More conversations from the Summit coming, but let me know your thoughts on this one.  Do you agree?  Disagree?


Christina Phillips is a Microsoft Certified Trainer and Dynamics GP Certified Professional. She is a director with BKD Technologies, providing training, support, and project management services to new and existing Microsoft Dynamics customers. This blog represents her views only, not those of her employer.


Thursday, October 6, 2016

How do you choose your passwords and keep them secure?

By Steve Endow

I've had a mini discussion on Twitter recently about passwords.  There was some joking about the stereotype of the password written on a Post-It Note stuck on a monitor, and about how common passwords tend to be re-used.

I noted that I preferred P-Touch labels for my monitor passwords, as they worked better than Post-It Notes.


I occasionally have calls with Dynamics partners who store all client information in a central system, such as MS CRM Online.  In addition to the standard customer information, they store VPN connection information, Windows logins, and SQL Server sa passwords in plain text in the CRM customer records.  Logistically this makes sense, as it allows all of the consultants to quickly access login info and assist customers.  But it poses a potential security risk, as a single compromised CRM login could expose all customer connection information, and full access to customer Dynamics GP SQL Servers and databases.

Monday, October 3, 2016

Why Care? A Case for Really Understanding Your Account Framework

It seems like most of us have had a time in our careers as consultants where we did it all.  We installed the software, configured and trained, migrated data, and even did an upgrade or two.  Over the years, my job has evolved where now I spend a lot more time working with a team.  I don't remember the last upgrade I did (maybe three or four years ago?), other than on my own machine.  And I don't recall the last new install I did. 




So it occurs to me that as we bring people in to consulting, the "do everything" approach is not really used much anymore from what I can tell.  Due to the increasing technical complexities of installing and supporting systems, and larger partner organizations, we tend to see people fall in to one or two of three primary categories- functional, technical, developer.  And for this reason, there is sometime a disconnect between things that each group should know and understand. 




Many years ago, I made the case for waiting to install the software until after we had completed our discovery.  It was common practice to schedule installation as soon as we had registration keys, which sometimes meant even before we had formally kicked off the project.  Why is this an issue?  Account Framework.  This thing that isn't an issue very often, but when it is-- it is a significant issue that can lead a customer to say "Why didn't you anticipate this?".  Which, by the way, is something project managers don't want to be asked.




I want to make a case that everyone on your team, and clients/users as well, needs to understand the significance of the Account Framework.  In many ways, it is the most critical decision (or lack of making a decision) encountered during the installation process.  Handled poorly, it can cost you money, time, and project goodwill.  At a high level, the Account Framework is comprised of three components- maximum number of segments, maximum number of characters for the entire account string, and individual maximum characters for each individual segment.




The Account Framework is defined during the creation of the Dynamics GP system database.  It is defined at this stage because it impacts the fields and sorting available for the chart of accounts in ALL COMPANY DATABASES.  Did you catch that?  ALL COMPANY DATABASES.  Now, let's contrast with the Account Format.  The Account Format is defined during the actual configuration (logging in and setting up) in each company.  The key here is that the Account Format can be different in each company, but all companies' Account Formats must be able to individually fit within the overall Account Framework?




Huh?




Well, let's take the standard example of 66 characters and 10 segments.  This is the largest possible Account Framework in Dynamics GP.  This allows us to grow to use 10 segments of 6-7 characters each (as it allocates the 66 over 10 segments).  So the following Account Formats would be possible with a "66 and 10" Account Framework:




XX-XXXXX-X-XX
XXXX-XX
X-X-XX-XXXX-XX-XXX-X




Wouldn't be possible in this example?



XX-XXXXXXXX-X


Or


X-X-X-X-X-XX-XX-XX-XXXX-XX-X-X




It is important to keep in mind that the Account Framework is the largest the installation can GROW.  So maybe your initial account format for a company is XX-XXXX-X so you decide to specify the same as the Account Framework (a practice we come across frequently).  This works great initially, but if the client ever wants to expand their Account Format (a fairly common request when someone is on the software for a number of years, or even sometimes in the course of an implementation when the need to add an additional segment comes to light), they will have to chance the Account Framework (more on that later) which is not the flip of a switch.  Anecdotally, I have not seen evidence that a smaller account framework yields performance or other benefits.  But if you are reading this and you have seen such benefits, please share!




When a client wants to change the Account Format, it is a fairly straightforward process.  Then can update the Account Format Setup (Setup-Company-Account Format) and then as needed use the PSTL Account Modifier/Combiner tool to update segments as needed.  But if they encounter the boundaries of the Account Framework when doing this, it becomes a much larger issue.  Technically, you can script the changes to the Account Framework to alter the necessary tables and components.  But the recommended approach would be to use the Reformatter tool from Corporate Renaissance (which effectively creates a new Dynamics database and ports over the needed data)...




http://www.crgroup.com/Products/SolutionsforMicrosoftDynamicsGP/Pages/Re-Formatter.aspx




But of course that involved buying a product, testing, and then deploying the fix.  Microsoft used to also offer a service to do this through support (for an additional fee), but that involves additional down time as the data is sent to MS and returned.  In all cases, additional cost and time is involved.  And it takes a change that is intended to make the system flexible (e.g., being able to change the account format and use the PSTL account modified/combiner) and user-friendly, and adds cost and potential consulting hours.




In my not so humble opinion, before an install happens, everyone on the project team should understand what framework is being requested and why.  If you want to check your account framework, one of the easiest places to do so is Setup-Company-Account Format where you can see the maximum number of segments, characters, and the max length for each segment per the framework.




For reference, when installing Dynamics GP for the first time, GP utilities will allow you to select either a Basic or Advanced installation.  The Basic installation will install with a default Account Framework of maximum 5 segments, 45 characters, and 9 characters per segment.  This cannot be changed.  An advanced installation will allow you to specify the framework.









Christina Phillips is a Microsoft Certified Trainer and Dynamics GP Certified Professional. She is a director with BKD Technologies, providing training, support, and project management services to new and existing Microsoft Dynamics customers. This blog represents her views only, not those of her employer.

Sunday, October 2, 2016

Supporting .NET 2.0 references in a 4.0+ class library at runtime

By Steve Endow

If you don't know what a .NET mixed mode assembly is, you can skip this post and save a few minutes of your life.  If you do know what a .NET mixed mode assembly is and understand why it can be a pain, you may want to read on.

This post is primarily to document this solution for myself so that I can find it again in the future without having to dig through 10 old projects (like I had to do yesterday).

This solution is something my colleague Andrew Dean and I have shared during our Dynamics GP .NET Development presentations at the reIMAGINE and GPUG Summit, as it is something we have had to use in our development projects with Dynamics GP.

In the case of Dynamics GP, the primary reason I've had to use this is because I regularly use GPConnNet.dll.  That dll is still only .NET 2.0 'compatible' (or whatever the term is).  So if you develop a new solution using .NET 4.5.1, you will get the famous mixed mode assembly error.

Mixed mode assembly is built against version 'v2.0.50727' of the runtime and cannot be loaded in the 4.0 runtime without additional configuration information.

The standard solution to resolve this error is to modify your application config file.  Meaning your app.config / exe.config file.

That works fine if you are developing an EXE, but it won't work if you are developing a class library DLL that will be used by other applications that you can't control.  Like Dynamics GP.

This post by Reed Copsey Jr. provides an alternative, and brilliant, approach to setting the .NET legacy policy at runtime.  This is a life saver for DLL libraries that are referencing resources with multiple .NET versions.

http://reedcopsey.com/2011/09/15/setting-uselegacyv2runtimeactivationpolicy-at-runtime/

public static class RuntimePolicyHelper
{
    public static bool LegacyV2RuntimeEnabledSuccessfully { get; private set; }

    static RuntimePolicyHelper()
    {
        ICLRRuntimeInfo clrRuntimeInfo =
            (ICLRRuntimeInfo)RuntimeEnvironment.GetRuntimeInterfaceAsObject(
                Guid.Empty, 
                typeof(ICLRRuntimeInfo).GUID);
        try
        {
            clrRuntimeInfo.BindAsLegacyV2Runtime();
            LegacyV2RuntimeEnabledSuccessfully = true;
        }
        catch (COMException)
        {
            // This occurs with an HRESULT meaning 
            // "A different runtime was already bound to the legacy CLR version 2 activation policy."
            LegacyV2RuntimeEnabledSuccessfully = false;
        }
    }

    [ComImport]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    [Guid("BD39D1D2-BA2F-486A-89B0-B4B0CB466891")]
    private interface ICLRRuntimeInfo
    {
        void xGetVersionString();
        void xGetRuntimeDirectory();
        void xIsLoaded();
        void xIsLoadable();
        void xLoadErrorString();
        void xLoadLibrary();
        void xGetProcAddress();
        void xGetInterface();
        void xSetDefaultStartupFlags();
        void xGetDefaultStartupFlags();

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        void BindAsLegacyV2Runtime();
    }
}


Go forth and develop mixed mode assembly class libraries.


You can also find him on Google+ and Twitter





Saturday, October 1, 2016

Cool Visual Studio Immediate Window trick

By Steve Endow

I'm a big fan of the Immediate Window in Visual Studio.  When you are debugging code and trying to figure out a problem, the immediate window is a simple and quick way to check variable values, test operations at a breakpoint, and take a look at what is going on.

But there is one small issue.  If you are outputting lots of text, such as an eConnect XML document or eConnect exception message, the Immediate Window will output the entire XML document as a single line of text.  A really, really long line.  Worse, newlines will be displayed in the text as \n\r.  

This makes outputting XML to the Immediate Window a bit of a hassle--I have been copying the text, pasting it into UltraEdit, replacing the newline characters with actual CRLF line breaks, and then formatting the XML.  It's a hassle.

So, once again, my laziness to repeat that process finally overcame my laziness to actually do some research and see if there was a better solution.  Of course, there is a better way.  I just didn't know it for the last TEN YEARS.  I'm apparently a slow learner.

Big surprise, the answer was on Stack Overflow.

https://stackoverflow.com/questions/2868862/newlines-in-the-immediate-window

The trick is to type ",nq" after your Immediate Window command to request "no quotes".  Apparently this is a "format specifier".

https://msdn.microsoft.com/en-us/library/e514eeby.aspx

Holy cow, what a huge improvement.  It might seem trivial, but it makes a huge difference.  Here's an example of before and after.


Notice the standard "? response" command outputs that variable text (an eConnect exception) as a single line that's a pain to read.  Once I typed "? response,nq", like magic, it output the text in a very nicely formatted manner.  Brilliant.  Soooo much more readable and it saves me a half dozen useless steps in a text editor.

There are at least 1 billion shortcuts and hidden gems in Visual Studio that I still don't know, but I'm finding them one at a time...  Pacing myself.


You can also find him on Google+ and Twitter






Thursday, September 29, 2016

Fix Dynamics GP scaling and font size issues on high DPI displays

My blog has moved!  Please visit the new blog at:  https://blog.steveendow.com/

I will no longer be posting to Dynamics GP Land, and all new posts will be at https://blog.steveendow.com

Thanks!




By Steve Endow


Update: If you are also having issues using Remote Desktop with high DPI displays, check out this post by Nathan Hayden at BKD on a workaround for RDP apps:

http://dynamicsinsights.com/2018/10/05/remote-desktop-high-dpi-dynamics-gp/



If you have a relatively new Windows laptop with a high resolution display or if you have 4K monitors on a Windows desktop, you are likely familiar with the numerous software display issues related to these "high DPI" displays.

If you use a 4K monitor at full resolution, the fonts and text in Windows is microscopic.  To make text readable and buttons large enough to click, Windows uses "scaling", whereby it increases the size of text and graphics to make them readable and large enough to actually use.  (I'm sure there's a huge technical discussion about the details, but I don't care about any of that, I just want to get work done.)

So when you run Windows 10 with a high DPI display, it will typically recommend running at 200% scaling.  I prefer to use 175% to get more real estate on my displays.


This Scaling technique generally works well, and with many applications, you may not even realize that scaling is occurring...

Until you launch an application that isn't "high DPI aware" or high DPI compatible.  Then you'll see a complete mess. I use SugarSync, which does not handle scaling very well.  Notice the text on the left is very small compared to the folder names on the right.


It's annoying, but tolerable.

I thought that Dynamics GP 2015 displayed fine on my Surface Pro 4 when I first installed it, but I rarely use GP on my SP4, and when I launched it earlier this week, I saw this odd mix of font sizes.  A colleague told me the same thing--GP used to display properly on his Surface Pro 4, but recently the fonts went haywire.


Notice the menus at the top are very large, while the text on the left panes is tiny.

Similarly, SQL Server Management Studio 2014 is a hot mess on high DPI displays.  It was the SSMS 2014 issue that had me searching for a solution.  And I came across this brilliant post.

http://www.sqlservercentral.com/blogs/spaghettidba/2015/10/14/ssms-in-high-dpi-displays-how-to-stop-the-madness/

Clearly the author has a pretty good understanding of the high DPI settings in Windows and figured out how to change the scaling method on a per-application basis using a manifest file.

I don't understand any of the mechanics, but I followed his instructions to import the extra registry key, then saved the Ssms.exe.manifest file to my machine.  Like magic, SSMS 2014 displayed properly.  The bitmap scaling on my displays at 175% is a bit fuzzy, but I'm okay with that, since it makes the applications much more usable.  I can always try 150% or 200% scaling if necessary if the blurriness bothers me.

Since it worked for SQL Server Management Studio, I then wondered--could it work for Dynamics GP?

(Full credit goes to Gianluca Sartori for his article showing how to implement this fix--I didn't come up with any of this)

I created a Dynamics.exe.manifest file...and behold.  GP launched just fine and rendered "normally", without the funky font sizes.


On a roll, I made a manifest file for SugarSync, and was pleased to see that it fixed SugarSync's scaling as well!  SugarSync already had a manifest file, so I just edited it to add the additional settings from the SSMS 2014 sample.

I don't understand any of the settings in the manifest file, but it seems to be fairly generic and flexible, as I've just used the technique for 3 different applications.

If you want to give this a try, you do so at your own risk.  If you don't know how to edit the registry or fix things if your computer goes haywire doing this, you should "consult an expert" to assist you.

Save this text to a file called "Scaling.reg".

Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\SideBySide]
"PreferExternalManifest"=dword:00000001

Once you have created the "reg" file, double click on it to import it into the Windows registry on the machine where Dynamics GP is installed.


Then save this text to a file called Dynamics.exe.manifest.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<dependency>
  <dependentAssembly>
    <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*">
    </assemblyIdentity>
  </dependentAssembly>
</dependency>
<dependency>
  <dependentAssembly>
    <assemblyIdentity type="win32" name="Microsoft.VC90.CRT" version="9.0.21022.8" processorArchitecture="amd64" publicKeyToken="1fc8b3b9a1e18e3b">
    </assemblyIdentity>
  </dependentAssembly>
</dependency>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
  <security>
    <requestedPrivileges>
      <requestedExecutionLevel level="asInvoker" uiAccess="false"/>
    </requestedPrivileges>
  </security>
</trustInfo>
<asmv3:application>
  <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
    <ms_windowsSettings:dpiAware xmlns:ms_windowsSettings="http://schemas.microsoft.com/SMI/2005/WindowsSettings">false</ms_windowsSettings:dpiAware>
  </asmv3:windowsSettings>
</asmv3:application>
</assembly>


Then copy your new Dynamics.exe.manifest file to the GP application directory where the Dynamics.exe file is located.

Give it a try and let me know if it works for you.  I'm curious if it fixes some, most, or all of the situations where GP is apparently displayed using small fonts.


UPDATE: It appears that GP 2013 may handle scaling differently than GP 2015.  With GP 2013, I'm seeing a completely different mess of font sizes, and the GP window fonts are extremely small.  I used the Dynamics.exe.manifest file and it now displays properly.

Before:


After adding the manifest file:


Huge difference.


Steve Endow is a Microsoft MVP for Dynamics GP and a Dynamics GP Certified IT Professional in Los Angeles.  He is the owner of Precipio Services, which provides Dynamics GP integrations, customizations, and automation solutions.

You can also find him on Google+ and Twitter