Założenia: mamy aplikację *.exe oraz bibliotekę *.dll. Wewnątrz tej biblioteki: class Program { static void Main(string[] args){//coś}}.
Czy jest możliwe, aby program .exe utworzył nowy proces uruchamiający kod z dll?
nie jestem pewien, jak jest pod .net, ale ogólnie - da się. dll mają identyczną strukturę jak exe, tak wiec exe może eksportować funkcje, a dll może być uruchomiony.
Jeżeli program exe też jest pisany pod .Net, zrób w dllce klasę Program i funkcję Main jako public i powinno ruszyć.
Jeżeli program jest natywny, będzie gorzej.
Moim zdaniem właśnie z natywną by było prościej, co do .net pewności nie mam...
Wszystko w .Net.
System.Diagnostics.Process.Start("TestClass.dll");
i
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo.FileName = (@"C:\Windows\System32\rundll32.exe");
p.StartInfo.Arguments = path + @"\TestClass.dll";
p.Start();
nie działa.
a tak wygląda *.dll
namespace TestClass
{
public static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
public static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
"nie działa" - nie dało się trochę bardziej opisowo?
Aczkolwiek sprawdziłem i rzeczywiście coś nie idzie ("nie jest prawidłową aplikacją systemu win32")
Napiszę największe różnice jakie znalazłem w nagółówkach, ale nie pokuszę się o interpretację.
- dll ma w "charakterystykach" zdefiniowane IMAGE_FILE_DLL, exe oczywiście nie ma.
- dll ma w tabeli importów _CorDllMain, exe CorExeMain
- dll najwyraźniej nie ma xml manifestu.
edit:
(w .net:) An EXE is visible to the system as a regular Win32 executable. Its entry
point refers to a small loader which initializes the .NET runtime and tells
it to load and execute the assembly contained in the EXE.
A DLL is visible to the system as a Win32 DLL but most likely without any
entry points. The .NET runtime stores information about the contained
assembly in its own header.
Well, .NET blurs the differences. As Dmitriy says a .NET library is a Win32
DLL, which means that there are flags set as such in the Win32 headers in
the file. A .NET process is a Win32 EXE, again, with flags set as such.
However, to .NET a library can have the extension DLL or EXE, .NET checks
for both, BUT, even if the extension is EXE it still must be built as a
library if it is used to export classes.In .NET v1.1 and v1.0, only libraries can export classes, you cannot do this
with a process (there is one exception). If you want to export objects from
a process you must use .NET remoting. The exception is the .NET Installer
class, which can be a public class in a process and the installer tool can
still call it.In .NET 2.0 both libraries (DLL) and processes (EXE) can export classes.
A refleksja?
@Johny
tak, refleksja możesz wywołać metodę normalnie startujacą program, tylko że to nie będzie to nowy proces.
Zawsze możesz zrobić sobie osobny wątek, albo AppDomain
Dllka
namespace ClassLibrary1
{
public static class Program
{
[STAThread]
public static void Main()
{
Application.Run(new Form());
}
}
}
//wywolanie
class Program
{
static void Main()
{
Thread t = new Thread(ClassLibrary1.Program.Main);
t.Start();
}
}
Wątki to ja znam, ale nie o to się rozchodzi. Windows Forms UserControl może być umieszczana wewnątrz strony internetowej pod IE. Przy nadaniu odpowiednich uprawnień, można pozwolić takiej kontrolce na odpalenie nowej Formy, wątków, etc. Problem w tym, że po zamknięciu okna IE, kontrolka i wszystko, co ona wywołała, zostaje ubite. Dlatego zastanawiałem się, czy można jakoś utworzyć nowy, niezależny proces.
Raczej nie odpalisz nowego procesu spod IE. Poza tym proces nie umiera dopoki dzialaja jakies watki, wiec jak odpalisz swoj, to IR de facto nie powinien sie zakonczyc.
Form'a odpalam w nowym wątku, ale wywoływany jest Dispose po wyłączeniu ostatniej karty/okna IE. Pewnie jakaś forma zabezpieczeń, bo pole do nadużyć spore ;| Dzięki mimo wszystko [soczek]
Mały update.
Jeśli wstawimy WindowsForms User Control w stronę html, odpalimy to pod IE(zakładając nawet, że nasza kontrolka ma pełne uprawnienia), stworzymy nowy wątek i ubijemy kartę(nie całą przeglądarkę), to wątek działa minutę i zostaje ubity. Jakieś pomysły? Próbowałem GC,SurpressFinalize(this) i GC.KeepAlive(this), ale minuta i wszystko ginie ;|
private System.Threading.Thread t;
MainForm mf;
public void GoThread()
{
try
{
t = new System.Threading.Thread(RunForm);
t.IsBackground = false;
t.Start();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void RunForm()
{
mf = new MainForm();
Application.Run(mf);
GC.KeepAlive(mf);
GC.KeepAlive(this);
}
Nie rozumiem tego za bardzo. Gdyby wątek został zniszczony od razu, to byłoby to całkiem logiczne, ale tak? Skąd ta 1(zawsze) minuta. Dlaczego nie 5/10/30 sec., albo między 50 a 70 sec.?