2010-06-29 24 views
10

Vorrei determinare se il mio programma è in esecuzione su una versione di Windows Server. Apparentemente, System.Environment non contiene informazioni sul fatto che Windows è una versione server (non ci sono tali informazioni nello OS version object).Determinare se il programma è in esecuzione su Windows Server

So che posso usare SystemInformation.TerminalServerSession per verificare se il mio programma è in esecuzione su un desktop remoto (vedi anche this question), ma questo sarà anche vero se l'utente è semplicemente accedendo una pianura macchina client di Windows in remoto.

Quindi esiste un metodo supportato per determinare se il codice è in esecuzione su un server o su un computer client? Non mi dispiace usare P/Invoke se necessario.

Nota: non desidero cercare la stringa "Server" nel nome del prodotto, poiché probabilmente non funzionerà su alcuni sistemi a causa della localizzazione.

risposta

15

Grazie ai puntatori forniti dalla risposta di Nick, ho finalmente trovato ciò che stavo cercando. La funzione IsOS(OS_ANYSERVER) fa esattamente ciò di cui ho bisogno. Ecco il codice di esempio che dovrebbe funzionare per qualsiasi versione del sistema operativo (compresa la pre-Vista, dal momento che importiamo la funzione IsOS da ordinale da shlwapi.dll):

class OS 
{ 
    public static bool IsWindowsServer() 
    { 
     return OS.IsOS (OS.OS_ANYSERVER); 
    } 

    const int OS_ANYSERVER = 29; 

    [DllImport("shlwapi.dll", SetLastError=true, EntryPoint="#437")] 
    private static extern bool IsOS(int os); 
} 
+1

Se nick ti ha dato la risposta che hai usato per ottenere le informazioni di cui hai bisogno, allora dovresti accettare quella risposta invece della tua (le informazioni qui dovrebbero essere modificate nella tua domanda). –

+4

Bene, Nick non ha fornito la soluzione IsOS. Sembrava quindi più utile per altri lettori segnare la mia risposta come risposta accettata. Ho accreditato Nick con un voto positivo. –

+1

È una buona risposta, grazie per l'aiuto. Inoltre uso sempre un sito molto buono quando devo chiamare metodi esterni: http://www.pinvoke.net/ Ecco il metodo IsOS: http://www.pinvoke.net/default.aspx/shlwapi/IsOS .html – Major

5

Puoi P/Invoke le seguenti funzioni Win32:

GetProductInfo per Vista/Windows Server 2008+
GetVersionEx per Windows 2000 e

BJ Rollison ha un good post e sample code su questo sul suo blog.

+0

Grazie per i link. Ho finalmente risolto il problema chiamando IsOS. –

0

Ci dovrebbe essere una serie di di 'Funzioni Versione aiuto' definito nel file di intestazione VersionHelpers.h di WinAPI nell'assembly Kernel32.DLL. Quello che, secondo la documentazione, dovrebbe funzionare per il tuo caso è IsWindowsServer (void). Descrizione è qui:

http://msdn.microsoft.com/en-us/library/windows/desktop/dn424963%28v=vs.85%29.aspx

in C#, il codice sarebbe come questo (non testata):

using System.Runtime.InteropServices; 

public static class MyClass 
{ 
    [DllImport("Kernel32.dll")] 
    public static extern Boolean IsWindowsServer(); 
} 

E poi il codice del consumo sarebbe semplicemente:

bool is_it_a_server = MyClass.IsWindowsServer(); 

I' Non ho mai usato nessuna di queste funzioni quindi fammi sapere come funziona ...

+1

non sembra funzionare correttamente per me – Sauleil

+0

Quando utilizzo Kernel32.dll o Ntdll.dll per DllImport, viene visualizzato un errore che non riesce a trovare IsWindowsServer() in quegli assembly. – Brundle

+0

Vedere la risposta di Paul Hoepping; spiega perché 'IsWindowsServer' non può essere trovato in' kernel32.dll'. –

1

IsWindowsServer è una in linea in VersionHelpers.h.

È possibile trovare e leggere il file di intestazione sul computer. Utilizza la funzione API VerifyVersionInfoW.

Non è disponibile la funzione IswindowsServer in kernel32.dll.

0

Ho avuto lo stesso problema, anche se negli script.

Ho trovato questo valore; Sto esecuzione di query utilizzando WMI:

https://msdn.microsoft.com/en-us/library/aa394239(v=vs.85).aspx 
Win32_OperatingSystem 
ProductType 
    Data type: uint32 
    Access type: Read-only 
    Additional system information. 
    Work Station (1) 
    Domain Controller (2) 
    Server (3) 

Ho provato questo per le seguenti versioni del sistema operativo:

  • Windows XP Professional SP3
  • Windows 7 Enterprise
  • di Windows 8.1 Pro
  • di Windows 8.1 Enterprise
  • Windows 10 Pro 10.0.16299
  • Windows Server 2003 R2 Standard Edition
  • Windows Server 2003 R2 Standard Edition x64
  • Windows Server 2008 R2 Standard
  • di Windows Server 2012 Datacenter
  • di Windows Server 2012 R2 Datacenter

Trova il mio esempio in batch file qui sotto.

Lucas.

for /f "tokens=2 delims==" %%a in ('wmic.exe os get producttype /value') do (
    set PRODUCT_TYPE=%%a 
) 
if %PRODUCT_TYPE%==1 set PRODUCT_TYPE=Workstation 
if %PRODUCT_TYPE%==2 set PRODUCT_TYPE=DomainController 
if %PRODUCT_TYPE%==3 set PRODUCT_TYPE=Server 
echo %COMPUTERNAME%: %PRODUCT_TYPE% 

Si può facilmente fare questo in C#:

using Microsoft.Management.Infrastructure; 
... 
string Namespace = @"root\cimv2"; 
string className = "Win32_OperatingSystem"; 

CimInstance operatingSystem = new CimInstance(className, Namespace);