---
title: "Namespace för Windows konton ?"
type: "forum-thread"
url: "https://www.webforum.nu/amne/dotnet/82664-namespace-för-windows-konton"
topic: ".NET"
topic_url: "https://www.webforum.nu/amne/dotnet"
author: "erka"
published: "2003-07-24T08:39:02.000Z"
updated: "2003-08-06T11:10:45.000Z"
replies: 14
views: 766
page: 1
pages: 1
language: "sv-SE"
site: "webForum — webforum.nu"
rights: "Upphovsrätten till varje inlägg tillhör dess författare."
attribution: "Citera som: webForum, https://www.webforum.nu/amne/dotnet/82664-namespace-för-windows-konton"
---

# Namespace för Windows konton ?

## #1 — erka, 2003-07-24T08:39Z

Jag undrar om någon vet i vilket namespace jag hittar klasser för att hantera windows konton, tex om jag vill ändra lösenordet till en viss använder lokalt på servern.

Permalänk: https://www.webforum.nu/p/82664

## #2 — erka, 2003-07-25T07:21Z

Har nu letat i 2 dagar efter hur man ändrar NLTM lösenord via .net, men inte hittat något. Det borde ju gå. Ingen som har någon annan idé ;) Börjar bli smått desperat

Permalänk: https://www.webforum.nu/p/1120816

## #3 — developer, 2003-07-26T09:48Z

Använd NetUserChangePassword med interop

Permalänk: https://www.webforum.nu/p/1121516

## #4 — erka, 2003-07-26T15:51Z

developer, förklara gärna lite mer :) tack

Permalänk: https://www.webforum.nu/p/1121705

## #5 — developer, 2003-07-27T22:49Z

Normalt används funktionen [NetUserChangePassword](http://msdn.microsoft.com/library/en-us/netmgmt/netmgmt/netuserchangepassword.asp) för att programmatiskt byta lösenord. Dock finns inte den exponerad i .Nets klassbibliotek. Man använder då "interop" (interoperability) eller mer specifikt P/Invoke för att komma åt den som en vanlig C-funktioner från en dll.

NetUserChangePassword finns i Netapi32.dll, och du måste då i din klass berätta att du vill komma åt den. Såhär:

```
[DllImport("Netapi32.dll", EntryPoint="NetUserChangePassword", SetLastError=false, CharSet=CharSet.Unicode, ExactSpelling=true)]
private static extern NET_API_STATUS NetUserChangePassword(String domainname, String username, String oldpassword, String newpassword);
```

Nu vet .Net runtimen att den ska använda den NetUserChangePassword som finns i NetApi32.dll från din C# kod. Dock finns inte NET_API_STATUS i .Nets klassbibliotek, men från \<LMCons.h\> ser man att det är en DWORD, vilket i C# motsvarar en uint.

Det är smidigt att lägga in returvärdena i en enum. Dessutom tycker jag det är trevligare att wrappa all funktionalitet i en klass så att användaren av klassen inte ser vad som ligger bakom. Klassen har statiska publika metoder för att byta lösenord och kastar exception om något går fel. All kod är \*givetvis\* helt otestad.

```
using System;
using System.Runtime.InteropServices;

public sealed class NetApi 
{
	#region P/Invoke
	private const uint NERR_BASE = 2100; // från <LMErr.h>
	private enum NET_API_STATUS : uint 
	{
		NERR_Success            = 0,
		ERROR_ACCESS_DENIED     = 5,
		ERROR_INVALID_PASSWORD  = 86,
		NERR_InvalidComputer    = NERR_BASE+251,
		NERR_NotPrimary         = NERR_BASE+126,
		NERR_UserNotFound       = NERR_BASE+121,
		NERR_PasswordTooShort   = NERR_BASE+145,
	}
	[DllImport("Netapi32.dll", EntryPoint="NetUserChangePassword", SetLastError=false, CharSet=CharSet.Unicode, ExactSpelling=true)]
	private static extern NET_API_STATUS NetUserChangePassword(String domainname, String username, String oldpassword, String newpassword);
	#endregion

	// Den här klassen vill vi inte skapa instanser av. En privat konstruktor
	// stoppar det.
	private NetApi() {}

	#region Exceptions

	// Just nu har vi bara password-funktionalitet, men senare kanske du
	// vill lägga till mer från NetApi. Därför har vi ett bas-exception
	// för framtida bruk.
	public class NetApiException : Exception
	{
	}

	// Detta kastas om password-bytet gått fel
	public sealed class PasswordException : NetApiException 
	{
		public enum ExceptionReason 
		{
			OldPasswordRejected,
			NewPasswordRejected,
			InvalidUserName,
			DomainNotFound,
			NotPrimary,
			UnknownError,
		};

		ExceptionReason m_Reason;
		ExceptionReason Reason { get { return m_Reason; } }
		public PasswordException(ExceptionReason reason) 
		{
			m_Reason = reason;
		}
		public override string ToString()
		{
			return "Failed to change password: " + Reason.ToString();
		}
	}
	#endregion

	/// <summary>
	/// Byter lösenord för angiven användare
	/// </summary>
	public static void ChangePassword(String domainname, String username, String oldpassword, String newpassword) 
	{
		if (oldpassword == null) throw new ArgumentNullException("oldpassword");
		if (newpassword == null) throw new ArgumentNullException("newpassword");

		switch (NetUserChangePassword(domainname, username, oldpassword, newpassword)) 
		{
			case NET_API_STATUS.NERR_Success:
				break;

			case NET_API_STATUS.NERR_UserNotFound:
				throw new PasswordException(PasswordException.ExceptionReason.InvalidUserName);
			case NET_API_STATUS.ERROR_INVALID_PASSWORD:
				throw new PasswordException(PasswordException.ExceptionReason.OldPasswordRejected);
			case NET_API_STATUS.NERR_PasswordTooShort:
				throw new PasswordException(PasswordException.ExceptionReason.NewPasswordRejected);
			case NET_API_STATUS.NERR_InvalidComputer:
				throw new PasswordException(PasswordException.ExceptionReason.DomainNotFound);
			case NET_API_STATUS.NERR_NotPrimary:
				throw new PasswordException(PasswordException.ExceptionReason.NotPrimary);

			default:
				throw new PasswordException(PasswordException.ExceptionReason.UnknownError);
		}
	}

	/// <summary>
	/// Byter lösenord för användaren som kör detta.
	/// </summary>
	public static void ChangePassword(String oldpassword, String newpassword) 
	{
		ChangePassword(null, null, oldpassword, newpassword);
	}
}
```

 Mer information om interop finns bland annat här:

- [MSDN Magazine, July 2003](http://msdn.microsoft.com/msdnmag/issues/03/07/NET/default.aspx)
- [Gotdonet - How Do I... Get Started Using Interoperability?](http://samples.gotdotnet.com/QuickStart/howto/default.aspx?url=/quickstart/howto/doc/Interop/Interop_Overview.aspx)

Permalänk: https://www.webforum.nu/p/1122274

## #6 — erka, 2003-07-28T08:15Z

Stort tack developer, lär återkomma med fler frågor snart ;)

Permalänk: https://www.webforum.nu/p/1122346

## #7 — erka, 2003-07-28T12:20Z

Håller nu på och pillar, din kod verkar fungera hyffsat med små modifieringar. Den spottar ut felmeddelanden om jag skickar in fel användarnamn etc. Men om jag skickar in rätt lösenord och användare ger den mig

throw new PasswordException(PasswordException.ExceptionReason.UnknownError);

Min c# är ju inget vidare, är det något rättighetsproblem kanske ?

Permalänk: https://www.webforum.nu/p/1122484

## #8 — developer, 2003-07-28T13:08Z

Kolla så NET_API_STATUS-konstanterna stämmer, du får söka i .h filerna för att hitta dem. Alternativt göra ett c-program som skriver ut de numeriska värdena. Sedan såg jag att jag glömt ERROR_ACCESS_DENIED i switchen.

Vad blir det numeriska returvärdet?

  NET_API_STATUS status = NetUserChangePassword(...);

Permalänk: https://www.webforum.nu/p/1122507

## #9 — erka, 2003-07-28T13:42Z

Tack developer får nu 

throw new PasswordException(PasswordException.ExceptionReason.AccessDenied)

men om jag ger asp.net kontot rättigheter till Netapi32.dll fungerar det ändå inte. Är det något annat kanske. Hajjar inte riktigt hur jag ska få ut det numeriska returvärdet, kör det på en aspx sida där jag än så länge bara har klassen i ett script block, på sidan finns textfält för gamalt lösenord samt nytt, och en submittknapp som triggar en sub som i sin tur kör ChangeUsrPassword med värdena från textboxarna.

tacksam

Permalänk: https://www.webforum.nu/p/1122531

## #10 — developer, 2003-07-28T17:39Z

Det är inte själva dll:en du inte ha access till. Du lyckas ju exekvera funktionen och den returnerar en felkod. Problemet måste vara att användaren inte har rätt att exekvera NetUserChangePassword.

Vad händer om du kör från en vanlig windows form applikation eller en console-applikation med samma parametrar?

Vilket OS? Vilken användare blir det som kör funktionen under IIS:en? Läs hjälpen för NetUserChangePassword under "Remarks" om ERROR_ACCESS_DENIED.

Permalänk: https://www.webforum.nu/p/1122665

## #11 — erka, 2003-07-29T14:03Z

det är win2000, användaren som kör funktionen är den som är inloggad, om jag loggar in som "Erka" med lösenordet "querty" så är det ju det lösenordet jag försöker ändra. Ska kolla hjälpen, tack för hjälpen hitills :)

Permalänk: https://www.webforum.nu/p/1123097

## #12 — erka, 2003-08-05T12:52Z

Har lyckats lösa det nu genom att köra en "impersonation" som serveradmin innan jag försöker byta lösenord, sedan byter jag tillbaks till inloggad användare. Bara ett problem då jag inte är en c# kille.

Hur får jag felmeddelanden som fångas i tex

```
throw new PasswordException(PasswordException.ExceptionReason.InvalidUserName);
```

att skrivas ut med en förklarande text istället som nu skrivas ut rakt på sidan

Exception of type PasswordException was thrown. 
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. Har en label på sidan som heter LblErrorMsg

tacksam

Permalänk: https://www.webforum.nu/p/1129871

## #13 — erka, 2003-08-06T08:39Z

Vad jag undrar över är alltså hur jag i c# ska skriva för att få felmeddelandet (om något genereras) i ditt exempel att skrivas ut i en label på aspx sidan om ett fel uppstår.

tacksam

Permalänk: https://www.webforum.nu/p/1130362

## #14 — developer, 2003-08-06T10:54Z

Läs om try/catch: <http://msdn.microsoft.com/library/en-us/csref/html/vclrfTheTrycatchStatement.asp>

```
try
{
    NetApi.ChangePassword("", "");
}
catch (PasswordException passwordException)
{
    string err = "";
    switch (passwordException.Reason)
    {
        case NetApi.PasswordException.OldPasswordRejected: s = "invalid password"; break;
        case NetApi.PasswordException.NewPasswordRejected: s = "New password incorrect (rejected by policy, too short etc.)"; break;
        default: s = passwordException.Reason.ToString(); break;
    }
    Console.WriteLine("Failed to change password: {0}", s);
}
```

Permalänk: https://www.webforum.nu/p/1130490

## #15 — erka, 2003-08-06T11:10Z

Stort tack developer, härligt med folk som hjälper till andra som inte vet lika mycket :) Trode inte att try catch fanns i c#

Permalänk: https://www.webforum.nu/p/1130501

---

Tråden på webben: https://www.webforum.nu/amne/dotnet/82664-namespace-för-windows-konton
