Laden...

Forenbeiträge von Pedant Ingesamt 12 Beiträge

12.12.2021 - 19:17 Uhr

Hallo gfoidl,

So soll ein Forenbetrieb funktionieren

Jetzt wollte ich besonders artig sein und meinen Thread als [gelöst] markieren, so wie es hier angeregt wird:
myCSharp.de - Wie poste ich richtig?

ihr könnt anderen myCSharp-Benutzern das Leben und die Forumssuche erleichtern, wenn ihr eure Threads durch ein vorangestelltes [erledigt] im Titel als erledigt kennzeichnet, sobald das der Fall ist. Dazu einfach im ersten Beitrag des Threads auf 'Beitrag editieren' klicken, bei 'Thema:' das [erledigt] eintragen und den 'Beitrag speichern'. Statt [erledigt] könnt ihr natürlich auch [gelöst] verwenden, wenn das die Sache besser trifft, also insbesondere, wenn eine funktionierende und für andere nachvollziehbare Lösung des Problems auch wirklich explizit im Thread angegeben wurde.

Es scheitert aber daran, dass ich den ersten Beitrag im Thread nicht oder nicht mehr bearbeiten kann.

Falls ein Moderator das lesen und Langeweile haben sollte, kann er gerne dem Threadtitel ein [gelöst] voranstellen.

Gruß Frank

12.12.2021 - 14:05 Uhr

Hallo,

irgendwoher hatte ich eine ITapi3.dll als kompiliertes Binary und nutzte sie bisher.
Die Datei war von 2010.
Der Sourcecode ist noch verfügbar:
GitHub - markjulmar/itapi3: C++/CLI TAPI 3.0 client .NET wrapper

Das alte Binary gab es nur als 32-Bit-Variante.
Der Sourcecode war zwar für Visual Studio 2008, er ließ sich aber irgendwie in VS 2019 öffnen und kompilieren.
So erhielt ich eine 32- und eine 64-Bit-DLL.
Die funktionierten aber nicht überall und gaben dann mit der Eingangs beschriebenen Fehlermeldung aus, dass sie irgendetwas vermissten.

Die Hauptursache für mein Problem war wohl meine Unkenntnis von den Unterschieden zwischen Debug und Release.

Es ist wohl so, dass es von einigen DLL-Dateien spezielle Debug-Varianten gibt, die bei Windows zunächst nicht mit dabei sind.
Diese DLL tragen ein zusätzliches d am Ende des Dateinamens, zumindest trifft es auf diese beiden Dateien, die mein Programm mit der neuen ITapi3.dll benötigt.

VCRUNTIME140D.DLL
ucrtbased.dll

Die "normalen" Dateien sind ohne das d benannt.

VCRUNTIME140.DLL
ucrtbase.dll

Die DLL sollte schon Teil von Windows 10 sein, seit irgendeinem Upgrade (als Teil von Universal CRT).

Danke, das trifft dann aber auf die Datei ohne das d zu.

Ich hatte mein Programm und die ITapi3.dll mit der Einstellung "Debug" statt "Release" kompiliert.
Das führte dazu, dass als Änhängigkeiten, die DLL mit d gesucht und genutzt wurden.
Auf meinen Entwicklungsrechnern waren diese *d.dll vorhanden, auf normalen Windows10-Rechnern aber nicht.
Auf den normalen Windows10-Rechnern startete mein Programm daher nicht.

Ich habe jetzt alles auf "Release" kompliert und weiß jetzt auch, dass ich das so beibehalten sollte.
Es ist schon schlimm, wenn man nicht weiß was man tut.

Ohne gfoidl Tipp Dependencies zu nutzen, hätte ich das Problem wahrscheinlich nie beheben können.

Nochmal vielen Dank Euch beiden
Gruß Frank

10.12.2021 - 13:24 Uhr

Hallo gfoidl,

vielen Dank für Deinen ausführlichen und sehr hilfreichen Beitrag.

Edit: * den gibts jetzt sogar neu:
>

Das verlinkte, installationsfreie Tool hat mir gezeigt was fehlt.
Im konkreten Fall ist es eine DLL namens ucrtbased.dll.
Sie wird wohl auch "Microsoft C Runtime Library" genannt.
Sie ist Teil des "Windows Software Development Kit" und das ist auch bei "Visual Studio" mit dabei.

Ich melde mich nochmal zum Thema, mit mehr Details, sobald ich mich mit diesem Ergebnis und dessen Auswirkungen auf mein Programm näher befasst habe.
Wie es aussieht sollte ich mich auch mal mit dem Unterschied beim Kompilieren zwischen Debug und Release befassen.
Das hat anscheinend jeweils andere Abhängigkeiten zur Folge.

Gruß und Dank
Frank

09.12.2021 - 18:38 Uhr

Hallo,

bei einem C#-Programm von mir ist eine DLL (ITapi3.dll) als Verweis eingebunden.
Das Programm habe ich mit MS Visual Studio 2019 kompiliert.
Wenn ich das Programm in einer Eingabeaufforderung starte, kommt diese Fehlermeldung:

Fehlermeldung:
Unhandled Exception: System.IO.FileNotFoundException:
Could not load file or assembly 'ITapi3.dll' or one of its dependencies.
The specified module could not be found.

Wenn gemeldet wird, dass ein module nicht gefunden werden konnte, dann sollte man meinen, dass nach einem module gesucht wurde und nicht nach irgendeinem, sondern nach einem bestimmten.
Die Fehlermeldung verrät leider nicht welches module vermisst wird.
Nebenbei gefragt: Was ist eigentlich ein module?

Meine eigentliche Frage lautet: Wie kann man herausfinden nach welchem module gesucht wurde?

Die genannte ITapi3.dll wird übrigens nicht vermisst, denn wenn die Datei nicht vorhanden ist, sagt die Fehlermeldung:

Fehlermeldung:
...
The system cannot find the file specified.

Ich weiß aber, dass der Fehler mit dieser DLL zusammenhängt.
Der Fehler tritt übrigens nicht auf, wenn ich das Programm auf einem Rechner starte auf dem MS Visual Studio installiert ist.

Ich erhoffe mir eine allgemeine Antwort wo und wie man dem Fehler auf die Schliche kommen kann, daher habe ich keine spezifischen Details gepostet, die dann vielleicht von der Allgemeinheit der Frage ablenken.
Falls Informationen über mein Projekt und mein System dennoch erforderlich oder hilfreich sein sollten, reiche ich gerne alles nach.

Gruß Frank

19.04.2017 - 14:10 Uhr

Hallo ujr,

ja danke, das war eine Überlegung wert.
Es ist zwar nicht exakt die Lösung für mein Problem, aber durchaus ein alternativer Workaroud.
Ich habe das jetzt als optionalen, zweiten Workaroud eingebaut.
Gibt man der exe jetzt eine Batchdatei als Parameter an, dann werden die "Process"-Variablen gesetzt und per cmd die angegebene Batch gestartet.
Das Working-Directory wird dabei entsprechend gesetzt.

Beispiel:
meine.exe /b "C:\Mein Ordner\irgendeine.cmd"
=> meine.exe ermittelt die Werte und setzt die Variabeln entsprechend
=> irgendeine.cmd wird im Ordner "C:\Mein Ordner" gestartet
=> meine.exe beendet sich
=> irgendeine.cmd läuft weiter und kann die Variablen verwenden

Gruß Frank

18.04.2017 - 21:26 Uhr

Hallo david.m,

...na dann hatte ich ja recht mit "zuwenig Phantasie".

Gruß und Dank
Frank

18.04.2017 - 20:52 Uhr

Hallo Abt,

ob "User" oder "Machine" macht für mich tatsächlich keinen Unterschied.

Wenn ich jetzt aber so über "Process" nachdenke, bin ich etwas irritiert.
Man kann damit aus einem C#-Programm heraus Umgebungsvariablen setzen, die aber nur für den Prozess gültig und sichbar sind, der sie gesetzt hat, also nur für das Programm selbst und auch nur für die Dauer seiner Laufzeit.
Gibt es in C# nicht genug Möglichkeiten und Platz Variablen zu setzen?
Muss man noch welche ins Betriebssystem auslagern?

Wahrscheinlich fehlt es mir an Phantasie, aber mir fällt nichts ein wozu man das gebrauchen könnte?

Gruß Frank

18.04.2017 - 17:16 Uhr

Hallo Abt,

meinst Du mit "Übergabeparameter"
dings.exe /Parameter
einerseits und
cmd.StartInfo.Arguments = "Parameter"; andererseits oder etwas anderes?

Gruß Frank

18.04.2017 - 17:05 Uhr

Hallo,

danke für Eure Antworten.
Wie es aussieht muss ich vorerst bei meinem beschriebenen Workaroud belieben.
Ich finde es allerdings überraschend, dass es anscheinend keinen vorgesehenen Weg der Interaktion zwischen Batch und C# gibt und wie es sich hier anhört auch nicht zwischen Powershell und C#.
Das könnte ja auch in vielen anderen Situationen hilfreich sein und nicht nur bei meinem konkreten Anliegen.

Es gibt aber nur die beiden Varianten: Prozess oder Maschine.

Genaugenommen sind es drei: Machine, Process und User, aber alle drei nicht zielführend.

Spätestens mit dem Creators Update wird die cmd von der Powershell abgelöst.

Das "Ablösen", habe ich dem schon installierten Creators Updates schon wieder ausgetrieben.

Gerade jetzt wäre es eine gute Idee sich von der Leiche Batch zu verabschieden.

Batch sehe ich zwar nicht als "Leiche", aber vielleicht ist es tatsächlich an der Zeit sich mit Powershell zu befassen.
Dank für den Buchtipp.

...wusste ich nicht dass es pro Prozess nur Kopien gibt.

Eine Anmerkung dazu: mit dem Befehl setx statt mit set, kann man die Originale setzen und/oder ändern (was mir aber auch nicht helfen würde).

Gruß Frank

18.04.2017 - 16:30 Uhr

Hallo Abt,

danke für Deine Antwort, aber scheinbar hast Du übersehen, was ich bei "Das habe ich schon ausprobiert" unter 2. geschrieben habe.
Das permanente Setzen ist einerseits nicht erwünscht und andererseits in meinem Fall leider auch nutzlos und es (wie bei 1.) nur an den Prozess zu koppeln ist ja leider auch nicht zielführend.

Gruß Frank

18.04.2017 - 15:51 Uhr

Hallo,

ich versuche mit einer exe eine Umgebungsvariable zu setzen mit der Zielsetzung, dass diese (nur) in der Eingabeaufforderung gültig ist, in der ich auch die exe ausgeführe.

Mache ich es nur mit Batch

@echo off
set Test=123
echo %Test%

wird 123 ausgegeben und das ist gut so.

Was ich möchte ist das hier:

@echo off
REM set Test=123
meine-exe-die-set-Test-macht.exe
echo %Test%

Hier bekomme ich es nicht hin, dass auch 123 ausgegeben wird.

Das habe ich schon ausprobiert:

1.

Environment.SetEnvironmentVariable("Test", "123");
string ausgabe = System.Environment.GetEnvironmentVariable("Test");
Console.WriteLine(ausgabe);

Das funktioniert soweit, aber die gesetzte Variable ist verloren, sobald meine exe beendet ist.
Dann hätte ich auch gleich string ausgabe="123"; schreiben können und es hätte mir auch nichts genutzt.

2.

Environment.SetEnvironmentVariable("Test", "123", EnvironmentVariableTarget.User);

Das will ich nicht, da so die Variable dauerhaft in der Registry eingetragen wird und ich brauche sie nur temporär im aktuellen Kontext.
Außerdem steht die Variable so noch nicht in der Eingabeaufforderung zur Verfügung, in der sie gesetzt wurde, sondern erst in allen später geöffneten Eingabeaufforderung, wo sie aber nicht mehr benötigt wird.

3.

Process cmd = new Process();
cmd.StartInfo.FileName = "cmd.exe";
cmd.StartInfo.Arguments = "/k set Test=123";
cmd.Start();

Das öffnet mir eine neue, zusätzliche Eingabeaufforderung in der zwar die Variable korrekt gesetzt ist, aber meine Ausgangseingabeaufforderung kennt die Variable trotzdem nicht.
Außerdem möchte ich keine neu Eingabeaufforderung öffnen, sondern bei der bleiben, bei der ich bin.

4.

Process cmd = new Process();
cmd.StartInfo.FileName = "cmd.exe";
cmd.StartInfo.Arguments = "/c set Test=123";
cmd.Start();

Mit /c statt /k öffnet mir das zwar keine bleibende, neue Eingabeaufforderung, aber die gesetzte Variable ist sofort wieder verloren, sobald cmd sie erfolgreich gesetzt und sich anweisungsgemäß wieder geschlossen hat.
Die aufrufende Eingabeaufforderung hat, wie bei 1., davon nichts.

Mein aktueller Workaround
Im Moment lasse ich mir von meiner exe eine Batch-Datei erzeugen, in der der gewünscht set-Befahl enthalten ist und rufe dann diese Batch per call auf und lösche diese Datei wieder.
Das sieht dann so aus:

@echo off
meine-exe-die-eine-setTest.cmd-erzeugt.exe
REM Der Inhalt von setTest.cmd ist: set Test=123
call setTest.cmd
del setTest.cmd
echo %Test%

Es ist allerdings nicht sonderlich elegant eine Variable über die Festplatte zu übergeben.

Wozu das Ganze?
Der Wert, den ich der Umgebungsvariablen zuweisen möchte ist nicht statisch, sondern das Ergebnis einer Auswertung, die die exe ausführt.
Diese Auswertung von der Batch selbst erledigen zu lassen ist zu komplex.
Andersherum wäre es mir zu unflexibel, alles von der exe erledigen zu lassen und somit ohne Batch auszukommen.

Meine Fragen
Gibt es eine Möglichkeit eine Umgebungsvariable so setzen zu lassen, dass sie (nur) im gewünschten Kontext gültig ist?
Hat jemand einen alternativen Ansatz für eine Variabenübergabe von exe zu Batch?
Dazu noch eine Anmerkung: Es geht nicht nur um eine Variable, die übergeben werden soll, sondern um 42 Stück.

Gruß Frank

20.10.2014 - 10:00 Uhr

Hallo,

vom Level her, bin ich eher Anfänger, doch bisher kam ich mit Google und ausprobieren immer irgendwie zurecht.
Jetzt gehen mir aber die Ideen aus und daher schreibe ich meinen ersten Frage-Beitrag.

Ich versuche aus einer Videodatei gezielt ein Einzelbild zu lesen und dieses in einer PicturBox darzustellen, also diesen "Fünfzeiler" zu schreiben:

Program:

  1. Öffne testvideo.avi
  2. Spiele das Video nicht ab
  3. Gehe zu Stelle x
    (x=Zeitpunkt, Timecode, Framenummer oder was auch immer geht)
  4. lies das dortige Frame
  5. Nimm es und zeig es in der PictureBox
    (Das soll nicht das ganze Programm sein, es ist aber ein Kernstück an dem ich bisher scheitere.)

Versucht habe ich bisher:

DirectX SDK Jun2010 (9.29.1962.0)
using Microsoft.DirectX.AudioVideoPlayback;

film.SeekCurrentPosition(...)
So kann ich zu einer beliebigen Stelle springen,
Weiß dann aber nicht wie ich an das Bild kommen soll.

film.RenderToTexture
Damit komme ich an nutzbare Bilder.
Der Vorgang kennt aber kein Seek und ignoriert die aktuelle Position im Film.
Einmal gestartet wird immer die ganze Datei von vorne bis hinten "abgespielt".

AForge.NET Framework 2.2.5
http://www.aforgenet.com/framework/downloads.html
using AForge.Video;

film.NewFrame mit NewFrameEventHandler
Damit komme ich an nutzbare Bilder, doch auch hier wird immer die ganze Datei von vorn bis hinten "abgespielt".

film.Stop() / film.Start()
Mehr ist nicht. Hier gibt es kein Seek und kein Pause.

Hat jemand einen Tipp wie ich das Bisherige in den Griff bekomme oder was ich alternativ probieren kann?

Gruß Frank