0

With VisualStudio it is easy to create application types for Console, Forms, etc, but I see no option for a command line application. I intend to install the small program below as a simple .exe in c:\windows\system32. If I open a command terminal and CD to the bin\debug dir of the VS project, I can type DateTime and get nice output. However, if I copy the DateTime.exe to c:\windows\system32 and open another command terminal, the command DateTime gives an error saying that the application could not be started, because of .Net Shim errors.

Should I do something different to create a commandline application rather than a Console app?

Should I install more files from the bin\debug directory in c:\windows\system32 ?

using System;

namespace DateTime
{
    class Program
    {
        static void Main()
        {
                Console.Write(System.DateTime.Now.ToString("o"));
        }
    }
}

NB: reason for the above command line app is that the system commands Date/T and Time/T do not provide seconds output. My app shows e.g. 2015-07-13T10:58:29.7329261+02:00 (, and you can get other formats with an argument, see previous edits of this question)

Roland
  • 4,619
  • 7
  • 49
  • 81
  • 8
    Console is command line.... – leppie Jul 13 '15 at 10:28
  • 5
    Why are you putting it in the system32 folder? – transporter_room_3 Jul 13 '15 at 10:29
  • 2
    ^^the most important question here – Igal Tabachnik Jul 13 '15 at 10:31
  • 2
    If I pass `shmock` as the first command line parameter - how will the date be formatted? – Thorsten Dittmar Jul 13 '15 at 10:31
  • What happens if you also copy the application's `DateTime.exe.config` file along with your application? Could be that the system fails to determine the correct .NET version to execute your program and the config file contains a respective runtime version entry. https://support.microsoft.com/en-us/kb/2715633#bookmark-codeC – Thorsten Dittmar Jul 13 '15 at 10:34
  • 1
    @ThorstenDittmar shm stands for seconds, hour(0-12), minute, the other letters ock will be outputted uninterpreted. – Roland Jul 13 '15 at 12:02
  • 1
    @ThorstenDittmar there is no *.config file in the bin/debug folder – Roland Jul 13 '15 at 12:03
  • 1
    @transporter_room_3 because it is in %PATH% – Roland Jul 13 '15 at 12:04
  • @Roland My first question about how the date is formatted of course aimed towards the total lack of error handling in your code. The second point: What's your target .NET framework? – Thorsten Dittmar Jul 13 '15 at 12:05
  • @ThorstenDittmar in the interest of this forum I tried to give a very small piece of sample code. Error handling only distracts from the problem of how to create a command line utility. – Roland Jul 13 '15 at 12:19
  • my question specifically refers to `VisualStudio` as this is my tool for C#. It offers methods to create several types of applications, but I do not know how to use it for command line apps. – Roland Jul 13 '15 at 12:28
  • @Roland Using "Console application" is the correct way of creating a command line app. – Thorsten Dittmar Jul 13 '15 at 12:41

3 Answers3

4

Console project is a command line project.

You can use the args [] to track command line parameters.

Your executable may have dependencies: You can use something like obfuscator or another tool to package them into the .exe so you don't need external files.

Alternatively, install your project into its own folder, and modify the PATH variable to include the path to the directory - this will let you run your .exe from any folder, much like you can run 'dir' in any folder.

I'm not clear what your DateTime problem is, but you can use the .ToString() overload to adjust the formatting, and .Parse() to interpret the date from a variety of formats.

var dt = new DateTime();
dt.ToString("dd/MM/yyyy hh:mm:ss");
Community
  • 1
  • 1
NibblyPig
  • 51,118
  • 72
  • 200
  • 356
  • And how does this address the error the OP is asking for? – leppie Jul 13 '15 at 10:30
  • I am very interested in a tool to package the dependencies into the .exe. That may be the solution to my problem. – Roland Jul 13 '15 at 10:37
  • About the `DateTime` problem, I do already use your method. The problem was that the original DOS system command` Time/T` does not show seconds. – Roland Jul 13 '15 at 10:38
  • Take a look at DLL Merging, you should be able to find a tool to do it. http://stackoverflow.com/questions/2156321/merging-net-managed-dlls recommends ILMerge – NibblyPig Jul 13 '15 at 10:42
  • @SLC: I upvote, but do not mark as answer. Your solution led me to interesting options, but did not solve my problem. VS gave me 6 references by default when creating a new Console project, but I could remove them all and was still able to build and run the project. Looking at the required `using` -s I should need System.dll and System.Core.dll, but `ILMerge` (from Microsoft research, found through the comments above) could not add those dll's in. Those 2 dll's are used 'automatically' by VS. Seems not so simple to create a simple *.exe command line utility :-( – Roland Jul 13 '15 at 12:11
  • @SLC a command line utility is, in my opinion, a single *.exe file that I can install in any directory listed in %PATH% and run from the command line. Several command line utilities can be called as a sequence, from the command line (using &) or from a batch file. On the other hand, a Console app can be called or started from the command line or from the file explorer, and is not a single *.exe. – Roland Jul 13 '15 at 12:17
  • @Roland Any command line application you build using C# requires the .NET framework - no way around this. The references you mention are all required for .NET applications, so you need to leave them there. Creating a command line tool using VS is actually *the simplest thing*! Select the "Console project" template and go. – Thorsten Dittmar Jul 13 '15 at 12:44
  • `DotFuscator`, a tool built in VisualStudio, does not produce a single *.exe file. – Roland Jul 13 '15 at 14:56
  • ILMerge should work, according to other posts on the topic http://stackoverflow.com/questions/10137937/merge-dll-into-exe. Apparently there is a GUI tool that might help too. I still think using the PATH variable is the way to go. It's how many command line tools work, they aren't all just single .exe files. – NibblyPig Jul 13 '15 at 15:12
  • @ThorstenDittmar Thanks, but I managed to build the above code as a console project, as I mentioned. But it appears to be something different than a `command line` app like c:\windows\system32\find.exe – Roland Jul 13 '15 at 15:13
  • @SLC it appears that packaging all depencies in the .exe is not the issue. In c:\windows\system32 there are many .dll files. It must be something different. I will have to take the upvote back, sorry. I am looking forward for someone taking my little code, build it, and install it in c:\windows\system32. However, this is not a critical problem for me. If there is no solution, so be it. – Roland Jul 13 '15 at 15:18
  • You might also consider writing this in C++, for a simple task like this, you should be able to do it even with no prior knowledge of C++. – NibblyPig Jul 13 '15 at 15:22
  • Actually this is a good question! I've tried to write some small tool to edit some text file for a daily task. And every call of that tool results in a small cmd window popping up, which is not necessary (it does not show anything). What I would expect is the same behavior like for an echo call: you write echo hi in your cmd and it just writes some text - without extra windows popping up. – Ryugeist Jul 03 '20 at 17:09
0

As advised by SLC, I tried to write this app in C++. It turns out that VisualStudio offers a choice for C++ Console apps: with CLR, or as Win32, where CLR stands for the dot-Net Framework. Indeed the Win32 project builds as a simple .EXE file that can be installed in any directory mentioned in %PATH%, e.g., C:\Windows\System32\ .

VisualStudio does not offer this choice for C# Console apps.

Unfortunately, C++ is a step backwards from C#: it is more complex. It should run faster for certain types of apps, but cost more time to develop. Compare this C++ code with the C# source above:

#include "stdafx.h"
#include <iostream>
#include <ctime>

int main()
{
    // get current time
    time_t time_now = time(0);
    // convert to local time struct
    struct tm tstruct;
    localtime_s(&tstruct, &time_now);
    // format to string
    char str_time[80];
    strftime(str_time, sizeof(str_time), "%Y-%m-%d %H:%M:%S", &tstruct);
    // to stdout
    std::cout << str_time << std::endl;
    return 0;
}

As said, the above C++ code, as a Win32 Console project, will run as a single .EXE file from a directory in %PATH%.

For completeness, here is a nicer source code in C++, as a CLR Console project, i.e., with the .Net Framework, that will code comparably fast as C#, but will also NOT run as a single .EXE file from a directory in %PATH%.

#include "stdafx.h"
using namespace System;
int main()
{
    Console::WriteLine(DateTime::Now);
    Console::WriteLine(DateTime::Now.ToString(L"o"));
    Console::WriteLine(DateTime::Now.ToString(L"yyyy-MM-dd HH:mm:ss"));
    return 0;
 }

Output is, e.g.:

14-7-2015 16:23:27
2015-07-14T16:23:27.6978497+02:00
2015-07-14 16:23:27

The above apps are also tested from PowerShell, but then the CLR/.Net based apps can also not be run from %PATH%.

Roland
  • 4,619
  • 7
  • 49
  • 81
0

There is a simple NuGet package that helps you to create your own command-line application without handling many things line parsing the arguments and mapping the types etc.,

https://www.nuget.org/packages/CommandLineTool/