10

I need a way for my .Net Winform app to detect if my app is opened on a Laptop or a Workstation.

I have looked at Environment and SystemInformation but to no avail. Would WMI do the trick?

Thanks for the direction....


As requested I have an application that uses Merge Replication to allow our users to work in Members homes. Some who use the program never go in the field and as such only have towers. This is a WORK only app so our systems are somewhat controlled. As in, no UPS on Desktops and No Laptop CPU either.

I have setup my DAL to be able to switch, based an a setting, between local SQL and the Central SQL Server. I would like to be able to set this automatically based on there system.

If a laptop then they should be pointing local if a tower, centrally.

Does this help? I deliberately left it off before to don't clutter the answers. My apologies for apologies for accomplishing the opposite.

Refracted Paladin
  • 12,096
  • 33
  • 123
  • 233
  • 8
    Remotely activate their webcam, take a picture of their eye, then use one of those awesome image enhancement utilities (like you see on those TV shows all the time, 'cause I'm sure they really exist, they're on TV!) to detect the computer type from the image reflection on their pupil. Of course, you've got amazing image detection software that will do this automatically, right!? – Stewbob May 14 '10 at 20:18
  • 2
    What, exactly, do you want to know, and why do you want to know it? If the laptop had eight CPUs and 32GB of RAM, would you want to treat it as a laptop? If a workstation was running on batteries, would you want to treat it as a workstation? – John Saunders May 14 '10 at 20:22
  • 1
    As other people have pointed out, this is a deceptively difficult question to answer. Perhaps it would be useful if you shared more about what you are _actually_ trying to do. What is your application going to do that depends on the type of computer used? – Kennet Belenky May 14 '10 at 20:22
  • @John Saunders - See my edit above in answer to your suggestion. – Refracted Paladin May 14 '10 at 20:36
  • 2
    Judging by your extra information, you don't really want to tell if the machine is a laptop or not. What you really want is a UI toggle for the two modes of operation. – Kennet Belenky May 14 '10 at 20:42
  • @Kennet Belenky - No, I already HAVE a UI toggle between the two modes. I appologize for not making that clearer. What I need is a way to Automatically Toggle it. We have VERY low tech users that we CANNOT entrust with this ability. That make more sense? – Refracted Paladin May 14 '10 at 20:50
  • 5
    What if you just pinged the central SQL server to see if you can access it? If so, then use it, otherwise use the local store. – David May 14 '10 at 21:00
  • @Stewbob: I like that idea, I need a copy of the class once you have it working! On a similar but completely serious note, what about a dialog that featured two large icons, each representing the mode intended? They could be *pictures* of a laptop/desktop, or pictures showing connected (online)/disconnected (offline) modes. Though, I guess the question is whether the user is allowed to make such a decision at all. – JYelton May 14 '10 at 21:15
  • I would appreciate an explanation on the downvote(*though I already have a guess...*)? I can't improve the question without **feedback**. – Refracted Paladin May 14 '10 at 22:09
  • 1
    You've got a system with 2 possible configurations, and you _must_ use the correct configuration every time? You need either a clear, operational definition of the circumstances for each situation, or you need to make your system robust to misconfiguration. @David's idea is the best I've seen yet, but there are still situations in which it'll fail. – Kennet Belenky May 14 '10 at 22:23

7 Answers7

13

This is a really hard problem to solve because of the edge cases involved. I don'tk now how accurate you need to be for your application, but here is a reliable way to find out if the user is on a sterotypical laptop.

Win32_Battery

You might want to take a look at EstimatedRunTime.

EstimatedRunTime

Data type: uint32
Access type: Read-only

Estimate in minutes of the time to battery charge depletion under the

present load conditions if the utility power is off, or lost and remains off, or a laptop is disconnected from a power source. This property is inherited from CIM_Battery.

You also might want to check:

Win32_PortableBattery

Also, here's an interesting discussion of a similar problem and dealing with UPS.

http://forum.bigfix.com/viewtopic.php?pid=19908

Specifically:

"Microsoft ACPI-Compliant Control Method Battery"

Also, as noted in the comments, you will have to consider users on a laptop plugged into the wall with the battery disconnected.

Robert Greiner
  • 29,049
  • 9
  • 65
  • 85
  • Can a desktop employ a battery (other than UPS)? – JYelton May 14 '10 at 19:57
  • 1
    @JYelton: I haven't heard of one; but UPS causes a bunch of false positives. Win 7 itself is confused by them. For example, if you have a UPS connected to a desktop, 7 believes you are running on battery power and therefore won't give you the windows experience index numbers. – NotMe May 14 '10 at 20:06
  • 2
    Yeah, I've been thinking about that. The edge cases here could lead to some false positives/negatives. For instance, what if the user is using a laptop that is connected to the wall with the battery disconnected. Do you call it a laptop because the guy at Fry's said it was? Or do you count it as a desktop because that's how it's being used at present? These are design decisions that will have to be decided on before the application releases. – Robert Greiner May 14 '10 at 20:10
  • Thanks but because of our in-house "controlled" environment this could well work. Thank you for a positive potential solution accompanied by a word of caution. A perfect SO answer!! – Refracted Paladin May 14 '10 at 22:11
  • Sure thing, being in a controlled situation will definitely improve your chances of getting a correct reading. This is definitely an interesting problem and I hope you get it working the way you want it. Good luck! – Robert Greiner May 15 '10 at 00:46
4

http://msdn.microsoft.com/en-us/library/Aa394474

then look at

ChassisTypes

Value Meaning
1 Other
2 Unknown
3 Desktop
4 Low Profile Desktop
5 Pizza Box
6 Mini Tower
7 Tower
8 Portable
9 Laptop
10 Notebook
11 Hand Held
12 Docking Station
13 All in One
14 Sub Notebook
15 Space-Saving
16 Lunch Box
17 Main System Chassis
18 Expansion Chassis
19 SubChassis
20 Bus Expansion Chassis
21 Peripheral Chassis
22 Storage Chassis
Keith Nicholas
  • 43,549
  • 15
  • 93
  • 156
  • I didn't know this existed - I doubt it is useful, how would this data get populated? I've built hundreds of desktop PCs and never set any sort of chassis type variable. – JYelton May 14 '10 at 19:59
  • I'm sure for desktops it would be rarer too populate it.... however, for laptops? as they tend to be OEM, I would think they would be set correctly. (perhaps) – Keith Nicholas May 14 '10 at 20:02
  • 1
    Aah, Pizza Box. Used to have one of those form factors. I doubt this value is often accurate or useful. – Broam May 14 '10 at 20:02
  • 2
    That class has some amazing properties. `ServicePhilosophy` (`ServiceFromTop`, `ServiceFromSide`, ...), `CableManagementStrategy`, `HeatGeneration` (in BTUs/hour), `NumberOfPowerCords`. – Michael Petrotta May 14 '10 at 20:08
  • I thought you were kidding when you said Pizza Box. Silly me. – Tim Lovell-Smith May 14 '10 at 20:48
3

Get the type of processor using (see this question):

System.Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE")

If you can determine it is a mobile processor, you have your answer.

(It's worth noting that WMI will give you better info, as explained in the question I linked.)

Community
  • 1
  • 1
JYelton
  • 35,664
  • 27
  • 132
  • 191
  • 7
    Although it is possible to get a desktop processor in a laptop. – Thomas May 14 '10 at 19:53
  • 6
    …And some people use laptop processors on desktop for lower power consumption. =) – Arkku May 14 '10 at 19:54
  • 2
    Perhaps the definition of laptop and desktop need to be explained, in other words, does the OP want to know the processor type, or the chassis style? If the latter, there's just no way to know! – JYelton May 14 '10 at 19:56
2

I have tested the following batch file successfully, but only on a few computers:

@echo off
reg query "HKLM\SYSTEM\CurrentControlSet\Enum\ACPI" /s | find "DeviceDesc" | find "ACPI Lid" > nul
if errorlevel 1 (
    echo This computer IS NOT a laptop ^(no ^"ACPI Lid^" device found in Registry^)
) else (
    echo This computer IS a laptop ^(^"ACPI Lid^" device found in Registry^)
)
echo. & pause
MikeOnline
  • 994
  • 11
  • 18
1

Based on your updated information I have a couple of recommendations.

  1. Make it a configurable option. Either during installation or the first run ask them what they are. This is going to be a lot more accurate than guessing.

  2. If you already have merge replication in place... Why not treat everyone as disconnected / remote user?

NotMe
  • 87,343
  • 27
  • 171
  • 245
  • **1 -** It IS a configurable option that I can switch at will. The problem is our users CANNOT be trusted to toggle this accordingly. **2 -** Because it seems pointless overhead to replicate to a tower that can NEVER be in the field. Why have the extra complexity and overhead? – Refracted Paladin May 14 '10 at 20:53
  • "Why have extra complexity and OH?" Because it is the right thing to do - GUESSING based on the hardware is pretty much guaranteed to be wrong and you are going to have the original problem anyway. Basing a decision on hardware type doesn't really solve your problem - at least not as I understand it. – Tim May 14 '10 at 21:39
1

You can check in C++ if computer has a lid. I think only laptops haave a lid so it should be enaugh to check this parameter.

SYSTEM_POWER_CAPABILITIES  oPowerCapabilities;

CallNtPowerInformation( POWER_INFORMATION_LEVEL::SystemPowerCapabilities, NULL, 0, &oPowerCapabilities, sizeof( oPowerCapabilities ) );

if( oPowerCapabilities.LidPresent == 1 )
{
    cout<<"Laptop";
}
else
{
    cout<<"PC";
}
AGR
  • 321
  • 6
  • 8
  • 1
    This seems like a good solution, it also has other useful attributes which seem to distinguish between "system batteries" and short term UPS batteries. For example, on a laptop I see LidPresent=1, SystemBatteriesPresent=1, BatteriesAreShortTerm=0, UpsPresent=0. – james Oct 15 '19 at 20:01
  • I've since tried this on a server with UPS, and found the following: LidPresent=0, SystemBatteriesPresent=1, BatteriesAreShortTerm=0, UpsPresent=0. In conclusion, it seems that UpsPresent can't be relied upon, but LidPresents looks a good candidate. – james Oct 16 '19 at 09:04
0

Maybe you can query for battery information?

Take a look at this

Francisco Soto
  • 10,277
  • 2
  • 37
  • 46