How to run arbitrary code when windows resumes from hibernate? - windows

I need to run some code when my computer resumes from hibernate (even before I logon). The laptop I am using has a bizzare problem. If I have an external monitor connected to it while resuming from hibernate the laptop chooses the external display as the main video device and the laptop screen remains blank. This becomes more frustrating when sometimes both displays remain blank indefinitely.
I am thinking of writing some code to switch the active display back to the laptop screen when the computer resumes from hibernate. But which windows event do I need to look for to begin with?
The built in hot keys for switching the display have also stopped working. I have reinstalled the OS several times by now and things go smoothly for a few days after that and then its back to square one.

This article on CodeProject discusses the various Windows messages that relate to power saving events.

I think most laptops have issues with that. It is not something they seem to be able to solve in the drivers/ACPI BIOS.
I know Linux allows you to modify the ACPI tables, but I cannot remember if this is possible on Windows.
A Google should provide links to tools you can use to inspect your laptop's ACPI tables in Windows (MS tools IIRC).

Related

Is there a faster way to connect to a Bluetooth device from cmd/powershell than btcom from Bluetooth command line tools?

I've put together a Powershell script to allow me to connect my Bluetooth headphones to my PC without having to open the Bluetooth settings page each time (based on the ones in https://github.com/stanleyguevara/win10-bluetooth-headphones, but using Get-PnPDevice and Get-PnPDeviceProperty to check whether the device is connected rather than using an environment variable to save the state).
The script works, but there's one big QoL issue. The script uses the Bluetooth command line tools here to connect/disconnect the device (in particular, it uses the btcom command). However, these commands are very slow to run, with the whole process taking around a minute total. This is true even though I am using the device's MAC address to connect, and not its friendly name (which would be even slower). This makes using the script much slower than just opening the settings panel each time (though opening the settings panel is less convenient since it requires opening and going through multiple windows).
I've seen many questions about this sort of thing (how to connect/disconnect a Bluetooth device from cmd/powershell, but everything I've seen regarding Windows tends to suggest using the Bluetooth command line tools at the link above, so they don't solve the speed issue. Other things I've found suggest disabling the Bluetooth adapter entirely, which isn't what I want to do. Others suggest using the Win+K shortcut to open up the connections sidepanel, but this doesn't really address the question of whether there's a way to do this from cmd/powershell, and is slightly less automated since you have to wait a second for the list to populate and manually navigate to the device to connect/disconnect (though at least it solves the problem of opening a bunch of windows).
Is there a way to connect/disconnect from a Bluetooth device in cmd/powershell that is faster than btcom?

Why would PDF Text extraction hang for a single PDF but work via RDP

I have a program that extracts text from PDFs. It runs as a scheduled task on Windows Server 2008.
The library I use is ByteScout's PDF Extractor SDK, which is based on Tesseract under the covers.
Since it went live last November, the program has successfully extracted text from over 50,000 PDFs from many different sources.
It recently hung on a single PDF and subsequently on a second one, from the same source in the same visual format.
I am able to recreate the problem using a trivial 12 line program. I sent this program to the vendor but running that program in their environment works (it does not hang).
So I did some experimentation and this is where it gets strange.
The program works on my PC (Windows 7) if I RDP to it, but not if I am directly logged in. This behavior is repeated on other Windows 7 PCs in our environment.
It works on Server 2008 if I am RDPed, but not as a scheduled task.
It works on Windows 10, whether I am RDPed or logged in directly.
If I watch the program in Process Monitor when it is stuck, I can see that it is opening and reading C:\Windows\Fonts\times.ttf over and over again.
If it was only working using RDP, I'd wonder if the cause had anything to do with failing use of graphics acceleration or some such, but given that it doesn't work as a scheduled task where none would be present either, I think that's a blind alley.
Does anyone have any suggestions where to look next?
So ByteScout have fixed the problem. To quote Eugene on the cause ...
The problem is in System.Drawing and GDI+. Sometimes it crashes on text drawing operations that are normal in PDF but causing some internal exceptions in System.Drawing. Moreover, it's behavior varies depending on display device capabilities. That is why it works in RDP session and crashes on a desktop.
We are trying various workarounds on these crashes, attempting to fall back to alternate text drawing ways. The hanging is related to these fallbacks.

GUI goes blank on remote desktop

I wrote a compiled MATLAB GUI that we run on a remote machine via Remote Desktop. Overall it runs fine, but sometimes the GUI will blank out many of the control objects (buttons, table, popups). It seems to happen after the screen of the client computer has been locked or after the GUI has been minimized.
If you move the mouse over the buttons, popups, or table headers, they reappear. The table cells will reappear if they are selected. The GUI hasn't crashed and still works fine, but the objects just disappear until you make them reappear again. I have only seen this happen when using remote desktop (Windows-Windows using Remote Desktop Connection).
How can I get this to stop happening? It isn't really breaking anything, but it is very annoying.
I don't know if this is an issue with MATLAB or with the Remote Desktop configuration, so I posted this question here. Feel free to move this to superuser if you think it's more appropriate.
Remote Desktop has issues with handling low level rendered graphics, and interacting with graphics cards. In our experience (we use Nvidia GPU's for rendering and computation engines on multiple projects/applications) we have found remote desktop to fail in so many cases, that we have ditched it for a third party tool.
I suspect this is what you are running into.
One option I would consider, is forcing Matlab to do software rendering, if this fixes the problem, then for certain it's the graphics cards. The first hit on a google search for "matlab software rendering" returns the matlab command opengl. Reading the documentation page for that, gives the command:
opengl software
It sounds like the remote desktop minimization is causing it. For efficiency, Windows will disable various graphics when a Remote Desktop window is minimized on the client computer. To prevent this, create and set a DWORD RemoteDesktop_SuppressWhenMinimized to 2 at the following registry location:
HKEY_LOCAL_MACHINE\Software\Microsoft\Terminal Server Client
After doing this minimizing and locking your screen shouldn't do anything to the RDP session. I doubt it's a graphics card issue, as Windows 10 Creator's Edition allowed remote sessions to use the remote graphics card just like as if you were running locally.

VS2010: Loading symbols from dlls very slow

I have a program which I am working on my Dell Laptop XPS 502X. At work, I usually have another monitor plugged in my DVI port and everything is fine. When I work from home, I only have the laptop screen. When I start the program in VS2010, it is very slow and I notice in the bottom of the screen Loading symbols for ...\NVIDIA Corporation\coprocmanager\detourel.dll... which takes around 10-20 seconds every time. Any idea on why this is happening ?
EDIT:
I thought it was a drivers problem, but now it happens again.
I tried the ideas posted in similar questions
-DeleteAllBreakpoints stuff, didn't work.
-No remote symbols fetch or network path
-Enabled Just My Code
Looks like a hook DLL injected by the graphics drivers... driving me crazy!
EDIT 2:
The problem happens on and off, today everything seems find, yesterday, I even noticed it was slow loading the GROOVEEX.dll while the program was running when I was starting a CFileDialog. So it might not just be something related to the graphics drivers.
It looks like nVidia's use of the Detours library from Microsoft. Hopefully this will help...
http://forums.nvidia.com/index.php?showtopic=212704
and
http://research.microsoft.com/en-us/projects/detours/
Run the msconfig tool that is built into Windows to take a look at some of the things that nVidia launches at startup. You may want to try disabling some of the startup items temporarily, but you'll want to research what each item you disable is before doing so, or you may have to go into safe mode to get back to a good state.

Program runs slow on just a couple of computers

I have a program that I run on multiple network PCs. When I compiled the most recent version, it runs extremely slowly on 2 PCs on the network, but runs fine for everyone else.
This used to happen with my old dev PC when I had an additional 2gb RAM installed. When I would remove the additional 2gb and recompile, it would then work fine for everyone.
Now, I am on a completely new machine and am having the same issue. I've tried to rebuild the project after rebooting, but still have the same issue.
For all other PCs, the program loads in about 3-5 seconds. On these 2 PCs, it takes anywhere from 45 seconds to 1.5 mins to load...
One of the PCs is an older Dell Dimension 8200, but the other is a newer OptiPlex that is identical to several other PCs on the network, so this is what is really making it so confusing.
For now, I've had to revert to the old version so it will run correctly for everyone.
Does anyone have any idea of anything to try?
Thanks in advance!!!
Edit:
Ok, it was an exhausting day yesterday trying various things to solve this issue. Here is what I tried and where the problem begins:
Using the new program
Went back to old versions of all updated components, but still had the same issue
Using the old program
I decided to go back to the drawing board and start from the old version of the application and incrementally add the new features a small piece at a time.
Recompiled the old version using the old components - program works fine
Updated to new DevExpress components - program works fine
Updated to new ESBPCS components - program works fine
Updated to new DeepSoftware components - program works fine
Ok, so now we know there is nothing with the component sets I've updated...
Added 1 image to each of 2 image lists - program works fine
Added new database table - program works fine
Added code to open and close the new table - program works fine
Added new action to action list and added a menu item and toolbar button to new action (action does nothing at this point) - program works fine
Added a new BLANK form to the application and added code to open the new form - BAM!!!
So, adding just one form to the application is what's causing the issue! I removed all the code for the opening of the form, commented out the uses clauses and removed the uses entry from the project source and everything is back to normal!
Anybody have any idea about this?
Thanks!
Edit 2:
For #Warren P - here is my .DPR source:
program Scheduler;
uses
ExceptionLog,
Forms,
SchedulerMainUnit in 'SchedulerMainUnit.pas' {FrmMain},
SchedulerDBInfoUnit in 'SchedulerDBInfoUnit.pas' {FrmDBInfo},
SchedulerHistoryUnit in 'SchedulerHistoryUnit.pas' {FrmHistory},
SchedulerOptionsUnit in 'SchedulerOptionsUnit.pas' {FrmOptions},
SchedulerExtVersionUnit in 'SchedulerExtVersionUnit.pas' {FrmExtVersion},
SchedulerSplashUnit in 'SchedulerSplashUnit.pas' {FrmSplash},
SchedulerInfoUnit in 'SchedulerInfoUnit.pas' {FrmInfo},
SchedulerShippedUnit in 'SchedulerShippedUnit.pas' {FrmShipped}; {<-- This is the new form with the issue}
{$R *.res}
begin
Application.Initialize;
Application.Title := 'SmartWool WIP Scheduling Assistant';
Application.CreateForm(TFrmMain, FrmMain);
Application.CreateForm(TFrmDBInfo, FrmDBInfo);
Application.CreateForm(TFrmHistory, FrmHistory);
Application.CreateForm(TFrmOptions, FrmOptions);
Application.CreateForm(TFrmExtVersion, FrmExtVersion);
Application.Run;
end.
And here is the intialization section of the main form to create the splash:
initialization
FrmSplash:=TFrmSplash.Create(Application);
FrmSplash.Show;
FrmSplash.Refresh;
Edit 3:
Anybody??? Please?
It could be that the program is waiting for timeouts when trying to access resources that are not available on that machine such as network drives or Internet hosts.
Try running Process Monitor when starting up your program and look for file open calls. Filter the output so it only shows your process.
http://technet.microsoft.com/en-us/sysinternals/bb896645
Performance problems initially can seem very daunting at first.
I have been on many teams where people have tried to guess at a reason for performance problems. This sometimes works, but is far less effective than actually measuring the code.
When reproducible on a development machine, I would recommend a profiler.
There was a previous question that asked about
Delphi Profiling tools which has several possible tools you could use.
When you can't reproduce the problem on your development machine, then it becomes a bit more difficult, but not impossible. Typically I have found that problems are related to an application dependency that is different, and not performing well. Understanding the external influences on your application can help pinpoint the problem.
Specifically common external problems in some of my applications.
Network
Database
Application Servers
Installation or Data File Location (i.e. Disk Performance)
Virus and Malware Scanners
Other application interring with yours such as a virus.
To monitor for items related to the network (i.e. Database, web services, etc...)
I typically use Wireshark which allows me to see if resources are responding in expected times. My most common problem is poor performing DNS and can found using Wireshark.
You can use the AutoRuns program to determine everything that starts up when your computer does, it's useful in determine differences between machines.
But most of all I have logging that can be turned on in my applications and this allows me to isolate the problem to a specific area of code. This narrowing down to a specific section of code reduces the guessing, and allows you to focus on a few possible problems.
I created a log function for this that I call at specific places (in your case especially during startup). It adds a timestamp to each log text and stores them in a TMemo that is regularly saved. Not only very helpful when debugging, but may also shed some light on your problem.
Are you using code signing - ie Microsoft Authenticode? If so, then outdated certificate authorities on the computers can cause significant delays to startup.
First, I would try to defragment the hard disk. If still slow, I would check the power supply. Maybe your hard disk are getting insufficient energy.
Check if there is the same antivirus software on those 2 problematic computers. If so, then your Delphi application may match byte pattern used in some virus made in Delphi. Update virus definitions to solve it, or report false alarm to antivirus company, or change antivirus software.
Check if there isn't any printer installed on those 2 problematic computers. If it is so, then add any printer and try again.
Idea 1:
One reason I have seen for very slow application load time, is when printing or reporting system components like Developer Express Express Print, are in your application.
The problem I saw when using Developer Express Printing components, is that I had an offline or non-responsive network printer in my list of printers (check the control panel printer icon) that was not responding. Some of those Developer Express components seem to read some information from each printer you have installed, and the solution was to go to those clients, and delete old printers from their control panel, that were no longer being used. Each not-responding network printer added up to 60 seconds for a TCP Timeout, to the startup time of my application.
Update - Idea 2:
Download MS DebugView and install it on the machine that runs slowly. Now go back to your main development PC, open the IDE, open your main project file (right click on the project, view project source in project viewer), this will show you the contents of your main project source file (.dpr). go to the main begin....end. block. Now set a breakpoint on the main begin statement, and single step INTO (not OVER) and you will see all the module initialization sections. In each one add this: OutputDebugString('ModuleName').
Now when you run this inside the Delphi Ide you will see messages, and see how far apart they come in, and understand what is taking a long time to initialize. Instead of installing the delphi ide onto the machine that runs slowly, Debug View (which is less than 400kb single executable) will be run, and it will show you these debug messages, along with a nice time display (##.# seconds) for each message.
MS Debug view is here.
Are you allowing the forms to be constructed on initialization within the DPR source? If so, you may do well to consider whether or not you want those forms sucking up memory the entire time, more-over if you want those forms to be wasting the application's time on load.
A rule of thumb: If the form is used a LOT during the application's execution, allow it to be constructed when the application loads (this will work out faster over-all than constructing the instance "on-demand").
If the form is not used very often at all (for example, a Dialog or an About Box), delete the "Application.CreateForm" line from the DPR source, and instead construct your instance on request...
var
LForm: TfrmAbout;
begin
Application.CreateForm(LForm, TfrmAbout);
try
LForm.ShowModal;
finally
LForm.Free;
end;
end;
Now that form (which may not even be displayed during the program's execution) is not sucking up system resources, and will not slow down the application's load time.
It may not solve your problem 100%, but it should certainly help!

Resources