Controlling the Namer in WpfApprovals in ApprovalTests - approval-tests

I ran into a problem with using WpfApprovals on different versions of the OS. My personal laptop is running Windows 7 Enterprise and the build server is running Windows 7 professional. Since the WpfApprovals is using the OS name in the approval file name, the tests are failing on the build server.
I tried a number of options to try to avoid including the OS in the approval name, however, it looks like this behavior is hard coded in WpfApprovals.cs...
public static void Verify(Control control)
{
ApprovalResults.UniqueForOs();
ApprovalTests.Approvals.Verify(new ImageWriter(f => WpfUtils.ScreenCapture(control, f)));
}
... short of creating a modified version of the library that comments out the ApprovalResults.UniqueForOs() call, is there a way to disable including OS info in the approval file name?
While I can appreciate that these tests will fail with different major os versions, they shouldn't fail accross different editions. I noticed that the standard string verifier doesn't force the UniqueForOs style naming.

Good point.
This Wpf is a bit tricky because the consistency is always an issue, but forcing it might not be the best idea, especially with no way to override the default behavior. While we figure out the correct solution for the next version, here are a couple of workarounds for 3.0.5
1) Copy file
You can just copy the approved file over to match both OS versions. This sucks a bit but involves no coding.
2) Customized Wpf call
While you stated not doing this it is a pretty easy fix
public static void Verify(Control control)
{
ApprovalTests.Approvals.Verify(new ImageWriter(f => WpfUtils.ScreenCapture(control, f)));
}
Unfortunately this is it. There is not way to intercept the namer.
Thanks for bring this to our attention!

Related

Why could an ASP.NET-Core app get the error message "Locking/unlocking file regions is not supported on this platform." when deployed on MacOS?

Our embedded database library uses the FileStream.Lock(long, long) method to implement locking. We have a customer using the .NET Standard 2.0 version of our library in their small ASP.NET-Core Razor Page application who reports that their application is getting a PlatformNotSupportedException "Locking/unlocking file regions is not supported on this platform. Use FileShare on the entire file instead." when deployed on MacOS (but not when deployed on Windows). I checked with the customer, and it’s on a 2013 Macbook Pro with a fresh up to date Catalina install on APFS.
Surely, locking file regions isn't truly unsupported on MacOS--or else we should be getting a lot more complaints! So, we're wondering if there's something that could be missing or wrong in a project or the installation that explains the error and would hopefully be correctable. Or could we somehow be running into a limitation in MacOS that is tighter than other platforms? We do use some large special values well past the end of most files (which is legal and works fine in most cases), but we already limited these not to exceed the positive range of a signed Int32 because some platforms apparently map the long arguments into int values.
Has anyone encountered this error before and solved what was wrong? Or is there really no way to support file region locking for .NET programs on a Mac?
If you check the source code you'll see that this is explicitly unsupported. The version-specific FileStream.OSX.cs file explicitly throws :
public partial class FileStream : Stream
{
private void LockInternal(long position, long length)
{
throw new PlatformNotSupportedException(SR.PlatformNotSupported_OSXFileLocking);
}
private void UnlockInternal(long position, long length)
{
throw new PlatformNotSupportedException(SR.PlatformNotSupported_OSXFileLocking);
}
}
The nice thing about GitHub is you can use blame to find out when that file changed and how.
The commit comment three years ago (February 2017) explains why this was turned off:
OSX doesn't support usage of both fcntl and flock. Since we're already using one in FileShare for the entire file, we cannot enable partial file locking like we do on other Unix platforms. The alternative is to throw a PNSE and suggest using FileShare on the whole file instead.

Extendscript Toolkit debugger fails: Can't start debug session

Not a programming problem per se, but rather a programming environment problem that I have been unable to find a solution to.
The problem relates to Adobe's Extendscript Toolkit (both 3.5 and 4), but so far I haven't been able to solve the problem, so here I am...
The error I get has appeared more or less over night. I didn't experience this problem yesterday, nor this morning. But exactly WHAT has happened is beyond me. I have removed preferences, I have uninstalled, reinstalled, created a new user, restored old preferences from Time Machine and I'm now pretty much lost for options.
Basically, nothing works in ESTK anymore. Just opening ESTK and entering alert('Hello') won't work. Neither will $.writeln(). Everything running from within ESTK seems to give the same error;
Cannot execute script in target engine 'main'
With details:
Cannot execute script in target engine 'main'!
(#1116) Can't start debug session.
Below is a screenshot taken from the new user I created to test, same problem.
The "funny" thing is that all the scripts (InDesign CS5, still hanging on to it for reasons) still work perfectly in the applications' script panels. So there is nothing wrong with the scripts (heck, they haven't changed one bit, and still refuses to run in ESTK).
As mentioned, I've tried installing the ESTK CC (version 4) as well, but the very same problem occurs there. Which leads me to think the problem lies somewhere else, but I do not know where, and why.
So, if anyone can shed any light on this issue, at all, I would be very happy. Debugging is basically the only thing ESTK is good for in my book, but now that even that functionality is gone, I don't know how to efficiently debug the scripts which is kind of hampering the workflow.
For reference, I'm running InDesign CS5 (from the old Creative Suite) on a 2008 Mac Pro with 10.11.6 (El Capitan) installed. Well aware that it's pretty out of date, but that is beside the point here.
In the above mentioned forum, Adobe has published a stable workaround!You just have to correct a setting inside the estk application:
Open the file(Mac): “/Applications/Adobe ExtendScript Toolkit CC/ExtendScript Toolkit.app/Contents/SharedSupport/Required/cdic/11BTBackend.jsx”
Search for the value: 604800000 (line reads bt.timeout = 604800000)
Replace that value with 604800 and save
Quit ExtendScript Toolkit and relaunch.
I can confirm that it works.
From the adobe Forum :
"we have found a first workaround: just change your date to any date before 20-nov-2018"
https://forums.adobe.com/message/10761440#10761440
Seems like a date issue :(
I just published a quick update about this on the Adobe Tech Blog.
For the time being, if you dismiss the dialog, you can still run your script via ESTK and step through code as usual.
Alternatively, if you really want to avoid the dialogs, and you don’t mind setting your clock back, you can sidestep the issue by setting your system clock back to November 19, 2018 or before. On most systems, changing the system time can have unintended side effects, so this isn’t recommended unless you’re really certain about it.

Troubleshooting VB6 App Crash after XP to Win7 Upgrade

I have a VB6 application that I provide support for. This application works on both Windows XP and Windows 7. Some users were migrated from Windows XP to Windows 7 using the User State Migration tool. These users now receive a generic "Application has crashed" Windows error message when they open certain screens (forms) in the application. My assumption is that there is a missing dll/ocx reference, but I'm having trouble tracking it down.
I've tried many/varied troubleshooting techniques:
Full uninstall and reinstall of my application
Manually re-registering all dll's and ocx's that I know are used
Running Process Monitor on a broken computer and a working computer to compare what dll's and ocx's are accessed. The answer might be here but even after filtering out most of the background noise the amount of data is overwhelming. At a minimum I reviewed all of the calls right before it crashes and all of the calls that were not successful. All of the non-successful calls match between working and non-working.
Installed the Windows Debugger Tools and captured a crash dump. Analyzed the crash dump with DebugDiag. DebugDiag says the exception is in msvbvm60.dll. I tried building a PDB file for my exe and loading it in DebugDiag to get more detail about where the exception is occuring but DebugDiag doesn't want to accept the PDB (might be doing something wrong here, but it just seems to ignore it. This same PDB file works fine when I do remote debugging, however.)
I recompiled my VB6 program without any optimizations in PCode. I've read online that sometimes building in PCode, while bad for performance, will tell you the real exception.
Used the above created PDB file to remote debug the VB6 application. The debugger says that the application crashes after the new window has been created, on a line that sets MousePointer = vbHourGlass... To me it seems unlikely that this is the real cause of the error. There are at least 20 other locations in the program where this same line is called and all work fine.
(Forgot about this one)
Used Dependency Walker and profiled the application on both a working and non-working computer. All errors found by dependency walker were the same between the two computers. There were no additional dependencies found on a working computer, and all missing dependencies on the non-working computer were also missing on the working one.
None of these actions changed my error message or showed me what the error is (unless it really is the mouse cursor issue)... There are no entries in the Windows Event Log related to the app crash.
The non-working and working computers all have the same base Windows 7 image, the only difference is whatever is being changed by USMT, which further convinces me that this is some kind of quirky configuration change or a missing dll/ocx or perhaps an unregistered dll/ocx.
Any ideas or thoughts on how I can track down the root cause of the issue would be greatly appreciated.
Update 1 - Response to questions
#MarkHall I have tried running it as admin, though not with UAC off. The application runs fine on a Windows 7 box as a non-admin with full UAC. Windows XP was 32-bit, Windows 7 is 64-bit, but again it works just fine on a like for like box where the user was not migrated from Windows XP.
#Beaner It's possible that it stores settings somewhere that have been corrupted, but the remote debugging leads me to think that it's more likely something else since it seems to die on a step related to the UI, which then makes me think it's probably a missing dll/ocx reference.
#Bob77 The application is installed into Program Files (x86). While many of the libraries do reside in the same folder, they are all registered.
Peter, often I've noticed that the debugger will indicate a line of code that is actually incorrect, depending on WHERE in the actual assembly language the fault occurs. You should look REAL close around your statement that sets the cursor to vbHourGlass. Your exception is PROBABLY happening BEFORE that line of code, but that line is what the debugger thinks is the actual faulted line of code.
Since you said it happens when a window OPENS, I'd look real close at any ocx's you may have referenced on the form, but perhaps NOT actually being used, or called. You might have one there that you don't intend to be there, that could be causing security issues, or something on Win7? Edit the .frm file by hand if you have to, and look at all the GUIDs the form references.
It is possible that one machine is using PER-USER registration, and the other is using PER-SYSTEM registration?? I don't know...
I would take a much closer look at the form that you are trying to open, and be VERY cautious of everything you are doing in the form load events, and so on. This sounds like it could be something as stupid as Windows Aero being enabled on one system, and not another, or some other sort of "Theme" setting that is throwing the VB Form Rendering routine into a hissyfit... Perhaps even something as stupid as a transparent color index in the icon you selected for that from?
If you are still developing this app, (or at least maintaining it), create an entirely NEW form, and re-create all the controls, etc, on the form (resist the temptation to copy/paste them from the old one...), and then see if THAT does the trick. Then, copy all the event code to the new form one event at a time, with at LEAST enough event code to make the form function, even if it's just a "dead form", that loads no data, or whatever the form is supposed to do. Check and debug after each change, and you WILL find it eventually. Of course, make sure you isolate one of the defunct systems to have a platform that you can duplicate the issue on, or then it's just guessing. I find that using something like Acronis w/ Universal Restore is a great option to then take the image file into a good HV, like VirtualBox, and then restore that image as a VM, so you can debug without interfering with your actual users. This sounds like a lot of work, but then again, so is re-writing an application that already exists, right? :)
Failing THAT... /* and */ are your friends!! (Well, we're dealing with VB, so ' would be your best friend! heh... But I'd start commenting out all the code on the form until that sucker opens. Then once it opens, start putting one line back at a time, and re-running it... That's called "VooDoo Debugging", but sometimes, you gotta do what you gotta do...
THANKS A LOT PETER! :) Now you got ME so involved in this, I feel like I'M the one debugging this sucker! Like if it was MY code I was trying to fix! :)
Let me know if any of this helps... I am actually quite interested in what you discover.

WinLockDLL.dll functions in Windows7

I'm running an app for testing students, which prevents them from doing anything but the test.
Naturally, the app blocks them from closing it, and blocks them from running the task manager (among other things):
[DllImport("WinLockDLL.dll")]
private static extern int CtrlAltDel_Enable_Disable(bool bEnableDisable);
private void Restrict(bool enabled)
{
CtrlAltDel_Enable_Disable(enabled);
}
The dll contains other functions I use, such as hiding the taskbar and the desktop.
Until recently, the students all had WindowsXP, and it worked.
Recently the students have all upgraded to Windows7, and it stopped working.
During debugging, I've found that Windows7 simply doesn't HAVE WinLockDLL.dll, so I copied the dll to one of the W7 computers and gave the app a try.
This time it found the dll and raised no errors, but the function simply had no effect.
So, does anyone know of an alternative in Windows7?
The closest thing I found was this, in which someone posted that:
All the functions you used in the example crash on Windows 7 unless you change the call to DLL_CALL_STDCALL
"Calling STDCALL" doesn't help, since that is exactly what DllImport does by default.
I've read of alternatives for blocking ctrl-alt-delete, such as canceling the ctrl key or blocking the taskmanager via registry or GPO, but I much prefer a simply alternative for WinLockDLL.dll, which contains several functions I use.
Thanks in advance!
For anyone that finds this in the future. I am creating a library to replace WinLock.dll for Windows 7. The source can be found here.
Win7Lock Github

Delphi program & Windows 64-bit compatibility issue

I have some customers/candidate who complained that my program doesn't work on their Windows 7 64 bit version (confirmed with screenshots). The errors were strange, for example:
in the trial version i am
getting a error message whenever i
click on \"mark\" \"delete\" \"help\".
error msg is: Access violation at
address 0046C978 in module
\'ideduper.exe.\' read of address
00000004
windows 7 ultimate 64bit. i7 920
#2.67GHz 9gb or ram
'Mark', 'delete' and 'help' are just standard TToolButton on TToolbar.
The other example is failing to get a thumbnail from IExtractImage.
I have told them to try Compatibility mode but still doesn't work.
The problem is when I tested it on Windows 7 HP 64-bit on my computer (which I've done it before released it actually) it just works fine! So I don't know what causing it
Do you have any advice ?Are different Windows package (home basic,premium,ultimate,etc) treating 32 bit prog differently ?Are the newer version of Delphis (I use 2006) more compatible with 64 bit Windows ? Do I need to wait until 64 bit compiler out?
Thanks in advance
Your best bet in my opinion is to add MadExcept or EurekaLog or something similar to your application and give it to the customer to try again. MadExcept will generate log with stack trace, which will give you a clearer view of what is happening there.
To answer 2nd part of the question, 32bit Delphi programs work fine on 64bit Windows 7. I think it's more likely you have some memory management problems and the customer just happens to stumble upon them while you don't. Use FastMM4 to track those down.
Your applications is trying to access an invalid pointer. Changing environment may surface issues that are hidden in others. Check your application, and use FastMM + JCL+JCVL/MadExcept/EurekaLog to get a detailed trace of the issue. Some Windows APIs may have some stricter call requisites under 7 and/or 64 bit, but we would have to know what your app actually cals.
A free alternative to MadExcept is JCL Debug stuff. However it is less thorough and doesn't include the cool dialog box to send the stack trace to you via email, or as a file you can attach and manually email.
MadExcept is worth the money, and it is free for non-commercial use. You could try it first on your own PC, observe its functionality, and be sure it functions the way you want, and then buy it.
If buying Delphi is worth it (and it is!) then buying mad Except is a no brainer. But if you insist on rolling your own, JCLDebug (part of jedi code library) is also pretty nice.
Give them a stripped down version of your app and see when the problem goes away. I am betting it is your code as I never had any problems with my (hundreds of) W7/64 clients.
I'd be willing to bet it's an issue in your code. The reason it's failing on your customer's machine and not yours is that your machine probably has the default Data Execution Protection (DEP) enabled (which is turned on only for essential Windows programs and services), while your customer's computer is actually using DEP as intended (turned on for all programs and services).
The default setting (which is compatible with older versions of Windows, like 95/98/ME), allows software to execute code from what should be data segments. The more strict setting won't allow this, and raises a system-level exception instead.
You can check the settings between the two by looking at System Properties. I'm not at a Win7 machine right now, but on WinXP you get there by right-clicking on My Computer, choosing Properties, clicking on Performance Options, and then selecting the "Data Execution Prevention" tab. Find it on Vista/Win7 by using the Help; search for Data Execution Protection.
The solution, as previous answers have told you, is to install MadExcept or EurekaLog. You can also get a free version as part of JEDI, in JCLDebug IIRC. I haven't used it, so I can't vouch for it personally. I've heard it's pretty good, though.
If you don't want to go that route, set a breakpoint somewhere in the startup portion of your app (make sure to build with debugging info turned on). Run your app until the breakpoint is hit, and then use the IDE's Search->Goto Address (which is disabled until the breakpoint is hit). Enter the address from the exception dialog (not the one that's almost all zeros, but the 0046C978 address, prefixed with $ to indicate it's in hex) as in $0046C978. You'll probably end up in the CPU window looking at assembly code, but you can usually pick out a line of Delphi code of some sort that can sometimes give you a place to start looking.
In addition to all previous suggestions, I'll add the difference in accessing Registry under WOW64 compared to Win32. If your application is accessing Registry to read or write some settings, you should be aware of this. First, take a look at this and this page in the MSDN. On this page you will find 2 flags that determine the access you get to Registry from 32- or 64-bit application. KEY_WOW64_64KEY is the one that you should use.
In any case, I agree with others about using madExcept (or any other similar tool) to be able to find the exact cause of your problems.

Resources