Michael Niethammers Blog

10.2.2010

Linq to SQL Fremdschlüssel programmatisch umsetzen

Abgelegt unter: SQL Server, C#, LINQ, .Net / Visual Studio — admin @ 18:10

In LinqtoSQL gibt es ein Problem, wenn man versucht Fremdschlüssel eines Datensatzes programmatisch umzusetzen, wenn es sich bei den beteiligten Tabellen um eine 1:n Beziehung handelt. In meinem Fall von heute ging es darum, den zugehörigen Parent-Datensatz “umzuhängen”.  Als Entwickler ist man geneigt einfach den Foreign-Key mit dem anderen Schlüssel zu ersetzen. In Linq führt das zu einer Exception:

image

image

Lösung:
Statt nur den Fremdschlüssel umzusetzen muss man die ganze Referenz umhängen indem man das neue, richtige Objekt zuweist. Linq löst hinter den Kulissen beim Speichern die IDs richtig auf und schreibt den geänderten Fremdschlüssel richtig weg. Auch in diesem Fall ist die Fehlermeldung nicht gerade sehr hilfreich!

25.11.2009

Verwendung der WPF ComboBox mit Linq

Abgelegt unter: C#, LINQ, WPF — admin @ 11:00

Nachdem ich selber kein vernünftiges Beispiel zu diesem Thema gefunden habe, kommt hier kurz zusammengefasst die Verwendung der WPF/Silverlight Combobox nochmal im Zusammenspiel mit LINQ.

Folgende Tabellen liegen diesem Beispiel zugrunde:

image

Im Beispiel soll über eine Combobox die aktuelle Position des Mitarbeiters eingetragen werden. In der Mitarbeitertabelle gibt es dazu das ForeignKey-Feld FK_Position und eine Relation zur Tabelle Position, die als Lookuptabelle dient.

In meiner Pflegemaske ist die Liste der Mitarbeiter so definiert:

image

In meiner Pflegemaske ist die Combo so definiert:

image

Und im Codebehind der Maske werden die Daten wie folgt geladen:

image

Ganz wichtig damit der Refresh der Combobox richtig funktioniert:

Im Listview, der die Mitarbeiterliste anzeigt, muss die Eigenschaft IsSynchronizedWithCurrentItem=”True” zu setzen!! Nur dann wird der aktuelle “Datensatz” in der Collection beim Blättern in der Liste auch umgesetzt und nur dadurch refreshed sich auch die Combobox wie gewünscht.

15.9.2009

WPF Multibinding – schon gewusst?

Abgelegt unter: C#, Visual Studio, WPF — wmn @ 15:26

Seit der Version 3.5 SP1 gibt es beim Databinding ein neues Feature, das man z.B. für die Anzeige von Tooltips bequem nutzen kann:

Dies hier wäre wohl der “klassische Ansatz um mehrere Texte als Tooltip anzuzeigen:

<Element>
  <
Element.Tooltip>
    <
StackPanel Orientation=“Horizontal”>
      <
TextBlock Text=“{Binding Path=Feldwert1}”/>
      <
TextBlock Text=“% von, “/>
      <
TextBlock Text=“{Binding Path=Feldwert2}”/>
      <
TextBlock Text=“% bis”/>
    </
StackPanel>
  </
Element.Tooltip>
</
Element>

So gehts inzwischen aber auch:

<TextBox.Text>
    <
MultiBinding StringFormat=“{}{1:#0}% von, {2:#0}% bis”>
      <
Binding Path=“Feldwert1″ />
      <
Binding Path=“Feldwert2″/>
    </
MultiBinding>
</
TextBox.Text>

Interessanterweise kann man diese Syntax auch in der Datenpflege anwenden. Das führt dazu, dass die Werte der zwei dahinterliegenden Felder in einer
Textbox erscheinen und dort auch gepflegt werden können. Allerdings ist das für den Anwender nicht gerade transparent wo das erste Feld aufhört und
wo das zweite anfängt. Auch das Thema Datenvalidierung wird dadurch sicher schwieriger. Insofern ist dieses neue Feature hier sicher nicht angebracht!

2.9.2009

Daten in einem ListView dynamisch anzeigen

Abgelegt unter: C#, Visual Studio — wmn @ 16:29

Häufig will man Daten, die einem bestimmten Status entsprechen oder bestimmte Werte überschreiten in einer Liste besonders hervorheben. Dies kann man in WPF recht einfach machen. Hier kann man sogar dynamisch die komplette optische Darstellung eines Elementes zur Laufzeit über einen Trigger austauschen.

Untenstehend habe ich einmal ein einfaches Beispiel aus einer WPF-Maske rauskopiert:

  1. Verwendet wird ein ListView-Steuerlement (erweiterte Listbox)
  2. der Trigger bzw. das Template ist der Einfachheit halber im XAML-Code direkt enthalten – im produktiven Einsatz sollte man diese in eine Ressource extrahieren damit man auch mehrere Spalten einfach daran binden kann
  3. Das Listview-Control ist an eine Collection gebunden, die über ein LINQ-Statement selektiert wird. Der Trigger schaltet die Farben abhängig vom Feldinhalt des Feldes Emplstatus (character) um:

<ListView x:Name=”lstPlanEmployees” IsSynchronizedWithCurrentItem=”True” ToolTip=”durch auswählen Personendaten anzeigen”  SelectionChanged=”lstPlanEmployees_SelectionChanged” FontSize=”12″ItemContainerStyle=”{DynamicResource ItemContStyle}” >
<ListView.View>
<GridView>
<GridViewColumn Width=”60″ >
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox x:Name=”txtStatusCol” Text=”{Binding Path=Emplstatus}” />
<DataTemplate.Triggers>
<DataTrigger Binding=”{Binding Path=Emplstatus}” Value=”aktiv”>
<Setter Property=”Foreground” TargetName=”txtStatusCol” Value=”Green” />
</DataTrigger>
<DataTrigger Binding=”{Binding Path=Emplstatus}” Value=”inaktiv” >
<Setter Property=”Foreground” TargetName=”txtStatusCol” Value=”Yellow” />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn DisplayMemberBinding=”{Binding Path=Jobtext}” Header=”Jobtext” Width=”150″ />
<GridViewColumn DisplayMemberBinding=”{Binding Path=Name}” Width=”180″ Header=”Name” />
</GridView>
</ListView.View>
</ListView>

1.9.2009

WPF Datenvalidierung – Schritt für Schritt

Abgelegt unter: C#, Visual Studio — wmn @ 08:22

Jeder hat das Problem, dass eingegebene Daten validiert werden müssen, bevor sie in der Datenbank abgelegt werden. Der Anwender soll bereits bei der Eingabe entsprechende Hinweise zu seinen Eingaben erhalten. Unten habe ich mal eine kleine Einführung für eine der vielen möglichen Varianten der Datenvalidierung aufgeführt. Der Text ist etwas rudimentär ich hoffe es hilft trotzdem bei der Entwicklung:

Im Beispiel wurde eine ganz normale WPF-Anwendung erstellt. In das Projekt wurde eine LINQ to SQL- oder Linq to Entities-Klasse aufgenommen um einen Datacontext für den Zugriff auf die Datenbank zu haben.

Textbox-Control im XAML:

  • Databinding ganz normal  an ein Object mit InotifyPropertyChanged-Events z.b. direkt Objekte aus dem DataContext
  • Nach der Prüfung wird bei einem Fehler die Fehlermessage als Tooltip angezeigt
  • Optional könnte man den Style im Fehlerfall noch anpassen – default ist ein roter Rand

<TextBox Margin=”5,5,5,5″ Grid.Column=”1″ TextWrapping=”Wrap” Text=”{ Binding NoDEPC,ValidatesOnExceptions=True, NotifyOnValidationError=true }” Validation.Error=”TextBox_Error”>
</
TextBox>
Eventhandler für Fehler in der Datenvalidierung im Codebehind oder im Template….

private
void TextBox_Error(object sender,
ValidationErrorEventArgs e)
{
if (e.Action == ValidationErrorEventAction.Added)
            {
            ((Control)sender).ToolTip =
e.Error.Exception.InnerException.Message.ToString();
            }
  else
      {
           ((Control)sender).ToolTip = “”;
     }
}

Das gebundene Object z.B. aus dem Datacontext muss erweitert werden:
Hier: gebundenes Feld NoDEPC

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Business;
using System.Collections;

namespace Business
    {
// die EntityKlasse, die vom LINQ-Designer generiert
// wurde, wird hier noch erweitert

public partial class Profit_Center 
   {
   public void SetDefaultValues()
             {
             ID_ProfitCenter = Guid.NewGuid();
             NoDesoursys = “99″;
             NoDeco_Area = “XXXXX”;
             PNSourSys = “33″;
            PNCo_Area = “05″;
             IsActive = true;
             IsTemplate = false;
             }
// überschriebene erweiterte Methode aus der Klasse

partial void OnNoDEPCChanged()
   {
   // sobald das property geändert wird
   //z.B. durchs Verlassen der Textbox
   // läuft die Regelprüfung
   CheckNodePC(this.NoDEPC);
   }

//eigentliche Regelprüfung in der klasse
public string CheckNodePC(string Nodename)
   {
   string msg = “”;

        if(Nodename== null || Nodename== “”)
                 msg = “Profitcenternamen dürfen nicht leer sein “;
        if(Nodename.Contains(” “)== true)
                 msg += “Profitcenternamen dürfen keine Leerstellen enthalten”;

       if (msg !=“”)
           {
       // exception auslösen damit die message auch
       //an die GUI kommt
            throw new ArgumentOutOfRangeException(msg);
             return msg;
           }
         }
    }


 

12.3.2009

Anleitung zu den Sicherheitseinstellungen für Silverlight-Anwendungen

Abgelegt unter: Silverlight, C#, Visual Studio — wmn @ 12:41

Nachdem unser WPF-Workshop nun schon einige Tage zurückliegt, bin ich derzeit an unserem Silverlight 2 - Projekt dran. Ein ziemlich nerviges Thema ist wieder einmal das Thema Security.
Hierzu habe ich ein ziemlich gutes Dokument mit entsprechenden Hinweisen gefunden:

http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=7cef15a8-8ae6-48eb-9621-ee35c2547773

21.1.2009

freies Refactoring Tool

Abgelegt unter: C#, Visual Studio — wmn @ 10:04


Viele kennen Resharper als Refactoring Tool seit langem. Von DevExpress gibt es ein deutlich eingeschränktes Tool mit ähnlicher Funktionalität - dafür ist es Freeware: 

 

http://www.devexpress.com/Products/Visual_Studio_Add-in/CodeRushX/

7.1.2009

VS Explorer for Visual Studio released.

Abgelegt unter: C#, Visual Studio — admin @ 10:24

von Universalthread.com:

From SSWare: “VS Explorer adds a Windows Explorer-Like file and folder browsing window to Visual Studio. It provides complete access to file andfolder context menus (including 3rd party extensions such as TortoiseSVN) and drag-drop functionality which allows directly adding files/folders to your projects. It can quickly browse to the current solution folder, project folder
or the selected item. It can add selected dll/exe files as references and open command prompt window on selected folder. VS Explorer eliminates switching back and forth between Visual Studio  and Windows Explorer and other external programs and allows you to focus on your work slow and preserve concentration, save time, reduce stress and work efficiently.”

http://www.ssware.com/vsexplorer/vsexplorer.htm

4.11.2008

Daten per OleDB nach Excel ausgeben mit C#

Abgelegt unter: C#, Sonstiges — wmn @ 16:23
Über COM Interop kann man ja direkt auf Excel zugreifen. Hier kommt ein Beispiel , wie man Daten dorthin schreibt.

Beispiel stammt von hier:


http://dotnet-snippets.de/dns/excel-datatable-mittels-oledb-in-excel-dokument-exportieren-SID272.aspx(Autor Hagen Sigel)

C#

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

using System;

using System.Collections.Generic;

using System.Text;

using System.Data;

using System.Data.OleDb;

using System.Runtime.Remoting;

using System.Reflection;

using System.Runtime.InteropServices;

namespace Rainbird.Examples.Office.Excel.OLEDBAccess

{

    /// <summary>

    /// Exportiert den Inhalt einer DataTable in ein neues Excel-Dokument.

    /// </summary>

    public
class ExcelExport

    {

        /// <summary>

        /// Privater Standardkonstruktor.

        /// </summary>

        private ExcelExport() { }

        /// <summary>

        /// Schreibt das Schema einer bestimmten Tabelle in eine neue Excel-Datei.

        /// </summary>

        /// <param name=”table”>Tabelle</param>

        /// <param name=”fileName”>Dateiname</param>

        public
static
void WriteTableSchemaToExcelFile(DataTable table, string fileName)

        {

            // Excel im Hintergrund öffnen

            object excel = Activator.CreateInstance(Type.GetTypeFromProgID(”Excel.Application“));

            // Auflistung der Mappeen abrufen

            object books = excel.GetType().InvokeMember(”Workbooks“, BindingFlags.IgnoreCase | BindingFlags.GetProperty | BindingFlags.OptionalParamBinding, null, excel, new
object[0]);

            // Neue Mappe erstellen

            object book = books.GetType().InvokeMember(”Add“, BindingFlags.InvokeMethod | BindingFlags.OptionalParamBinding, null, books, new
object[0]);

            // Auflistung der Tabellenblätter abrufen

            object sheets = book.GetType().InvokeMember(”Sheets“, BindingFlags.IgnoreCase | BindingFlags.GetProperty | BindingFlags.OptionalParamBinding, null, book, new
object[0]);

            // Neues Tabellenblatt erstellen

            object sheet = sheets.GetType().InvokeMember(”Add“, BindingFlags.InvokeMethod | BindingFlags.OptionalParamBinding, null, sheets, new
object[0]);

            // Name des Tabellenblatts festlegen

            sheet.GetType().InvokeMember(”Name“, BindingFlags.SetProperty, null, sheet, new
object[1] { table.TableName });

            // Zähler

            int i = 0;

            // Spalten der Tabelle durchlaufen

            foreach (DataColumn column in table.Columns)

            {

                // Zähler erhöhen

                i++;

                // Feldnamen einfügen

                object range = sheet.GetType().InvokeMember(”Cells“, BindingFlags.GetProperty | BindingFlags.OptionalParamBinding, null, sheet, new
object[2] { 1, i });

                range.GetType().InvokeMember(”Value“, BindingFlags.SetProperty | BindingFlags.OptionalParamBinding, null, range, new
object[1] { column.ColumnName });

            }

            // Dokument speichern

            book.GetType().InvokeMember(”SaveAs“, BindingFlags.InvokeMethod | BindingFlags.OptionalParamBinding, null, book, new
object[1] { fileName });

            // COM-Verweise freigeben

            Marshal.ReleaseComObject(sheet);

            Marshal.ReleaseComObject(sheets);

            Marshal.ReleaseComObject(book);

            Marshal.ReleaseComObject(books);

            // Excel schließen

            excel.GetType().InvokeMember(”Quit“, BindingFlags.InvokeMethod, null, excel, new
object[0]);

            // Excel.Application COM-Verweis freigeben

            Marshal.ReleaseComObject(excel);

        }

        /// <summary>

        /// Erzeugt eine OLEDB-Verbindungszeichenfolge für ein bestimmtes Excel-Dokument.

        /// </summary>

        /// <param name=”fileName”>Dateiname (.XLS)</param>

        /// <returns>Verbindungszeichenfolge</returns>

        private
static
string BuidExcelConnectionString(string fileName)

        {

            // Verbindungszeichenfolge erzeugen un zurückgeben

            returnProvider=Microsoft.Jet.OLEDB.4.0;Data Source=” + fileName + “;Extended Properties=Excel 8.0“;

        }

        /// <summary>

        /// Erzeugt aus einer Tabelle ein Excel-Dokument.

        /// </summary>

        /// <param name=”table”>Tabelle</param>

        /// <param name=”fileName”>Dateiname des Ziel-Excel-Dokuments</param>

        public
static
void FillExcelSheet(DataTable table, string fileName)

        {

            // Neue leere Excel-Datei aus dem Tabellenschema erzeugen

            WriteTableSchemaToExcelFile(table, fileName);

            // Verbindungszeichenfolge erzeugen

            string connectionString = BuidExcelConnectionString(fileName);

            // Neue OLEDB-Verbindung erzeugen

            OleDbConnection connection = new OleDbConnection(connectionString);

            connection.Open();

            // String-Generator für Parameter erzeugen

            StringBuilder parameterBuilder = new StringBuilder(”) VALUES (“);

            // Spalten zählen

            int columnCount=table.Columns.Count;

            // INSERT SQL-Anweisung für Excel erzeugen

            StringBuilder builder = new StringBuilder(”INSERT INTO [“);

            builder.Append(table.TableName);

            builder.Append(”$] (“);

            // Alle Spalten durchlaufen

            for (int i = 0; i < columnCount; i++)

            {

                // Spaltennamen anfügen

                builder.Append(table.Columns[i].ColumnName);

                // Parameter anfügen

                parameterBuilder.Append(”?“);

                // Wenn eine weitere Spalte folgt …

                if (i < (columnCount - 1))

                {

                    // Kommas anfügen

                    builder.Append(”,“);

                    parameterBuilder.Append(”,“);

                }

            }

            // SQL-Anweisung fertigstellen

            builder.Append(parameterBuilder.ToString());

            builder.Append(”)“);

            string insertStatement = builder.ToString();

            // Preisliste durchlaufen

            foreach (DataRow row in table.Rows)

            {

                // Neuen OLEDB-Befehl erzeugen

                OleDbCommand command = new OleDbCommand(insertStatement, connection);

                // Alle Spalten durchlaufen

                foreach(DataColumn column in table.Columns)

                {

                    // Parameter übergeben                   

                    command.Parameters.Add(new OleDbParameter(column.ColumnName,row[column]));

                }

                // Befehl ausführen

                command.ExecuteNonQuery();

            }

            // Verbindung schließen

            connection.Close();

        }

    }

}

Assemblies signieren Schritt für Schritt

Abgelegt unter: C#, Visual Studio — admin @ 16:12

Mein Assembly bekommt einen starken Namen - Erstellen und Signieren einer Assembly mit strong name
Was ist ein ?Strong Name??

Ein Assembly, das mit dem Anwendungsverzeichnis ausgeliefert wird, benötigt in der Regel keinen besonderen Namen. Ein Assembly aber, das von mehreren Anwendungen gleichzeitig benutzt werden soll, braucht einen absolut eindeutigen Namen ? den sogenannten ?strong name? (starken Namen).
Dieser strong name ist ein einfacher Textstring, der sich aus dem Namen der Assembly, einem öffentlichen Schlüssel und einer digitalen Signatur zusammensetzt.
Ein strong name erfüllt folgende Anforderungen:
? Namenseindeutigkeit durch die Verwendung eindeutiger Schlüsselpaare
? Schutz der Versionsherkunft ? nur der Entwickler des Codes kann eine Folge-Version des Assemblies erstellen
? garantiert Integrität der Assembly
? Installation im Global Assembly Cache (GAC) möglich

Um die Vorteile eines Assemblies mit starkem Namen zu behalten und Dll-Konflikte zu vermeiden, können Assemblies mit strong name nur auf Assemblies mit strong name verweisen.

Wie erstelle ich eine Assembly mit einem starken Namen?
Um ein Assembly mit einem starken Namen zu erstellen, muß man zuerst ein Schlüsselpaar aus einem öffentlichen und einem privaten Schlüssel generieren.
Dafür gibt es das Kommandozeilen-Tool sn.exe im Verzeichnis %FrameworkSDK%\bin.
In der Eingabe aufforderung geben Sie folgenden Befehl ein:
Sn -k meinKey.snk
Es wird dabei ein Schlüsselpaar in der Datei meinKey.snk angelegt.
Dieses Schlüsselpaar muß dann der Assembly zugewiesen, d.h. signiert werden. Dafür haben Sie zwei verschiedene Möglichkeiten.

1. Signieren über Attribute unter Verwendung der Datei AssemblyInfo.vb bzw .cs:
[C#]
[assembly: AssemblyKeyFileAttribute(@”..\..\meinKey.snk”)]

Falls Sie eine IDE, z. B. Visual Studio .NET, verwenden, müssen Sie wissen, wo diese nach der Schlüsseldatei sucht. Visual Basic .NET sucht die Schlüsseldatei beispielsweise in dem Verzeichnis, in dem die Visual Studio-Projektmappe enthalten ist, wohingegen der C#-Compiler die Schlüsseldatei in dem Verzeichnis sucht, in dem die Binärdatei enthalten ist.

2. Signieren über die Nutzung des Kommandozeilen-Tools Assembly-Linker al.exe:
al /out:meinAssembly.dll meinModul.netmodule /keyfile:meinKey.snk

Bei beiden Möglichkeiten wird der öffentliche Schlüssel als sogenannter Token im Manifest der Assembly abgelegt. Ein Token ist ein Teilabschnitt des vollständigen öffentlichen Schlüssels und wird aus Platzgründen oft an Stelle des eigentlichen Schlüssels verwendet. Zusätzlich wird die Assembly mit dem privaten Schlüssel signiert. Diese Signatur ist wiederum Teil des Manifests.

Durch die Umkehrung der Signatur mit Hilfe des öffentlichen Schlüssels kann man nun sicher feststellen, ob eine Assembly auf dem Weg vom Autor zum Empfänger verändert wurde.
Somit kann kein Unbefugter den Code ändern, wenn er nicht im Besitz des vollständigen Schlüsselpaares ist.

Es ist zu empfehlen, ein Schlüsselpaar nur einmal für eine Firma bzw. für ein Projekt zu generieren und diese Datei, vor allem den privaten Schlüssel, gut unter Verschluß zu halten.

Da Sie eine Assembly nach dem Erstellen nicht mehr mit einem strong name signieren können, stellt sich die Frage, was ich als Entwickler tun kann, wenn ich gerade nur über den öffentlichen, nicht aber den privaten Schlüssel verfüge. Darauf gibt es eine einfache Antwort: das verzögerte Signieren.

Wie funktioniert das verzögerte Signieren?
Beim verzögerten Signieren (delayed signing) wird die Assembly vorerst nur teilweise signiert. Dabei wird nur der öffentliche Schlüssel verwendet. Für den privaten Schlüssel und die vollständige Signierung wir Platz reserviert.

Zuerst müssen Sie über den öffentlichen Schlüssel verfügen.

Sollten Sie über das vollständige Schlüsselpaar verfügen und das verzögerte Signieren aus einem anderen Grund anwenden wollen, können Sie den öffentlichen Schlüssel so aus der Schlüssel-Datei herausfiltern:
Sn -p meinKey.snk meinPublicKey.snk
meinPublicKey.snk enthält nun nur den öffentlichen Schlüssel der Datei meinKey.snk.

Nun fügen Sie der AssemblyInfo-Datei zwei benutzerdefinierte Attribute aus dem System.Reflection Namespace hinzu:

[C#]
[assembly:AssemblyKeyFileAttribute(”meinPublicKey.snk”)]
[assembly:AssemblyDelaySignAttribute(true)]

Dabei wird der Name der Datei mit dem öffentlichen Schlüssel angegeben und das verzögerte Signieren durch den Wert ?true? aktiviert.
Wird das Assembly dann kompiliert, ist es zwar nur teilweise signiert, besitzt aber einen starken Namen und kann im GAC installiert und dort verwendet werden.
Zuvor muß allerdings noch die Überprüfung der Signatur deaktiviert werden, da die Assembly ja über keine gültige starke Namenssignatur verfügt. Diese Deaktivierung können Sie wieder mit dem Strong Name-Tool vornehmen:

Sn -Vr meinAssembly.dll

Zu einem späteren Zeitpunkt, üblicherweise unmittelbar vor der Weitergabe, signieren Sie dann die Assembly mit dem kompletten Schlüsselpaar:

Sn -R meinAssembly.dll

Danach schalten Sie die Verifizierung für die Assembly wieder ein:

Sn -Vu meinAssembly.dll

Hinweis: Bei allen Optionen für Sn.exe wird die Groß- und Kleinschreibung beachtet. Eine vollständige Liste aller Optionen finden Sie in der .NET Framework SDK-Dokumentation unter dem Stichwort ’sn.exe’.

Nächste Seite »

läuft stressfrei mit WordPress ( WordPress.de )